Merge pull request #43 from SuperTux88/property-types
Add property types and change timestamp format
This commit is contained in:
commit
22482f792c
45 changed files with 345 additions and 213 deletions
|
|
@ -43,16 +43,16 @@ module DiasporaFederation
|
|||
# @!attribute [r] guid
|
||||
# @see Entities::Person#guid
|
||||
# @return [String] guid
|
||||
property :guid
|
||||
property :guid, :string
|
||||
|
||||
# @!attribute [r] nickname
|
||||
# The first part of the diaspora* ID
|
||||
# @return [String] nickname
|
||||
property :nickname, default: nil
|
||||
property :nickname, :string, default: nil
|
||||
|
||||
# @!attribute [r] full_name
|
||||
# @return [String] display name of the user
|
||||
property :full_name
|
||||
property :full_name, :string
|
||||
|
||||
# @!attribute [r] url
|
||||
# @deprecated should be changed to the profile url. The pod url is in
|
||||
|
|
@ -60,7 +60,7 @@ module DiasporaFederation
|
|||
# installations).
|
||||
#
|
||||
# @return [String] link to the pod
|
||||
property :url, default: nil
|
||||
property :url, :string, default: nil
|
||||
|
||||
# @!attribute [r] public_key
|
||||
# When a user is created on the pod, the pod MUST generate a pgp keypair
|
||||
|
|
@ -69,17 +69,17 @@ module DiasporaFederation
|
|||
# "-----BEGIN PUBLIC KEY-----" and ending with "-----END PUBLIC KEY-----".
|
||||
#
|
||||
# @return [String] public key
|
||||
property :public_key
|
||||
property :public_key, :string
|
||||
|
||||
# @!attribute [r] photo_large_url
|
||||
# @return [String] url to the big avatar (300x300)
|
||||
property :photo_large_url
|
||||
property :photo_large_url, :string
|
||||
# @!attribute [r] photo_medium_url
|
||||
# @return [String] url to the medium avatar (100x100)
|
||||
property :photo_medium_url
|
||||
property :photo_medium_url, :string
|
||||
# @!attribute [r] photo_small_url
|
||||
# @return [String] url to the small avatar (50x50)
|
||||
property :photo_small_url
|
||||
property :photo_small_url, :string
|
||||
|
||||
# @!attribute [r] first_name
|
||||
# @deprecated We decided to only use one name field, these should be removed
|
||||
|
|
@ -87,7 +87,7 @@ module DiasporaFederation
|
|||
#
|
||||
# @see #full_name
|
||||
# @return [String] first name
|
||||
property :first_name
|
||||
property :first_name, :string
|
||||
|
||||
# @!attribute [r] last_name
|
||||
# @deprecated We decided to only use one name field, these should be removed
|
||||
|
|
@ -95,7 +95,7 @@ module DiasporaFederation
|
|||
#
|
||||
# @see #full_name
|
||||
# @return [String] last name
|
||||
property :last_name
|
||||
property :last_name, :string
|
||||
|
||||
# @!attribute [r] searchable
|
||||
# @deprecated As this is a simple property, consider move to WebFinger instead
|
||||
|
|
@ -105,7 +105,7 @@ module DiasporaFederation
|
|||
#
|
||||
# flag if a user is searchable by name
|
||||
# @return [Boolean] searchable flag
|
||||
property :searchable
|
||||
property :searchable, :boolean
|
||||
|
||||
# CSS selectors for finding all the hCard fields
|
||||
SELECTORS = {
|
||||
|
|
|
|||
|
|
@ -35,24 +35,24 @@ module DiasporaFederation
|
|||
# The Subject element should contain the webfinger address that was asked
|
||||
# for. If it does not, then this webfinger profile MUST be ignored.
|
||||
# @return [String]
|
||||
property :acct_uri
|
||||
property :acct_uri, :string
|
||||
|
||||
# @!attribute [r] alias_url
|
||||
# @note could be nil
|
||||
# @return [String] link to the users profile
|
||||
property :alias_url
|
||||
property :alias_url, :string
|
||||
|
||||
# @!attribute [r] hcard_url
|
||||
# @return [String] link to the +hCard+
|
||||
property :hcard_url
|
||||
property :hcard_url, :string
|
||||
|
||||
# @!attribute [r] seed_url
|
||||
# @return [String] link to the pod
|
||||
property :seed_url
|
||||
property :seed_url, :string
|
||||
|
||||
# @!attribute [r] profile_url
|
||||
# @return [String] link to the users profile
|
||||
property :profile_url
|
||||
property :profile_url, :string
|
||||
|
||||
# @!attribute [r] atom_url
|
||||
# This atom feed is an Activity Stream of the user's public posts. diaspora*
|
||||
|
|
@ -63,18 +63,18 @@ module DiasporaFederation
|
|||
# Note that this feed MAY also be made available through the PubSubHubbub
|
||||
# mechanism by supplying a <link rel="hub"> in the atom feed itself.
|
||||
# @return [String] atom feed url
|
||||
property :atom_url
|
||||
property :atom_url, :string
|
||||
|
||||
# @!attribute [r] salmon_url
|
||||
# @note could be nil
|
||||
# @return [String] salmon endpoint url
|
||||
# @see https://cdn.rawgit.com/salmon-protocol/salmon-protocol/master/draft-panzer-salmon-00.html#SMLR
|
||||
# Panzer draft for Salmon, paragraph 3.3
|
||||
property :salmon_url
|
||||
property :salmon_url, :string
|
||||
|
||||
# @!attribute [r] subscribe_url
|
||||
# This url is used to find another user on the home-pod of the user in the webfinger.
|
||||
property :subscribe_url
|
||||
property :subscribe_url, :string
|
||||
|
||||
# @!attribute [r] guid
|
||||
# @deprecated Either convert these to +Property+ elements or move to the
|
||||
|
|
@ -84,7 +84,7 @@ module DiasporaFederation
|
|||
# @see HCard#guid
|
||||
# @see Entities::Person#guid
|
||||
# @return [String] guid
|
||||
property :guid
|
||||
property :guid, :string
|
||||
|
||||
# @!attribute [r] public_key
|
||||
# @deprecated Either convert these to +Property+ elements or move to the
|
||||
|
|
@ -98,7 +98,7 @@ module DiasporaFederation
|
|||
# DER-encoded PKCS#1 key beginning with the text
|
||||
# "-----BEGIN PUBLIC KEY-----" and ending with "-----END PUBLIC KEY-----".
|
||||
# @return [String] public key
|
||||
property :public_key
|
||||
property :public_key, :string
|
||||
|
||||
# +hcard_url+ link relation
|
||||
REL_HCARD = "http://microformats.org/profile/hcard".freeze
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module DiasporaFederation
|
|||
# Alias for author
|
||||
# @see AccountDeletion#author
|
||||
# @return [String] diaspora* ID
|
||||
property :author, alias: :diaspora_id, xml_name: :diaspora_handle
|
||||
property :author, :string, alias: :diaspora_id, xml_name: :diaspora_handle
|
||||
|
||||
# @return [String] string representation of this object
|
||||
def to_s
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@ module DiasporaFederation
|
|||
|
||||
# @!attribute [r] text
|
||||
# @return [String] the comment text
|
||||
property :text
|
||||
property :text, :string
|
||||
|
||||
# @!attribute [r] created_at
|
||||
# Comment entity creation time
|
||||
# @return [Time] creation time
|
||||
property :created_at, default: -> { Time.now.utc }
|
||||
property :created_at, :timestamp, default: -> { Time.now.utc }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,21 +9,21 @@ module DiasporaFederation
|
|||
# The diaspora* ID of the person who shares their profile
|
||||
# @see Person#author
|
||||
# @return [String] sender ID
|
||||
property :author
|
||||
property :author, :string
|
||||
|
||||
# @!attribute [r] recipient
|
||||
# The diaspora* ID of the person who will be shared with
|
||||
# @see Validation::Rule::DiasporaId
|
||||
# @return [String] recipient ID
|
||||
property :recipient
|
||||
property :recipient, :string
|
||||
|
||||
# @!attribute [r] following
|
||||
# @return [Boolean] if the author is following the person
|
||||
property :following, default: true
|
||||
property :following, :boolean, default: true
|
||||
|
||||
# @!attribute [r] sharing
|
||||
# @return [Boolean] if the author is sharing with the person
|
||||
property :sharing, default: true
|
||||
property :sharing, :boolean, default: true
|
||||
|
||||
# @return [String] string representation of this object
|
||||
def to_s
|
||||
|
|
|
|||
|
|
@ -8,26 +8,26 @@ module DiasporaFederation
|
|||
# The diaspora* ID of the person initiated the conversation
|
||||
# @see Person#author
|
||||
# @return [String] diaspora* ID
|
||||
property :author, xml_name: :diaspora_handle
|
||||
property :author, :string, xml_name: :diaspora_handle
|
||||
|
||||
# @!attribute [r] guid
|
||||
# A random string of at least 16 chars
|
||||
# @see Validation::Rule::Guid
|
||||
# @return [String] conversation guid
|
||||
property :guid
|
||||
property :guid, :string
|
||||
|
||||
# @!attribute [r] subject
|
||||
# @return [String] the conversation subject
|
||||
property :subject
|
||||
property :subject, :string
|
||||
|
||||
# @!attribute [r] created_at
|
||||
# @return [Time] Conversation creation time
|
||||
property :created_at, default: -> { Time.now.utc }
|
||||
property :created_at, :timestamp, default: -> { Time.now.utc }
|
||||
|
||||
# @!attribute [r] participants
|
||||
# The diaspora* IDs of the persons participating the conversation separated by ";"
|
||||
# @return [String] participants diaspora* IDs
|
||||
property :participants, xml_name: :participant_handles
|
||||
property :participants, :string, xml_name: :participant_handles
|
||||
|
||||
# @!attribute [r] messages
|
||||
# @return [[Entities::Message]] Messages of this conversation
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@ module DiasporaFederation
|
|||
# If +true+ set a like, if +false+, set a dislike (dislikes are currently not
|
||||
# implemented in the diaspora* frontend).
|
||||
# @return [Boolean] is it a like or a dislike
|
||||
property :positive
|
||||
property :positive, :boolean
|
||||
|
||||
# @!attribute [r] parent_type
|
||||
# A string describing the type of the parent
|
||||
# Can be "Post" or "Comment" (Comments are currently not implemented in the
|
||||
# diaspora* frontend).
|
||||
# @return [String] parent type
|
||||
property :parent_type, xml_name: :target_type
|
||||
property :parent_type, :string, xml_name: :target_type
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,17 +7,17 @@ module DiasporaFederation
|
|||
# @!attribute [r] address
|
||||
# A string describing your location, e.g. a city name, a street name, etc
|
||||
# @return [String] address
|
||||
property :address
|
||||
property :address, :string
|
||||
|
||||
# @!attribute [r] lat
|
||||
# Geographical latitude of your location
|
||||
# @return [String] latitude
|
||||
property :lat
|
||||
property :lat, :string
|
||||
|
||||
# @!attribute [r] lng
|
||||
# Geographical longitude of your location
|
||||
# @return [String] longitude
|
||||
property :lng
|
||||
property :lng, :string
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,18 +13,18 @@ module DiasporaFederation
|
|||
# @!attribute [r] text
|
||||
# Text of the message composed by a user
|
||||
# @return [String] text
|
||||
property :text
|
||||
property :text, :string
|
||||
|
||||
# @!attribute [r] created_at
|
||||
# Message creation time
|
||||
# @return [Time] creation time
|
||||
property :created_at, default: -> { Time.now.utc }
|
||||
property :created_at, :timestamp, default: -> { Time.now.utc }
|
||||
|
||||
# @!attribute [r] conversation_guid
|
||||
# Guid of a conversation this message belongs to
|
||||
# @see Conversation#guid
|
||||
# @return [String] conversation guid
|
||||
property :conversation_guid
|
||||
property :conversation_guid, :string
|
||||
|
||||
# It is only valid to receive a {Message} from the author itself,
|
||||
# or from the author of the parent {Conversation} if the author signature is valid.
|
||||
|
|
@ -48,6 +48,16 @@ module DiasporaFederation
|
|||
parent.author
|
||||
end
|
||||
|
||||
# old timestamp format, because this signature is only used from old pods which also relay with old format
|
||||
# @deprecated remove after {Message} doesn't include {Relayable} anymore
|
||||
def normalize_property(name, value)
|
||||
if name == :created_at
|
||||
value.to_s
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
# Default implementation, don't verify signatures for a {Message}.
|
||||
# @see Entity.populate_entity
|
||||
# @deprecated remove after {Message} doesn't include {Relayable} anymore
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ module DiasporaFederation
|
|||
# A string describing a type of the target to subscribe on
|
||||
# Currently only "Post" is supported.
|
||||
# @return [String] parent type
|
||||
property :parent_type, xml_name: :target_type
|
||||
property :parent_type, :string, xml_name: :target_type
|
||||
|
||||
# It is only valid to receive a {Participation} from the author themself.
|
||||
# @deprecated remove after {Participation} doesn't include {Relayable} anymore
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ module DiasporaFederation
|
|||
# MUST assign them a guid - a random string of at least 16 chars.
|
||||
# @see Validation::Rule::Guid
|
||||
# @return [String] guid
|
||||
property :guid
|
||||
property :guid, :string
|
||||
|
||||
# @!attribute [r] author
|
||||
# The diaspora* ID of the person
|
||||
|
|
@ -19,12 +19,12 @@ module DiasporaFederation
|
|||
# alias for author
|
||||
# @see Person#author
|
||||
# @return [String] diaspora* ID
|
||||
property :author, alias: :diaspora_id, xml_name: :diaspora_handle
|
||||
property :author, :string, alias: :diaspora_id, xml_name: :diaspora_handle
|
||||
|
||||
# @!attribute [r] url
|
||||
# @see Discovery::WebFinger#seed_url
|
||||
# @return [String] link to the pod
|
||||
property :url
|
||||
property :url, :string
|
||||
|
||||
# @!attribute [r] profile
|
||||
# All profile data of the person
|
||||
|
|
@ -34,7 +34,7 @@ module DiasporaFederation
|
|||
# @!attribute [r] exported_key
|
||||
# @see Discovery::HCard#public_key
|
||||
# @return [String] public key
|
||||
property :exported_key
|
||||
property :exported_key, :string
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,52 +8,52 @@ module DiasporaFederation
|
|||
# A random string of at least 16 chars
|
||||
# @see Validation::Rule::Guid
|
||||
# @return [String] guid
|
||||
property :guid
|
||||
property :guid, :string
|
||||
|
||||
# @!attribute [r] author
|
||||
# The diaspora* ID of the person who uploaded the photo
|
||||
# @see Person#author
|
||||
# @return [String] author diaspora* ID
|
||||
property :author, xml_name: :diaspora_handle
|
||||
property :author, :string, xml_name: :diaspora_handle
|
||||
|
||||
# @!attribute [r] public
|
||||
# Points if the photo is visible to everyone or only to some aspects
|
||||
# @return [Boolean] is it public
|
||||
property :public, default: false
|
||||
property :public, :boolean, default: false
|
||||
|
||||
# @!attribute [r] created_at
|
||||
# Photo entity creation time
|
||||
# @return [Time] creation time
|
||||
property :created_at, default: -> { Time.now.utc }
|
||||
property :created_at, :timestamp, default: -> { Time.now.utc }
|
||||
|
||||
# @!attribute [r] remote_photo_path
|
||||
# An url of the photo on a remote server
|
||||
# @return [String] remote photo url
|
||||
property :remote_photo_path
|
||||
property :remote_photo_path, :string
|
||||
|
||||
# @!attribute [r] remote_photo_name
|
||||
# @return [String] remote photo name
|
||||
property :remote_photo_name
|
||||
property :remote_photo_name, :string
|
||||
|
||||
# @!attribute [r] text
|
||||
# @return [String] text
|
||||
property :text, default: nil
|
||||
property :text, :string, default: nil
|
||||
|
||||
# @!attribute [r] status_message_guid
|
||||
# Guid of a status message this photo belongs to
|
||||
# @see StatusMessage#guid
|
||||
# @return [String] guid
|
||||
property :status_message_guid, default: nil
|
||||
property :status_message_guid, :string, default: nil
|
||||
|
||||
# @!attribute [r] height
|
||||
# Photo height
|
||||
# @return [String] height
|
||||
property :height
|
||||
# @return [Integer] height
|
||||
property :height, :integer
|
||||
|
||||
# @!attribute [r] width
|
||||
# Photo width
|
||||
# @return [String] width
|
||||
property :width
|
||||
# @return [Integer] width
|
||||
property :width, :integer
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ module DiasporaFederation
|
|||
# A random string of at least 16 chars
|
||||
# @see Validation::Rule::Guid
|
||||
# @return [String] poll guid
|
||||
property :guid
|
||||
property :guid, :string
|
||||
|
||||
# @!attribute [r] question
|
||||
# Text of the question posed by a user
|
||||
# @return [String] question
|
||||
property :question
|
||||
property :question, :string
|
||||
|
||||
# @!attribute [r] poll_answers
|
||||
# Array of possible answers for the poll
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ module DiasporaFederation
|
|||
# A random string of at least 16 chars
|
||||
# @see Validation::Rule::Guid
|
||||
# @return [String] guid
|
||||
property :guid
|
||||
property :guid, :string
|
||||
|
||||
# @!attribute [r] answer
|
||||
# Text of the answer
|
||||
# @return [String] answer
|
||||
property :answer
|
||||
property :answer, :string
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ module DiasporaFederation
|
|||
# Guid of the answer selected by the user
|
||||
# @see PollAnswer#guid
|
||||
# @return [String] poll answer guid
|
||||
property :poll_answer_guid
|
||||
property :poll_answer_guid, :string
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ module DiasporaFederation
|
|||
# @param [Entity] entity the entity in which it is included
|
||||
def self.included(entity)
|
||||
entity.class_eval do
|
||||
property :author, xml_name: :diaspora_handle
|
||||
property :guid
|
||||
property :created_at, default: -> { Time.now.utc }
|
||||
property :provider_display_name, default: nil
|
||||
property :author, :string, xml_name: :diaspora_handle
|
||||
property :guid, :string
|
||||
property :created_at, :timestamp, default: -> { Time.now.utc }
|
||||
property :provider_display_name, :string, default: nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module DiasporaFederation
|
|||
# Alias for author
|
||||
# @see Profile#author
|
||||
# @return [String] diaspora* ID
|
||||
property :author, alias: :diaspora_id, xml_name: :diaspora_handle
|
||||
property :author, :string, alias: :diaspora_id, xml_name: :diaspora_handle
|
||||
|
||||
# @!attribute [r] first_name
|
||||
# @deprecated We decided to only use one name field, these should be removed
|
||||
|
|
@ -20,7 +20,7 @@ module DiasporaFederation
|
|||
# @see #full_name
|
||||
# @see Discovery::HCard#first_name
|
||||
# @return [String] first name
|
||||
property :first_name, default: nil
|
||||
property :first_name, :string, default: nil
|
||||
|
||||
# @!attribute [r] last_name
|
||||
# @deprecated We decided to only use one name field, these should be removed
|
||||
|
|
@ -28,33 +28,33 @@ module DiasporaFederation
|
|||
# @see #full_name
|
||||
# @see Discovery::HCard#last_name
|
||||
# @return [String] last name
|
||||
property :last_name, default: nil
|
||||
property :last_name, :string, default: nil
|
||||
|
||||
# @!attribute [r] image_url
|
||||
# @see Discovery::HCard#photo_large_url
|
||||
# @return [String] url to the big avatar (300x300)
|
||||
property :image_url, default: nil
|
||||
property :image_url, :string, default: nil
|
||||
# @!attribute [r] image_url_medium
|
||||
# @see Discovery::HCard#photo_medium_url
|
||||
# @return [String] url to the medium avatar (100x100)
|
||||
property :image_url_medium, default: nil
|
||||
property :image_url_medium, :string, default: nil
|
||||
# @!attribute [r] image_url_small
|
||||
# @see Discovery::HCard#photo_small_url
|
||||
# @return [String] url to the small avatar (50x50)
|
||||
property :image_url_small, default: nil
|
||||
property :image_url_small, :string, default: nil
|
||||
|
||||
property :birthday, default: nil
|
||||
property :gender, default: nil
|
||||
property :bio, default: nil
|
||||
property :location, default: nil
|
||||
property :birthday, :string, default: nil
|
||||
property :gender, :string, default: nil
|
||||
property :bio, :string, default: nil
|
||||
property :location, :string, default: nil
|
||||
|
||||
# @!attribute [r] searchable
|
||||
# @see Discovery::HCard#searchable
|
||||
# @return [Boolean] searchable flag
|
||||
property :searchable, default: true
|
||||
property :searchable, :boolean, default: true
|
||||
|
||||
property :nsfw, default: false
|
||||
property :tag_string, default: nil
|
||||
property :nsfw, :boolean, default: false
|
||||
property :tag_string, :string, default: nil
|
||||
|
||||
# @return [String] string representation of this object
|
||||
def to_s
|
||||
|
|
|
|||
|
|
@ -7,17 +7,17 @@ module DiasporaFederation
|
|||
# The diaspora* ID of the author
|
||||
# @see Person#author
|
||||
# @return [String] diaspora* ID
|
||||
property :author
|
||||
property :author, :string
|
||||
|
||||
# @!attribute [r] local
|
||||
# +true+ if the owner of the entity is local on the pod
|
||||
# @return [Boolean] is it a like or a dislike
|
||||
property :local
|
||||
property :local, :boolean
|
||||
|
||||
# @!attribute [r] public
|
||||
# Shows whether the entity is visible to everyone or only to some aspects
|
||||
# @return [Boolean] is it public
|
||||
property :public, default: false
|
||||
property :public, :boolean, default: false
|
||||
|
||||
# @!attribute [r] parent
|
||||
# Parent if the entity also has a parent (Comment or Like) or +nil+ if it has no parent
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@ module DiasporaFederation
|
|||
# @param [Entity] klass the entity in which it is included
|
||||
def self.included(klass)
|
||||
klass.class_eval do
|
||||
property :author, xml_name: :diaspora_handle
|
||||
property :guid
|
||||
property :parent_guid
|
||||
property :author_signature, default: nil
|
||||
property :parent_author_signature, default: nil
|
||||
property :author, :string, xml_name: :diaspora_handle
|
||||
property :guid, :string
|
||||
property :parent_guid, :string
|
||||
property :author_signature, :string, default: nil
|
||||
property :parent_author_signature, :string, default: nil
|
||||
entity :parent, Entities::RelatedEntity
|
||||
end
|
||||
|
||||
|
|
@ -146,19 +146,26 @@ module DiasporaFederation
|
|||
Base64.strict_encode64(privkey.sign(DIGEST, signature_data))
|
||||
end
|
||||
|
||||
# Sort all XML elements according to the order used for the signatures.
|
||||
# It updates also the signatures with the keys of the author and the parent
|
||||
# Update the signatures with the keys of the author and the parent
|
||||
# if the signatures are not there yet and if the keys are available.
|
||||
#
|
||||
# @return [Hash] sorted xml elements with updated signatures
|
||||
def xml_elements
|
||||
xml_data = super.merge(additional_xml_elements)
|
||||
signature_order.map {|element| [element, xml_data[element] || ""] }.to_h.tap do |xml_elements|
|
||||
xml_elements[:author_signature] = author_signature || sign_with_author
|
||||
xml_elements[:parent_author_signature] = parent_author_signature || sign_with_parent_author_if_available.to_s
|
||||
# @return [Hash] properties with updated signatures
|
||||
def enriched_properties
|
||||
super.merge(additional_xml_elements).tap do |hash|
|
||||
hash[:author_signature] = author_signature || sign_with_author
|
||||
hash[:parent_author_signature] = parent_author_signature || sign_with_parent_author_if_available.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Sort all XML elements according to the order used for the signatures.
|
||||
#
|
||||
# @return [Hash] sorted xml elements
|
||||
def xml_elements
|
||||
data = super
|
||||
order = signature_order + %i(author_signature parent_author_signature)
|
||||
order.map {|element| [element, data[element] || ""] }.to_h
|
||||
end
|
||||
|
||||
# The order for signing
|
||||
# @return [Array]
|
||||
def signature_order
|
||||
|
|
@ -172,7 +179,7 @@ module DiasporaFederation
|
|||
|
||||
# @return [String] signature data string
|
||||
def signature_data
|
||||
data = to_h.merge(additional_xml_elements)
|
||||
data = normalized_properties.merge(additional_xml_elements)
|
||||
signature_order.map {|name| data[name] }.join(";")
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -24,25 +24,25 @@ module DiasporaFederation
|
|||
# This signature is mandatory only when federating from an upstream author to the subscribers.
|
||||
# @see Relayable#parent_author_signature
|
||||
# @return [String] parent author signature
|
||||
property :parent_author_signature, default: nil
|
||||
property :parent_author_signature, :string, default: nil
|
||||
|
||||
# @!attribute [r] target_guid
|
||||
# Guid of a relayable to be deleted
|
||||
# @see Comment#guid
|
||||
# @return [String] target guid
|
||||
property :target_guid
|
||||
property :target_guid, :string
|
||||
|
||||
# @!attribute [r] target_type
|
||||
# A string describing a type of the target
|
||||
# @see Retraction#target_type
|
||||
# @return [String] target type
|
||||
property :target_type
|
||||
property :target_type, :string
|
||||
|
||||
# @!attribute [r] author
|
||||
# The diaspora* ID of the person who deletes a relayable
|
||||
# @see Person#author
|
||||
# @return [String] diaspora* ID
|
||||
property :author, xml_name: :sender_handle
|
||||
property :author, :string, xml_name: :sender_handle
|
||||
|
||||
# @!attribute [r] target_author_signature
|
||||
# Contains a signature of the entity using the private key of the
|
||||
|
|
@ -51,7 +51,7 @@ module DiasporaFederation
|
|||
# author is done.
|
||||
# @see Relayable#author_signature
|
||||
# @return [String] target author signature
|
||||
property :target_author_signature, default: nil
|
||||
property :target_author_signature, :string, default: nil
|
||||
|
||||
# @!attribute [r] target
|
||||
# Target entity
|
||||
|
|
@ -83,11 +83,11 @@ module DiasporaFederation
|
|||
# if the signatures are not there yet and if the keys are available.
|
||||
#
|
||||
# @return [Hash] xml elements with updated signatures
|
||||
def xml_elements
|
||||
def enriched_properties
|
||||
privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key, author)
|
||||
|
||||
super.tap do |xml_elements|
|
||||
fill_required_signature(privkey, xml_elements) unless privkey.nil?
|
||||
super.tap do |hash|
|
||||
fill_required_signature(privkey, hash) unless privkey.nil?
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ module DiasporaFederation
|
|||
# The diaspora* ID of the person who share their profile
|
||||
# @see Person#author
|
||||
# @return [String] sender ID
|
||||
property :author, xml_name: :sender_handle
|
||||
property :author, :string, xml_name: :sender_handle
|
||||
|
||||
# @!attribute [r] recipient
|
||||
# The diaspora* ID of the person who will be shared with
|
||||
# @see Validation::Rule::DiasporaId
|
||||
# @return [String] recipient ID
|
||||
property :recipient, xml_name: :recipient_handle
|
||||
property :recipient, :string, xml_name: :recipient_handle
|
||||
|
||||
# Use only {Contact} for receive
|
||||
# @return [Contact] instance as contact
|
||||
|
|
|
|||
|
|
@ -10,18 +10,18 @@ module DiasporaFederation
|
|||
# The diaspora* ID of the person who posted the original post
|
||||
# @see Person#author
|
||||
# @return [String] diaspora* ID
|
||||
property :root_author, xml_name: :root_diaspora_id
|
||||
property :root_author, :string, xml_name: :root_diaspora_id
|
||||
|
||||
# @!attribute [r] root_guid
|
||||
# Guid of the original post
|
||||
# @see StatusMessage#guid
|
||||
# @return [String] root guid
|
||||
property :root_guid
|
||||
property :root_guid, :string
|
||||
|
||||
# @!attribute [r] public
|
||||
# Has no meaning at the moment
|
||||
# @return [Boolean] public
|
||||
property :public, default: true # always true? (we only reshare public posts)
|
||||
property :public, :boolean, default: true # always true? (we only reshare public posts)
|
||||
|
||||
# @return [String] string representation of this object
|
||||
def to_s
|
||||
|
|
|
|||
|
|
@ -8,17 +8,17 @@ module DiasporaFederation
|
|||
# The diaspora* ID of the person who deletes the entity
|
||||
# @see Person#author
|
||||
# @return [String] diaspora* ID
|
||||
property :author, xml_name: :diaspora_handle
|
||||
property :author, :string, xml_name: :diaspora_handle
|
||||
|
||||
# @!attribute [r] target_guid
|
||||
# Guid of the entity to be deleted
|
||||
# @return [String] target guid
|
||||
property :target_guid, xml_name: :post_guid
|
||||
property :target_guid, :string, xml_name: :post_guid
|
||||
|
||||
# @!attribute [r] target_type
|
||||
# A string describing the type of the target
|
||||
# @return [String] target type
|
||||
property :target_type, xml_name: :type
|
||||
property :target_type, :string, xml_name: :type
|
||||
|
||||
# @!attribute [r] target
|
||||
# Target entity
|
||||
|
|
|
|||
|
|
@ -10,25 +10,25 @@ module DiasporaFederation
|
|||
# Guid of a post to be deleted
|
||||
# @see Retraction#target_guid
|
||||
# @return [String] target guid
|
||||
property :target_guid
|
||||
property :target_guid, :string
|
||||
|
||||
# @!attribute [r] target_type
|
||||
# A string describing the type of the target
|
||||
# @see Retraction#target_type
|
||||
# @return [String] target type
|
||||
property :target_type
|
||||
property :target_type, :string
|
||||
|
||||
# @!attribute [r] author
|
||||
# The diaspora* ID of the person who deletes a post
|
||||
# @see Person#author
|
||||
# @return [String] diaspora* ID
|
||||
property :author, xml_name: :sender_handle
|
||||
property :author, :string, xml_name: :sender_handle
|
||||
|
||||
# @!attribute [r] author_signature
|
||||
# Contains a signature of the entity using the private key of the author of a post
|
||||
# This signature is mandatory.
|
||||
# @return [String] author signature
|
||||
property :target_author_signature, default: nil
|
||||
property :target_author_signature, :string, default: nil
|
||||
|
||||
# @!attribute [r] target
|
||||
# Target entity
|
||||
|
|
@ -68,9 +68,9 @@ module DiasporaFederation
|
|||
# if the signatures are not there yet and if the keys are available.
|
||||
#
|
||||
# @return [Hash] xml elements with updated signatures
|
||||
def xml_elements
|
||||
super.tap do |xml_elements|
|
||||
xml_elements[:target_author_signature] = target_author_signature || sign_with_author.to_s
|
||||
def enriched_properties
|
||||
super.tap do |hash|
|
||||
hash[:target_author_signature] = target_author_signature || sign_with_author.to_s
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ module DiasporaFederation
|
|||
# @!attribute [r] text
|
||||
# Text of the status message composed by the user
|
||||
# @return [String] text of the status message
|
||||
property :text, xml_name: :raw_message
|
||||
property :text, :string, xml_name: :raw_message
|
||||
|
||||
# @!attribute [r] photos
|
||||
# Optional photos attached to the status message
|
||||
|
|
@ -29,7 +29,7 @@ module DiasporaFederation
|
|||
# @!attribute [r] public
|
||||
# Shows whether the status message is visible to everyone or only to some aspects
|
||||
# @return [Boolean] is it public
|
||||
property :public, default: false
|
||||
property :public, :boolean, default: false
|
||||
|
||||
private
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ module DiasporaFederation
|
|||
properties.map {|key, value|
|
||||
type = self.class.class_props[key]
|
||||
|
||||
if type == String || value.nil?
|
||||
if type.instance_of?(Symbol) || value.nil?
|
||||
[key, value]
|
||||
elsif type.instance_of?(Class)
|
||||
[key, value.to_h]
|
||||
|
|
@ -160,11 +160,15 @@ module DiasporaFederation
|
|||
type = self.class.class_props[name]
|
||||
return false if type.nil? # property undefined
|
||||
|
||||
setable_string?(type, val) || setable_nested?(type, val) || setable_multi?(type, val)
|
||||
setable_property?(type, val) || setable_nested?(type, val) || setable_multi?(type, val)
|
||||
end
|
||||
|
||||
def setable_property?(type, val)
|
||||
setable_string?(type, val) || type == :timestamp && val.is_a?(Time)
|
||||
end
|
||||
|
||||
def setable_string?(type, val)
|
||||
type == String && val.respond_to?(:to_s)
|
||||
%i(string integer boolean).include?(type) && val.respond_to?(:to_s)
|
||||
end
|
||||
|
||||
def setable_nested?(type, val)
|
||||
|
|
@ -215,8 +219,29 @@ module DiasporaFederation
|
|||
end
|
||||
end
|
||||
|
||||
def normalized_properties
|
||||
properties.map {|name, value| [name, normalize_property(name, value)] }.to_h
|
||||
end
|
||||
|
||||
def normalize_property(name, value)
|
||||
case self.class.class_props[name]
|
||||
when :string, :integer, :boolean
|
||||
value.to_s
|
||||
when :timestamp
|
||||
value.nil? ? "" : value.utc.iso8601
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
# default: nothing to enrich
|
||||
def enriched_properties
|
||||
normalized_properties
|
||||
end
|
||||
|
||||
# default: no special order
|
||||
def xml_elements
|
||||
properties.map {|name, value| [name, self.class.class_props[name] == String ? value.to_s : value] }.to_h
|
||||
enriched_properties
|
||||
end
|
||||
|
||||
def add_property_to_xml(doc, root_element, name, value)
|
||||
|
|
@ -255,12 +280,12 @@ module DiasporaFederation
|
|||
end
|
||||
|
||||
# @param [String] name property name to parse
|
||||
# @param [Class] type target type to parse
|
||||
# @param [Class, Symbol] type target type to parse
|
||||
# @param [Nokogiri::XML::Element] root_node XML node to parse
|
||||
# @return [Object] parsed data
|
||||
private_class_method def self.parse_element_from_node(name, type, root_node)
|
||||
if type == String
|
||||
parse_string_from_node(name, root_node)
|
||||
if type.instance_of?(Symbol)
|
||||
parse_string_from_node(name, type, root_node)
|
||||
elsif type.instance_of?(Array)
|
||||
parse_array_from_node(type.first, root_node)
|
||||
elsif type.ancestors.include?(Entity)
|
||||
|
|
@ -271,12 +296,34 @@ module DiasporaFederation
|
|||
# Create simple entry in data hash
|
||||
#
|
||||
# @param [String] name xml tag to parse
|
||||
# @param [Class, Symbol] type target type to parse
|
||||
# @param [Nokogiri::XML::Element] root_node XML root_node to parse
|
||||
# @return [String] data
|
||||
private_class_method def self.parse_string_from_node(name, root_node)
|
||||
private_class_method def self.parse_string_from_node(name, type, root_node)
|
||||
node = root_node.xpath(name.to_s)
|
||||
node = root_node.xpath(xml_names[name].to_s) if node.empty?
|
||||
node.first.text if node.any?
|
||||
parse_property(type, node.first.text) if node.any?
|
||||
end
|
||||
|
||||
# @param [Symbol] type target type to parse
|
||||
# @param [String] text data as string
|
||||
# @return [String, Boolean, Integer, Time] data
|
||||
private_class_method def self.parse_property(type, text)
|
||||
case type
|
||||
when :timestamp
|
||||
begin
|
||||
Time.parse(text).utc
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
when :integer
|
||||
text.to_i if text =~ /^\d+$/
|
||||
when :boolean
|
||||
return true if text =~ /(true|t|yes|y|1)$/i
|
||||
false if text =~ /(false|f|no|n|0)$/i
|
||||
else
|
||||
text
|
||||
end
|
||||
end
|
||||
|
||||
# Create an entry in the data hash for the nested entity
|
||||
|
|
|
|||
|
|
@ -18,12 +18,15 @@ module DiasporaFederation
|
|||
|
||||
# Define a generic (string-type) property
|
||||
# @param [Symbol] name property name
|
||||
# @param [Symbol] type property type
|
||||
# @param [Hash] opts further options
|
||||
# @option opts [Object, #call] :default a default value, making the
|
||||
# property optional
|
||||
# @option opts [Symbol] :xml_name another name used for xml generation
|
||||
def property(name, opts={})
|
||||
define_property name, String, opts
|
||||
def property(name, type, opts={})
|
||||
raise InvalidType unless property_type_valid?(type)
|
||||
|
||||
define_property name, type, opts
|
||||
end
|
||||
|
||||
# Define a property that should contain another Entity or an array of
|
||||
|
|
@ -35,7 +38,7 @@ module DiasporaFederation
|
|||
# @option opts [Object, #call] :default a default value, making the
|
||||
# property optional
|
||||
def entity(name, type, opts={})
|
||||
raise InvalidType unless type_valid?(type)
|
||||
raise InvalidType unless entity_type_valid?(type)
|
||||
|
||||
define_property name, type, opts
|
||||
end
|
||||
|
|
@ -86,9 +89,11 @@ module DiasporaFederation
|
|||
|
||||
# @deprecated
|
||||
def determine_xml_name(name, type, opts={})
|
||||
raise ArgumentError, "xml_name is not supported for nested entities" if type != String && opts.has_key?(:xml_name)
|
||||
if !type.instance_of?(Symbol) && opts.has_key?(:xml_name)
|
||||
raise ArgumentError, "xml_name is not supported for nested entities"
|
||||
end
|
||||
|
||||
if type == String
|
||||
if type.instance_of?(Symbol)
|
||||
if opts.has_key? :xml_name
|
||||
raise InvalidName, "invalid xml_name" unless name_valid?(opts[:xml_name])
|
||||
opts[:xml_name]
|
||||
|
|
@ -121,10 +126,14 @@ module DiasporaFederation
|
|||
name.instance_of?(Symbol)
|
||||
end
|
||||
|
||||
def property_type_valid?(type)
|
||||
%i(string integer boolean timestamp).include?(type)
|
||||
end
|
||||
|
||||
# Checks if the type extends {Entity}
|
||||
# @param [Class] type the type to check
|
||||
# @return [Boolean]
|
||||
def type_valid?(type)
|
||||
def entity_type_valid?(type)
|
||||
[type].flatten.all? {|type|
|
||||
type.respond_to?(:ancestors) && type.ancestors.include?(Entity)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,38 +1,38 @@
|
|||
module DiasporaFederation
|
||||
module Entities
|
||||
class TestEntity < DiasporaFederation::Entity
|
||||
property :test
|
||||
property :test, :string
|
||||
end
|
||||
|
||||
class TestDefaultEntity < DiasporaFederation::Entity
|
||||
property :test1
|
||||
property :test2
|
||||
property :test3, default: true
|
||||
property :test4, default: -> { true }
|
||||
property :test1, :string
|
||||
property :test2, :string
|
||||
property :test3, :boolean, default: true
|
||||
property :test4, :boolean, default: -> { true }
|
||||
end
|
||||
|
||||
class OtherEntity < DiasporaFederation::Entity
|
||||
property :asdf
|
||||
property :asdf, :string
|
||||
end
|
||||
|
||||
class TestNestedEntity < DiasporaFederation::Entity
|
||||
property :asdf
|
||||
property :asdf, :string
|
||||
entity :test, TestEntity, default: nil
|
||||
entity :multi, [OtherEntity]
|
||||
end
|
||||
|
||||
class TestEntityWithXmlName < DiasporaFederation::Entity
|
||||
property :test
|
||||
property :qwer, xml_name: :asdf
|
||||
property :test, :string
|
||||
property :qwer, :string, xml_name: :asdf
|
||||
end
|
||||
|
||||
class TestEntityWithRelatedEntity < DiasporaFederation::Entity
|
||||
property :test
|
||||
property :test, :string
|
||||
entity :parent, RelatedEntity
|
||||
end
|
||||
|
||||
class Entity < DiasporaFederation::Entity
|
||||
property :test
|
||||
property :test, :string
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ module DiasporaFederation
|
|||
let(:parent) { FactoryGirl.create(:post, author: bob) }
|
||||
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
|
||||
let(:data) {
|
||||
FactoryGirl.build(:comment_entity, author: alice.diaspora_id, parent_guid: parent.guid, parent: parent_entity)
|
||||
.send(:xml_elements).merge(created_at: Time.now.utc, parent: parent_entity)
|
||||
add_signatures(
|
||||
FactoryGirl.build(:comment_entity, author: alice.diaspora_id, parent_guid: parent.guid, parent: parent_entity)
|
||||
)
|
||||
}
|
||||
|
||||
let(:xml) { <<-XML }
|
||||
|
|
@ -33,14 +34,14 @@ XML
|
|||
end
|
||||
|
||||
it "parses the created_at from the xml if it is included and correctly signed" do
|
||||
created_at = Time.now.utc - 1.minute
|
||||
created_at = Time.now.utc.change(usec: 0) - 1.minute
|
||||
comment_data = FactoryGirl.build(:comment_entity, author: alice.diaspora_id, parent_guid: parent.guid).to_h
|
||||
comment_data[:created_at] = created_at
|
||||
comment_data[:parent] = parent_entity
|
||||
comment = described_class.new(comment_data, %i(author guid parent_guid text created_at))
|
||||
|
||||
parsed_comment = described_class.from_xml(comment.to_xml)
|
||||
expect(parsed_comment.created_at).to eq(created_at.to_s)
|
||||
expect(parsed_comment.created_at).to eq(created_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ module DiasporaFederation
|
|||
let(:parent) { FactoryGirl.create(:conversation, author: bob) }
|
||||
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
|
||||
let(:signed_msg1) {
|
||||
FactoryGirl.build(:message_entity, author: bob.diaspora_id, parent_guid: parent.guid, parent: parent_entity)
|
||||
.send(:xml_elements).merge(parent: parent_entity)
|
||||
add_signatures(
|
||||
FactoryGirl.build(:message_entity, author: bob.diaspora_id, parent_guid: parent.guid, parent: parent_entity)
|
||||
)
|
||||
}
|
||||
let(:signed_msg2) {
|
||||
FactoryGirl.build(:message_entity, author: bob.diaspora_id, parent_guid: parent.guid, parent: parent_entity)
|
||||
.send(:xml_elements).merge(parent: parent_entity)
|
||||
add_signatures(
|
||||
FactoryGirl.build(:message_entity, author: bob.diaspora_id, parent_guid: parent.guid, parent: parent_entity)
|
||||
)
|
||||
}
|
||||
let(:data) {
|
||||
FactoryGirl.attributes_for(:conversation_entity).merge!(
|
||||
|
|
@ -24,7 +26,7 @@ module DiasporaFederation
|
|||
<diaspora_handle>#{data[:author]}</diaspora_handle>
|
||||
<guid>#{parent.guid}</guid>
|
||||
<subject>#{data[:subject]}</subject>
|
||||
<created_at>#{data[:created_at]}</created_at>
|
||||
<created_at>#{data[:created_at].utc.iso8601}</created_at>
|
||||
<participant_handles>#{data[:participants]}</participant_handles>
|
||||
#{data[:messages].map {|a| a.to_xml.to_s.indent(2) }.join("\n")}
|
||||
</conversation>
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@ module DiasporaFederation
|
|||
let(:parent) { FactoryGirl.create(:post, author: bob) }
|
||||
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
|
||||
let(:data) {
|
||||
FactoryGirl.build(
|
||||
:like_entity,
|
||||
author: alice.diaspora_id,
|
||||
parent_guid: parent.guid,
|
||||
parent_type: parent.entity_type,
|
||||
parent: parent_entity
|
||||
).send(:xml_elements).merge(parent: parent_entity)
|
||||
add_signatures(
|
||||
FactoryGirl.build(
|
||||
:like_entity,
|
||||
author: alice.diaspora_id,
|
||||
parent_guid: parent.guid,
|
||||
parent_type: parent.entity_type,
|
||||
parent: parent_entity
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
let(:xml) { <<-XML }
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ module DiasporaFederation
|
|||
let(:parent) { FactoryGirl.create(:conversation, author: bob) }
|
||||
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
|
||||
let(:data) {
|
||||
FactoryGirl.build(:message_entity, author: alice.diaspora_id, parent_guid: parent.guid, parent: parent_entity)
|
||||
.send(:xml_elements).merge(parent: parent_entity)
|
||||
add_signatures(
|
||||
FactoryGirl.build(:message_entity, author: alice.diaspora_id, parent_guid: parent.guid, parent: parent_entity)
|
||||
)
|
||||
}
|
||||
|
||||
let(:xml) { <<-XML }
|
||||
|
|
@ -36,19 +37,19 @@ XML
|
|||
end
|
||||
|
||||
it "allows parent author if the signature is valid" do
|
||||
expect_callback(:fetch_related_entity, "Conversation", entity.conversation_guid).and_return(data[:parent])
|
||||
expect_callback(:fetch_related_entity, "Conversation", entity.conversation_guid).and_return(parent_entity)
|
||||
expect_callback(:fetch_public_key, alice.diaspora_id).and_return(alice.private_key)
|
||||
expect(entity.sender_valid?(bob.diaspora_id)).to be_truthy
|
||||
end
|
||||
|
||||
it "does not allow any other person" do
|
||||
expect_callback(:fetch_related_entity, "Conversation", entity.conversation_guid).and_return(data[:parent])
|
||||
expect_callback(:fetch_related_entity, "Conversation", entity.conversation_guid).and_return(parent_entity)
|
||||
invalid_sender = FactoryGirl.generate(:diaspora_id)
|
||||
expect(entity.sender_valid?(invalid_sender)).to be_falsey
|
||||
end
|
||||
|
||||
it "does not allow the parent author if the signature is invalid" do
|
||||
expect_callback(:fetch_related_entity, "Conversation", entity.conversation_guid).and_return(data[:parent])
|
||||
expect_callback(:fetch_related_entity, "Conversation", entity.conversation_guid).and_return(parent_entity)
|
||||
expect_callback(:fetch_public_key, alice.diaspora_id).and_return(alice.private_key)
|
||||
invalid_msg = Entities::Message.new(data.merge(author_signature: "aa"))
|
||||
expect {
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@ module DiasporaFederation
|
|||
let(:parent) { FactoryGirl.create(:post, author: bob) }
|
||||
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
|
||||
let(:data) {
|
||||
FactoryGirl.build(
|
||||
:participation_entity,
|
||||
author: alice.diaspora_id,
|
||||
parent_guid: parent.guid,
|
||||
parent_type: parent.entity_type,
|
||||
parent: parent_entity
|
||||
).send(:xml_elements).merge(parent: parent_entity)
|
||||
add_signatures(
|
||||
FactoryGirl.build(
|
||||
:participation_entity,
|
||||
author: alice.diaspora_id,
|
||||
parent_guid: parent.guid,
|
||||
parent_type: parent.entity_type,
|
||||
parent: parent_entity
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
let(:xml) { <<-XML }
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module DiasporaFederation
|
|||
<guid>#{data[:guid]}</guid>
|
||||
<diaspora_handle>#{data[:author]}</diaspora_handle>
|
||||
<public>#{data[:public]}</public>
|
||||
<created_at>#{data[:created_at]}</created_at>
|
||||
<created_at>#{data[:created_at].utc.iso8601}</created_at>
|
||||
<remote_photo_path>#{data[:remote_photo_path]}</remote_photo_path>
|
||||
<remote_photo_name>#{data[:remote_photo_name]}</remote_photo_name>
|
||||
<text>#{data[:text]}</text>
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ module DiasporaFederation
|
|||
let(:parent) { FactoryGirl.create(:poll, author: bob) }
|
||||
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
|
||||
let(:data) {
|
||||
FactoryGirl.build(
|
||||
:poll_participation_entity,
|
||||
author: alice.diaspora_id,
|
||||
parent_guid: parent.guid,
|
||||
parent: parent_entity
|
||||
).send(:xml_elements).merge(parent: parent_entity)
|
||||
add_signatures(
|
||||
FactoryGirl.build(
|
||||
:poll_participation_entity,
|
||||
author: alice.diaspora_id,
|
||||
parent_guid: parent.guid,
|
||||
parent: parent_entity
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
let(:xml) { <<-XML }
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ module DiasporaFederation
|
|||
target_guid: target.guid,
|
||||
target_type: target.entity_type,
|
||||
target: target_entity
|
||||
).send(:xml_elements).tap do |data|
|
||||
).send(:enriched_properties).tap do |data|
|
||||
data[:target_author_signature] = nil
|
||||
data[:target] = target_entity
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ module DiasporaFederation
|
|||
|
||||
include Entities::Relayable
|
||||
|
||||
property :property
|
||||
property :property, :string
|
||||
|
||||
def parent_type
|
||||
PARENT_TYPE
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module DiasporaFederation
|
|||
<reshare>
|
||||
<diaspora_handle>#{data[:author]}</diaspora_handle>
|
||||
<guid>#{data[:guid]}</guid>
|
||||
<created_at>#{data[:created_at]}</created_at>
|
||||
<created_at>#{data[:created_at].utc.iso8601}</created_at>
|
||||
<provider_display_name>#{data[:provider_display_name]}</provider_display_name>
|
||||
<root_diaspora_id>#{data[:root_author]}</root_diaspora_id>
|
||||
<root_guid>#{data[:root_guid]}</root_guid>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ module DiasporaFederation
|
|||
target_guid: target.guid,
|
||||
target_type: target.entity_type,
|
||||
target: target_entity
|
||||
).send(:xml_elements).merge(target: target_entity)
|
||||
).send(:enriched_properties).merge(target: target_entity)
|
||||
}
|
||||
|
||||
let(:xml) { <<-XML }
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ module DiasporaFederation
|
|||
<status_message>
|
||||
<diaspora_handle>#{data[:author]}</diaspora_handle>
|
||||
<guid>#{data[:guid]}</guid>
|
||||
<created_at>#{data[:created_at]}</created_at>
|
||||
<created_at>#{data[:created_at].utc.iso8601}</created_at>
|
||||
<provider_display_name>#{data[:provider_display_name]}</provider_display_name>
|
||||
<raw_message>#{data[:text]}</raw_message>
|
||||
<photo>
|
||||
<guid>#{photo1.guid}</guid>
|
||||
<diaspora_handle>#{photo1.author}</diaspora_handle>
|
||||
<public>#{photo1.public}</public>
|
||||
<created_at>#{photo1.created_at}</created_at>
|
||||
<created_at>#{photo1.created_at.utc.iso8601}</created_at>
|
||||
<remote_photo_path>#{photo1.remote_photo_path}</remote_photo_path>
|
||||
<remote_photo_name>#{photo1.remote_photo_name}</remote_photo_name>
|
||||
<text>#{photo1.text}</text>
|
||||
|
|
@ -36,7 +36,7 @@ module DiasporaFederation
|
|||
<guid>#{photo2.guid}</guid>
|
||||
<diaspora_handle>#{photo2.author}</diaspora_handle>
|
||||
<public>#{photo2.public}</public>
|
||||
<created_at>#{photo2.created_at}</created_at>
|
||||
<created_at>#{photo2.created_at.utc.iso8601}</created_at>
|
||||
<remote_photo_path>#{photo2.remote_photo_path}</remote_photo_path>
|
||||
<remote_photo_name>#{photo2.remote_photo_name}</remote_photo_name>
|
||||
<text>#{photo2.text}</text>
|
||||
|
|
|
|||
|
|
@ -175,6 +175,23 @@ XML
|
|||
expect(entity.test).to eq("asdf")
|
||||
expect(entity.qwer).to eq("qwer")
|
||||
end
|
||||
|
||||
it "parses the string to the correct type" do
|
||||
xml = <<-XML.strip
|
||||
<test_default_entity>
|
||||
<test1>asdf</test1>
|
||||
<test2>qwer</qwer2>
|
||||
<test3>true</qwer3>
|
||||
</test_default_entity>
|
||||
XML
|
||||
|
||||
entity = Entities::TestDefaultEntity.from_xml(Nokogiri::XML::Document.parse(xml).root)
|
||||
|
||||
expect(entity).to be_an_instance_of Entities::TestDefaultEntity
|
||||
expect(entity.test1).to eq("asdf")
|
||||
expect(entity.test2).to eq("qwer")
|
||||
expect(entity.test3).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "nested entities" do
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ module DiasporaFederation
|
|||
expect(magic_env.payload.guid).to eq(post.guid)
|
||||
expect(magic_env.payload.author).to eq(post.author)
|
||||
expect(magic_env.payload.text).to eq(post.text)
|
||||
expect(magic_env.payload.public).to eq("true")
|
||||
expect(magic_env.payload.public).to eq(post.public)
|
||||
receiver
|
||||
end
|
||||
expect(receiver).to receive(:receive)
|
||||
|
|
@ -42,7 +42,7 @@ module DiasporaFederation
|
|||
expect(magic_env.payload.guid).to eq(post.guid)
|
||||
expect(magic_env.payload.author).to eq(post.author)
|
||||
expect(magic_env.payload.text).to eq(post.text)
|
||||
expect(magic_env.payload.public).to eq("true")
|
||||
expect(magic_env.payload.public).to eq(post.public)
|
||||
receiver
|
||||
end
|
||||
expect(receiver).to receive(:receive)
|
||||
|
|
|
|||
|
|
@ -4,43 +4,59 @@ module DiasporaFederation
|
|||
|
||||
context "simple properties" do
|
||||
it "can name simple properties by symbol" do
|
||||
dsl.property :test
|
||||
dsl.property :test, :string
|
||||
properties = dsl.class_props
|
||||
expect(properties).to have(1).item
|
||||
expect(properties[:test]).to eq(String)
|
||||
expect(properties[:test]).to eq(:string)
|
||||
expect(dsl.xml_names[:test]).to eq(:test)
|
||||
end
|
||||
|
||||
it "will not accept other types for names" do
|
||||
["test", 1234, true, {}].each do |val|
|
||||
expect {
|
||||
dsl.property val
|
||||
dsl.property val, :string
|
||||
}.to raise_error PropertiesDSL::InvalidName
|
||||
end
|
||||
end
|
||||
|
||||
it "will not accept other types for type" do
|
||||
["test", 1234, true, {}].each do |val|
|
||||
expect {
|
||||
dsl.property :fail, val
|
||||
}.to raise_error PropertiesDSL::InvalidType
|
||||
end
|
||||
end
|
||||
|
||||
it "accepts only supported types" do
|
||||
%i(text number foobar).each do |val|
|
||||
expect {
|
||||
dsl.property :fail, val
|
||||
}.to raise_error PropertiesDSL::InvalidType
|
||||
end
|
||||
end
|
||||
|
||||
it "can define multiple properties" do
|
||||
dsl.property :test
|
||||
dsl.property :asdf
|
||||
dsl.property :zzzz
|
||||
dsl.property :test, :string
|
||||
dsl.property :asdf, :string
|
||||
dsl.property :zzzz, :string
|
||||
properties = dsl.class_props
|
||||
expect(properties).to have(3).items
|
||||
expect(properties.keys).to include(:test, :asdf, :zzzz)
|
||||
properties.values.each {|type| expect(type).to eq(String) }
|
||||
properties.values.each {|type| expect(type).to eq(:string) }
|
||||
end
|
||||
|
||||
it "can add an xml name to simple properties with a symbol" do
|
||||
dsl.property :test, xml_name: :xml_test
|
||||
dsl.property :test, :string, xml_name: :xml_test
|
||||
properties = dsl.class_props
|
||||
expect(properties).to have(1).item
|
||||
expect(properties[:test]).to eq(String)
|
||||
expect(properties[:test]).to eq(:string)
|
||||
expect(dsl.xml_names[:test]).to eq(:xml_test)
|
||||
end
|
||||
|
||||
it "will not accept other types for xml names" do
|
||||
["test", 1234, true, {}].each do |val|
|
||||
expect {
|
||||
dsl.property :test, xml_name: val
|
||||
dsl.property :test, :string, xml_name: val
|
||||
}.to raise_error PropertiesDSL::InvalidName, "invalid xml_name"
|
||||
end
|
||||
end
|
||||
|
|
@ -91,13 +107,13 @@ module DiasporaFederation
|
|||
|
||||
describe ".default_values" do
|
||||
it "can accept default values" do
|
||||
dsl.property :test, default: :foobar
|
||||
dsl.property :test, :string, default: :foobar
|
||||
defaults = dsl.default_values
|
||||
expect(defaults[:test]).to eq(:foobar)
|
||||
end
|
||||
|
||||
it "can accept default blocks" do
|
||||
dsl.property :test, default: -> { "default" }
|
||||
dsl.property :test, :string, default: -> { "default" }
|
||||
defaults = dsl.default_values
|
||||
expect(defaults[:test]).to eq("default")
|
||||
end
|
||||
|
|
@ -105,27 +121,27 @@ module DiasporaFederation
|
|||
|
||||
describe ".resolv_aliases" do
|
||||
it "resolves the defined alias" do
|
||||
dsl.property :test, alias: :test_alias
|
||||
dsl.property :test, :string, alias: :test_alias
|
||||
data = dsl.resolv_aliases(test_alias: "foo")
|
||||
expect(data[:test]).to eq("foo")
|
||||
expect(data).not_to have_key(:test_alias)
|
||||
end
|
||||
|
||||
it "raises when alias and original property are present" do
|
||||
dsl.property :test, alias: :test_alias
|
||||
dsl.property :test, :string, alias: :test_alias
|
||||
expect {
|
||||
dsl.resolv_aliases(test_alias: "foo", test: "bar")
|
||||
}.to raise_error PropertiesDSL::InvalidData, "only use 'test_alias' OR 'test'"
|
||||
end
|
||||
|
||||
it "returns original data if no alias is defined" do
|
||||
dsl.property :test, alias: :test_alias
|
||||
dsl.property :test, :string, alias: :test_alias
|
||||
data = dsl.resolv_aliases(test: "foo")
|
||||
expect(data[:test]).to eq("foo")
|
||||
end
|
||||
|
||||
it "returns original data if alias is defined, but not present" do
|
||||
dsl.property :test
|
||||
dsl.property :test, :string
|
||||
data = dsl.resolv_aliases(test: "foo")
|
||||
expect(data[:test]).to eq("foo")
|
||||
expect(data).not_to have_key(:test_alias)
|
||||
|
|
@ -134,17 +150,17 @@ module DiasporaFederation
|
|||
|
||||
describe ".find_property_for_xml_name" do
|
||||
it "finds property by xml_name" do
|
||||
dsl.property :test, xml_name: :xml_test
|
||||
dsl.property :test, :string, xml_name: :xml_test
|
||||
expect(dsl.find_property_for_xml_name("xml_test")).to eq(:test)
|
||||
end
|
||||
|
||||
it "finds property by name" do
|
||||
dsl.property :test, xml_name: :xml_test
|
||||
dsl.property :test, :string, xml_name: :xml_test
|
||||
expect(dsl.find_property_for_xml_name("test")).to eq(:test)
|
||||
end
|
||||
|
||||
it "returns nil if property is not defined" do
|
||||
dsl.property :test, xml_name: :xml_test
|
||||
dsl.property :test, :string, xml_name: :xml_test
|
||||
expect(dsl.find_property_for_xml_name("unknown")).to be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -38,6 +38,14 @@ def expect_callback(*opts)
|
|||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(*opts)
|
||||
end
|
||||
|
||||
def add_signatures(entity)
|
||||
properties = entity.send(:enriched_properties)
|
||||
entity.to_h.tap do |hash|
|
||||
hash[:author_signature] = properties[:author_signature]
|
||||
hash[:parent_author_signature] = properties[:parent_author_signature]
|
||||
end
|
||||
end
|
||||
|
||||
# Requires supporting files with custom matchers and macros, etc,
|
||||
# in ./support/ and its subdirectories.
|
||||
fixture_builder_file = "#{File.dirname(__FILE__)}/support/fixture_builder.rb"
|
||||
|
|
|
|||
|
|
@ -75,14 +75,22 @@ shared_examples "an XML Entity" do |ignored_props=[]|
|
|||
def validate_values(value, parsed_value, type, ignored_props)
|
||||
if value.nil?
|
||||
expect(parsed_value).to be_nil
|
||||
elsif type == String
|
||||
expect(parsed_value.to_s).to eq(value.to_s)
|
||||
elsif type.instance_of?(Symbol)
|
||||
validate_property(value, parsed_value)
|
||||
elsif type.instance_of?(Array)
|
||||
value.each_with_index {|entity, index| check_entity(entity, parsed_value[index], ignored_props) }
|
||||
elsif type.ancestors.include?(DiasporaFederation::Entity)
|
||||
check_entity(value, parsed_value, ignored_props)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_property(value, parsed_value)
|
||||
if value.is_a?(Time)
|
||||
expect(parsed_value).to eq(value.change(usec: 0))
|
||||
else
|
||||
expect(parsed_value).to eq(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "a relayable Entity" do
|
||||
|
|
|
|||
Loading…
Reference in a new issue