From dd1c16ce91958fea743854d2b3b1cb693ae49f0b Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Wed, 28 Dec 2016 00:59:34 +0100 Subject: [PATCH] add types for string properties --- lib/diaspora_federation/discovery/h_card.rb | 22 ++++---- .../discovery/web_finger.rb | 20 +++---- .../entities/account_deletion.rb | 2 +- lib/diaspora_federation/entities/comment.rb | 4 +- lib/diaspora_federation/entities/contact.rb | 8 +-- .../entities/conversation.rb | 10 ++-- lib/diaspora_federation/entities/like.rb | 4 +- lib/diaspora_federation/entities/location.rb | 6 +- lib/diaspora_federation/entities/message.rb | 16 +++++- .../entities/participation.rb | 2 +- lib/diaspora_federation/entities/person.rb | 8 +-- lib/diaspora_federation/entities/photo.rb | 24 ++++---- lib/diaspora_federation/entities/poll.rb | 4 +- .../entities/poll_answer.rb | 4 +- .../entities/poll_participation.rb | 2 +- lib/diaspora_federation/entities/post.rb | 8 +-- lib/diaspora_federation/entities/profile.rb | 26 ++++----- .../entities/related_entity.rb | 6 +- lib/diaspora_federation/entities/relayable.rb | 10 ++-- .../entities/relayable_retraction.rb | 10 ++-- lib/diaspora_federation/entities/request.rb | 4 +- lib/diaspora_federation/entities/reshare.rb | 6 +- .../entities/retraction.rb | 6 +- .../entities/signed_retraction.rb | 8 +-- .../entities/status_message.rb | 4 +- lib/diaspora_federation/entity.rb | 55 ++++++++++++++++--- lib/diaspora_federation/properties_dsl.rb | 21 +++++-- spec/entities.rb | 22 ++++---- .../entities/comment_spec.rb | 9 +-- .../entities/conversation_spec.rb | 12 ++-- .../diaspora_federation/entities/like_spec.rb | 16 +++--- .../entities/message_spec.rb | 11 ++-- .../entities/participation_spec.rb | 16 +++--- .../entities/photo_spec.rb | 2 +- .../entities/poll_participation_spec.rb | 14 +++-- .../entities/relayable_spec.rb | 2 +- .../entities/reshare_spec.rb | 2 +- .../entities/status_message_spec.rb | 6 +- spec/lib/diaspora_federation/entity_spec.rb | 17 ++++++ .../federation/fetcher_spec.rb | 4 +- .../properties_dsl_spec.rb | 54 +++++++++++------- spec/spec_helper.rb | 8 +++ spec/support/shared_entity_specs.rb | 12 +++- 43 files changed, 311 insertions(+), 196 deletions(-) diff --git a/lib/diaspora_federation/discovery/h_card.rb b/lib/diaspora_federation/discovery/h_card.rb index 1bed928..17900fc 100644 --- a/lib/diaspora_federation/discovery/h_card.rb +++ b/lib/diaspora_federation/discovery/h_card.rb @@ -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 = { diff --git a/lib/diaspora_federation/discovery/web_finger.rb b/lib/diaspora_federation/discovery/web_finger.rb index 4d2da11..5c9444b 100644 --- a/lib/diaspora_federation/discovery/web_finger.rb +++ b/lib/diaspora_federation/discovery/web_finger.rb @@ -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 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 diff --git a/lib/diaspora_federation/entities/account_deletion.rb b/lib/diaspora_federation/entities/account_deletion.rb index 7c4553c..88e087e 100644 --- a/lib/diaspora_federation/entities/account_deletion.rb +++ b/lib/diaspora_federation/entities/account_deletion.rb @@ -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 diff --git a/lib/diaspora_federation/entities/comment.rb b/lib/diaspora_federation/entities/comment.rb index 561938b..99c8319 100644 --- a/lib/diaspora_federation/entities/comment.rb +++ b/lib/diaspora_federation/entities/comment.rb @@ -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 diff --git a/lib/diaspora_federation/entities/contact.rb b/lib/diaspora_federation/entities/contact.rb index 02451f9..693895d 100644 --- a/lib/diaspora_federation/entities/contact.rb +++ b/lib/diaspora_federation/entities/contact.rb @@ -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 diff --git a/lib/diaspora_federation/entities/conversation.rb b/lib/diaspora_federation/entities/conversation.rb index 6726dfd..57898d0 100644 --- a/lib/diaspora_federation/entities/conversation.rb +++ b/lib/diaspora_federation/entities/conversation.rb @@ -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 diff --git a/lib/diaspora_federation/entities/like.rb b/lib/diaspora_federation/entities/like.rb index ea182fb..02324ca 100644 --- a/lib/diaspora_federation/entities/like.rb +++ b/lib/diaspora_federation/entities/like.rb @@ -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 diff --git a/lib/diaspora_federation/entities/location.rb b/lib/diaspora_federation/entities/location.rb index 25aaf84..5bd8501 100644 --- a/lib/diaspora_federation/entities/location.rb +++ b/lib/diaspora_federation/entities/location.rb @@ -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 diff --git a/lib/diaspora_federation/entities/message.rb b/lib/diaspora_federation/entities/message.rb index 281f200..018c5ca 100644 --- a/lib/diaspora_federation/entities/message.rb +++ b/lib/diaspora_federation/entities/message.rb @@ -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 diff --git a/lib/diaspora_federation/entities/participation.rb b/lib/diaspora_federation/entities/participation.rb index 63fdaae..075e05d 100644 --- a/lib/diaspora_federation/entities/participation.rb +++ b/lib/diaspora_federation/entities/participation.rb @@ -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 diff --git a/lib/diaspora_federation/entities/person.rb b/lib/diaspora_federation/entities/person.rb index 44868d7..ab48857 100644 --- a/lib/diaspora_federation/entities/person.rb +++ b/lib/diaspora_federation/entities/person.rb @@ -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 diff --git a/lib/diaspora_federation/entities/photo.rb b/lib/diaspora_federation/entities/photo.rb index 83e5585..5ed71ea 100644 --- a/lib/diaspora_federation/entities/photo.rb +++ b/lib/diaspora_federation/entities/photo.rb @@ -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 diff --git a/lib/diaspora_federation/entities/poll.rb b/lib/diaspora_federation/entities/poll.rb index 4eeb916..47fd2dc 100644 --- a/lib/diaspora_federation/entities/poll.rb +++ b/lib/diaspora_federation/entities/poll.rb @@ -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 diff --git a/lib/diaspora_federation/entities/poll_answer.rb b/lib/diaspora_federation/entities/poll_answer.rb index 85ab83f..7c1ee17 100644 --- a/lib/diaspora_federation/entities/poll_answer.rb +++ b/lib/diaspora_federation/entities/poll_answer.rb @@ -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 diff --git a/lib/diaspora_federation/entities/poll_participation.rb b/lib/diaspora_federation/entities/poll_participation.rb index 24418a1..8ef8f9e 100644 --- a/lib/diaspora_federation/entities/poll_participation.rb +++ b/lib/diaspora_federation/entities/poll_participation.rb @@ -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 diff --git a/lib/diaspora_federation/entities/post.rb b/lib/diaspora_federation/entities/post.rb index 5ef961c..af161a1 100644 --- a/lib/diaspora_federation/entities/post.rb +++ b/lib/diaspora_federation/entities/post.rb @@ -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 diff --git a/lib/diaspora_federation/entities/profile.rb b/lib/diaspora_federation/entities/profile.rb index a61bbde..7a9b4c6 100644 --- a/lib/diaspora_federation/entities/profile.rb +++ b/lib/diaspora_federation/entities/profile.rb @@ -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 diff --git a/lib/diaspora_federation/entities/related_entity.rb b/lib/diaspora_federation/entities/related_entity.rb index 6f8cf9f..850babe 100644 --- a/lib/diaspora_federation/entities/related_entity.rb +++ b/lib/diaspora_federation/entities/related_entity.rb @@ -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 diff --git a/lib/diaspora_federation/entities/relayable.rb b/lib/diaspora_federation/entities/relayable.rb index 1cc3d77..cf0a2ad 100644 --- a/lib/diaspora_federation/entities/relayable.rb +++ b/lib/diaspora_federation/entities/relayable.rb @@ -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 diff --git a/lib/diaspora_federation/entities/relayable_retraction.rb b/lib/diaspora_federation/entities/relayable_retraction.rb index 8d742ad..00f0768 100644 --- a/lib/diaspora_federation/entities/relayable_retraction.rb +++ b/lib/diaspora_federation/entities/relayable_retraction.rb @@ -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 diff --git a/lib/diaspora_federation/entities/request.rb b/lib/diaspora_federation/entities/request.rb index 096cc70..7290974 100644 --- a/lib/diaspora_federation/entities/request.rb +++ b/lib/diaspora_federation/entities/request.rb @@ -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 diff --git a/lib/diaspora_federation/entities/reshare.rb b/lib/diaspora_federation/entities/reshare.rb index 95f27d7..cd831d7 100644 --- a/lib/diaspora_federation/entities/reshare.rb +++ b/lib/diaspora_federation/entities/reshare.rb @@ -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 diff --git a/lib/diaspora_federation/entities/retraction.rb b/lib/diaspora_federation/entities/retraction.rb index c3db746..cf1df09 100644 --- a/lib/diaspora_federation/entities/retraction.rb +++ b/lib/diaspora_federation/entities/retraction.rb @@ -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 diff --git a/lib/diaspora_federation/entities/signed_retraction.rb b/lib/diaspora_federation/entities/signed_retraction.rb index 9df148a..ed88dbd 100644 --- a/lib/diaspora_federation/entities/signed_retraction.rb +++ b/lib/diaspora_federation/entities/signed_retraction.rb @@ -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 diff --git a/lib/diaspora_federation/entities/status_message.rb b/lib/diaspora_federation/entities/status_message.rb index 14fbc79..555b8b5 100644 --- a/lib/diaspora_federation/entities/status_message.rb +++ b/lib/diaspora_federation/entities/status_message.rb @@ -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 diff --git a/lib/diaspora_federation/entity.rb b/lib/diaspora_federation/entity.rb index 5bbb64d..ccaa860 100644 --- a/lib/diaspora_federation/entity.rb +++ b/lib/diaspora_federation/entity.rb @@ -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) @@ -216,7 +220,18 @@ module DiasporaFederation end def normalized_properties - properties.map {|name, value| [name, self.class.class_props[name] == String ? value.to_s : value] }.to_h + 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 @@ -265,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) @@ -281,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 diff --git a/lib/diaspora_federation/properties_dsl.rb b/lib/diaspora_federation/properties_dsl.rb index 24d28b5..9fa3302 100644 --- a/lib/diaspora_federation/properties_dsl.rb +++ b/lib/diaspora_federation/properties_dsl.rb @@ -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) } diff --git a/spec/entities.rb b/spec/entities.rb index 5747df1..18f743e 100644 --- a/spec/entities.rb +++ b/spec/entities.rb @@ -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 diff --git a/spec/lib/diaspora_federation/entities/comment_spec.rb b/spec/lib/diaspora_federation/entities/comment_spec.rb index 1e630c0..25ef0d9 100644 --- a/spec/lib/diaspora_federation/entities/comment_spec.rb +++ b/spec/lib/diaspora_federation/entities/comment_spec.rb @@ -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(:enriched_properties).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 diff --git a/spec/lib/diaspora_federation/entities/conversation_spec.rb b/spec/lib/diaspora_federation/entities/conversation_spec.rb index 903053e..c618fca 100644 --- a/spec/lib/diaspora_federation/entities/conversation_spec.rb +++ b/spec/lib/diaspora_federation/entities/conversation_spec.rb @@ -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(:enriched_properties).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(:enriched_properties).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 #{data[:author]} #{parent.guid} #{data[:subject]} - #{data[:created_at]} + #{data[:created_at].utc.iso8601} #{data[:participants]} #{data[:messages].map {|a| a.to_xml.to_s.indent(2) }.join("\n")} diff --git a/spec/lib/diaspora_federation/entities/like_spec.rb b/spec/lib/diaspora_federation/entities/like_spec.rb index c298112..64bab59 100644 --- a/spec/lib/diaspora_federation/entities/like_spec.rb +++ b/spec/lib/diaspora_federation/entities/like_spec.rb @@ -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(:enriched_properties).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 } diff --git a/spec/lib/diaspora_federation/entities/message_spec.rb b/spec/lib/diaspora_federation/entities/message_spec.rb index 1fa9b1b..b2a54ef 100644 --- a/spec/lib/diaspora_federation/entities/message_spec.rb +++ b/spec/lib/diaspora_federation/entities/message_spec.rb @@ -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(:enriched_properties).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 { diff --git a/spec/lib/diaspora_federation/entities/participation_spec.rb b/spec/lib/diaspora_federation/entities/participation_spec.rb index 19e51b3..ebd32af 100644 --- a/spec/lib/diaspora_federation/entities/participation_spec.rb +++ b/spec/lib/diaspora_federation/entities/participation_spec.rb @@ -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(:enriched_properties).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 } diff --git a/spec/lib/diaspora_federation/entities/photo_spec.rb b/spec/lib/diaspora_federation/entities/photo_spec.rb index 92ba840..a9db12e 100644 --- a/spec/lib/diaspora_federation/entities/photo_spec.rb +++ b/spec/lib/diaspora_federation/entities/photo_spec.rb @@ -7,7 +7,7 @@ module DiasporaFederation #{data[:guid]} #{data[:author]} #{data[:public]} - #{data[:created_at]} + #{data[:created_at].utc.iso8601} #{data[:remote_photo_path]} #{data[:remote_photo_name]} #{data[:text]} diff --git a/spec/lib/diaspora_federation/entities/poll_participation_spec.rb b/spec/lib/diaspora_federation/entities/poll_participation_spec.rb index dd2361f..9a0b8b5 100644 --- a/spec/lib/diaspora_federation/entities/poll_participation_spec.rb +++ b/spec/lib/diaspora_federation/entities/poll_participation_spec.rb @@ -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(:enriched_properties).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 } diff --git a/spec/lib/diaspora_federation/entities/relayable_spec.rb b/spec/lib/diaspora_federation/entities/relayable_spec.rb index 1420926..5512f1b 100644 --- a/spec/lib/diaspora_federation/entities/relayable_spec.rb +++ b/spec/lib/diaspora_federation/entities/relayable_spec.rb @@ -21,7 +21,7 @@ module DiasporaFederation include Entities::Relayable - property :property + property :property, :string def parent_type PARENT_TYPE diff --git a/spec/lib/diaspora_federation/entities/reshare_spec.rb b/spec/lib/diaspora_federation/entities/reshare_spec.rb index 8b32927..d1efba8 100644 --- a/spec/lib/diaspora_federation/entities/reshare_spec.rb +++ b/spec/lib/diaspora_federation/entities/reshare_spec.rb @@ -7,7 +7,7 @@ module DiasporaFederation #{data[:author]} #{data[:guid]} - #{data[:created_at]} + #{data[:created_at].utc.iso8601} #{data[:provider_display_name]} #{data[:root_author]} #{data[:root_guid]} diff --git a/spec/lib/diaspora_federation/entities/status_message_spec.rb b/spec/lib/diaspora_federation/entities/status_message_spec.rb index 1215e24..25b7473 100644 --- a/spec/lib/diaspora_federation/entities/status_message_spec.rb +++ b/spec/lib/diaspora_federation/entities/status_message_spec.rb @@ -17,14 +17,14 @@ module DiasporaFederation #{data[:author]} #{data[:guid]} - #{data[:created_at]} + #{data[:created_at].utc.iso8601} #{data[:provider_display_name]} #{data[:text]} #{photo1.guid} #{photo1.author} #{photo1.public} - #{photo1.created_at} + #{photo1.created_at.utc.iso8601} #{photo1.remote_photo_path} #{photo1.remote_photo_name} #{photo1.text} @@ -36,7 +36,7 @@ module DiasporaFederation #{photo2.guid} #{photo2.author} #{photo2.public} - #{photo2.created_at} + #{photo2.created_at.utc.iso8601} #{photo2.remote_photo_path} #{photo2.remote_photo_name} #{photo2.text} diff --git a/spec/lib/diaspora_federation/entity_spec.rb b/spec/lib/diaspora_federation/entity_spec.rb index 8d0c6ba..0411bab 100644 --- a/spec/lib/diaspora_federation/entity_spec.rb +++ b/spec/lib/diaspora_federation/entity_spec.rb @@ -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 + + asdf + qwer + true + +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 diff --git a/spec/lib/diaspora_federation/federation/fetcher_spec.rb b/spec/lib/diaspora_federation/federation/fetcher_spec.rb index d1c5898..b04b170 100644 --- a/spec/lib/diaspora_federation/federation/fetcher_spec.rb +++ b/spec/lib/diaspora_federation/federation/fetcher_spec.rb @@ -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) diff --git a/spec/lib/diaspora_federation/properties_dsl_spec.rb b/spec/lib/diaspora_federation/properties_dsl_spec.rb index 5edf088..e4442c7 100644 --- a/spec/lib/diaspora_federation/properties_dsl_spec.rb +++ b/spec/lib/diaspora_federation/properties_dsl_spec.rb @@ -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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 32a75b2..32bcec1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -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" diff --git a/spec/support/shared_entity_specs.rb b/spec/support/shared_entity_specs.rb index 6a29bd1..ad750cf 100644 --- a/spec/support/shared_entity_specs.rb +++ b/spec/support/shared_entity_specs.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