diff --git a/lib/diaspora_federation/entities.rb b/lib/diaspora_federation/entities.rb index 7ab98e9..0a1e7b8 100644 --- a/lib/diaspora_federation/entities.rb +++ b/lib/diaspora_federation/entities.rb @@ -15,3 +15,12 @@ require "diaspora_federation/entities/photo" require "diaspora_federation/entities/status_message" require "diaspora_federation/entities/request" require "diaspora_federation/entities/participation" +require "diaspora_federation/entities/like" +require "diaspora_federation/entities/comment" +require "diaspora_federation/entities/account_deletion" +require "diaspora_federation/entities/message" +require "diaspora_federation/entities/conversation" +require "diaspora_federation/entities/relayable_retraction" +require "diaspora_federation/entities/reshare" +require "diaspora_federation/entities/retraction" +require "diaspora_federation/entities/signed_retraction" diff --git a/lib/diaspora_federation/entities/account_deletion.rb b/lib/diaspora_federation/entities/account_deletion.rb new file mode 100644 index 0000000..a0a81db --- /dev/null +++ b/lib/diaspora_federation/entities/account_deletion.rb @@ -0,0 +1,7 @@ +module DiasporaFederation + module Entities + class AccountDeletion < Entity + property :diaspora_id, xml_name: :diaspora_handle + end + end +end diff --git a/lib/diaspora_federation/entities/comment.rb b/lib/diaspora_federation/entities/comment.rb new file mode 100644 index 0000000..543930e --- /dev/null +++ b/lib/diaspora_federation/entities/comment.rb @@ -0,0 +1,12 @@ +module DiasporaFederation + module Entities + class Comment < Entity + property :guid + property :parent_guid + property :parent_author_signature + property :author_signature + property :text + property :diaspora_id, xml_name: :diaspora_handle + end + end +end diff --git a/lib/diaspora_federation/entities/conversation.rb b/lib/diaspora_federation/entities/conversation.rb new file mode 100644 index 0000000..e90709b --- /dev/null +++ b/lib/diaspora_federation/entities/conversation.rb @@ -0,0 +1,12 @@ +module DiasporaFederation + module Entities + class Conversation < Entity + property :guid + property :subject + property :created_at, default: -> { Time.now.utc } + entity :messages, [Entities::Message] + property :diaspora_id, xml_name: :diaspora_handle + property :participant_ids, xml_name: :participant_handles + end + end +end diff --git a/lib/diaspora_federation/entities/like.rb b/lib/diaspora_federation/entities/like.rb new file mode 100644 index 0000000..5d76188 --- /dev/null +++ b/lib/diaspora_federation/entities/like.rb @@ -0,0 +1,13 @@ +module DiasporaFederation + module Entities + class Like < Entity + property :positive + property :guid + property :target_type + property :parent_guid + property :parent_author_signature + property :author_signature + property :diaspora_id, xml_name: :diaspora_handle + end + end +end diff --git a/lib/diaspora_federation/entities/message.rb b/lib/diaspora_federation/entities/message.rb new file mode 100644 index 0000000..5eadac7 --- /dev/null +++ b/lib/diaspora_federation/entities/message.rb @@ -0,0 +1,14 @@ +module DiasporaFederation + module Entities + class Message < Entity + property :guid + property :parent_guid + property :parent_author_signature + property :author_signature + property :text + property :created_at, default: -> { Time.now.utc } + property :diaspora_id, xml_name: :diaspora_handle + property :conversation_guid + end + end +end diff --git a/lib/diaspora_federation/entities/relayable_retraction.rb b/lib/diaspora_federation/entities/relayable_retraction.rb new file mode 100644 index 0000000..11e5274 --- /dev/null +++ b/lib/diaspora_federation/entities/relayable_retraction.rb @@ -0,0 +1,11 @@ +module DiasporaFederation + module Entities + class RelayableRetraction < Entity + property :parent_author_signature + property :target_guid + property :target_type + property :sender_id, xml_name: :sender_handle + property :target_author_signature + end + end +end diff --git a/lib/diaspora_federation/entities/reshare.rb b/lib/diaspora_federation/entities/reshare.rb new file mode 100644 index 0000000..83647d7 --- /dev/null +++ b/lib/diaspora_federation/entities/reshare.rb @@ -0,0 +1,13 @@ +module DiasporaFederation + module Entities + class Reshare < Entity + property :root_diaspora_id # inconsistent, everywhere else it's "handle" + property :root_guid + property :guid + property :diaspora_id, xml_name: :diaspora_handle + property :public, default: true # always true? (we only reshare public posts) + property :created_at, default: -> { Time.now.utc } + property :provider_display_name, default: nil + end + end +end diff --git a/lib/diaspora_federation/entities/retraction.rb b/lib/diaspora_federation/entities/retraction.rb new file mode 100644 index 0000000..4c64137 --- /dev/null +++ b/lib/diaspora_federation/entities/retraction.rb @@ -0,0 +1,9 @@ +module DiasporaFederation + module Entities + class Retraction < Entity + property :post_guid + property :diaspora_id, xml_name: :diaspora_handle + property :type + end + end +end diff --git a/lib/diaspora_federation/entities/signed_retraction.rb b/lib/diaspora_federation/entities/signed_retraction.rb new file mode 100644 index 0000000..e648a02 --- /dev/null +++ b/lib/diaspora_federation/entities/signed_retraction.rb @@ -0,0 +1,10 @@ +module DiasporaFederation + module Entities + class SignedRetraction < Entity + property :target_guid + property :target_type + property :sender_id, xml_name: :sender_handle + property :target_author_signature + end + end +end diff --git a/lib/diaspora_federation/validators.rb b/lib/diaspora_federation/validators.rb index 5f4c7f3..07706e4 100644 --- a/lib/diaspora_federation/validators.rb +++ b/lib/diaspora_federation/validators.rb @@ -23,6 +23,7 @@ require "diaspora_federation/validators/rules/guid" require "diaspora_federation/validators/rules/not_nil" require "diaspora_federation/validators/rules/public_key" require "diaspora_federation/validators/rules/tag_count" +require "diaspora_federation/validators/rules/diaspora_id_count" module DiasporaFederation # Validators to perform basic sanity-checks on {DiasporaFederation::Entities federation entities}. @@ -42,3 +43,12 @@ require "diaspora_federation/validators/photo_validator" require "diaspora_federation/validators/location_validator" require "diaspora_federation/validators/status_message_validator" require "diaspora_federation/validators/participation_validator" +require "diaspora_federation/validators/like_validator" +require "diaspora_federation/validators/comment_validator" +require "diaspora_federation/validators/account_deletion_validator" +require "diaspora_federation/validators/message_validator" +require "diaspora_federation/validators/conversation_validator" +require "diaspora_federation/validators/relayable_retraction_validator" +require "diaspora_federation/validators/reshare_validator" +require "diaspora_federation/validators/retraction_validator" +require "diaspora_federation/validators/signed_retraction_validator" diff --git a/lib/diaspora_federation/validators/account_deletion_validator.rb b/lib/diaspora_federation/validators/account_deletion_validator.rb new file mode 100644 index 0000000..ad7e659 --- /dev/null +++ b/lib/diaspora_federation/validators/account_deletion_validator.rb @@ -0,0 +1,9 @@ +module DiasporaFederation + module Validators + class AccountDeletionValidator < Validation::Validator + include Validation + + rule :diaspora_id, %i(not_empty diaspora_id) + end + end +end diff --git a/lib/diaspora_federation/validators/comment_validator.rb b/lib/diaspora_federation/validators/comment_validator.rb new file mode 100644 index 0000000..9609dfb --- /dev/null +++ b/lib/diaspora_federation/validators/comment_validator.rb @@ -0,0 +1,20 @@ +module DiasporaFederation + module Validators + class CommentValidator < Validation::Validator + include Validation + + rule :guid, :guid + + rule :parent_guid, :guid + + rule :parent_author_signature, :not_empty + + rule :author_signature, :not_empty + + rule :text, [:not_empty, + length: {maximum: 65_535}] + + rule :diaspora_id, %i(not_empty diaspora_id) + end + end +end diff --git a/lib/diaspora_federation/validators/conversation_validator.rb b/lib/diaspora_federation/validators/conversation_validator.rb new file mode 100644 index 0000000..6a3036b --- /dev/null +++ b/lib/diaspora_federation/validators/conversation_validator.rb @@ -0,0 +1,13 @@ +module DiasporaFederation + module Validators + class ConversationValidator < Validation::Validator + include Validation + + rule :guid, :guid + + rule :diaspora_id, %i(not_empty diaspora_id) + + rule :participant_ids, diaspora_id_count: {maximum: 20} + end + end +end diff --git a/lib/diaspora_federation/validators/like_validator.rb b/lib/diaspora_federation/validators/like_validator.rb new file mode 100644 index 0000000..78b2a95 --- /dev/null +++ b/lib/diaspora_federation/validators/like_validator.rb @@ -0,0 +1,17 @@ +module DiasporaFederation + module Validators + class LikeValidator < Validation::Validator + include Validation + + rule :guid, :guid + + rule :parent_guid, :guid + + rule :parent_author_signature, :not_empty + + rule :author_signature, :not_empty + + rule :diaspora_id, %i(not_empty diaspora_id) + end + end +end diff --git a/lib/diaspora_federation/validators/message_validator.rb b/lib/diaspora_federation/validators/message_validator.rb new file mode 100644 index 0000000..0e9f244 --- /dev/null +++ b/lib/diaspora_federation/validators/message_validator.rb @@ -0,0 +1,19 @@ +module DiasporaFederation + module Validators + class MessageValidator < Validation::Validator + include Validation + + rule :guid, :guid + + rule :parent_guid, :guid + + rule :parent_author_signature, :not_empty + + rule :author_signature, :not_empty + + rule :diaspora_id, %i(not_empty diaspora_id) + + rule :conversation_guid, :guid + end + end +end diff --git a/lib/diaspora_federation/validators/relayable_retraction_validator.rb b/lib/diaspora_federation/validators/relayable_retraction_validator.rb new file mode 100644 index 0000000..38d5cc6 --- /dev/null +++ b/lib/diaspora_federation/validators/relayable_retraction_validator.rb @@ -0,0 +1,17 @@ +module DiasporaFederation + module Validators + class RelayableRetractionValidator < Validation::Validator + include Validation + + rule :parent_author_signature, :not_empty + + rule :target_guid, :guid + + rule :target_type, :not_empty + + rule :sender_id, %i(not_empty diaspora_id) + + rule :target_author_signature, :not_empty + end + end +end diff --git a/lib/diaspora_federation/validators/reshare_validator.rb b/lib/diaspora_federation/validators/reshare_validator.rb new file mode 100644 index 0000000..3f7f8cf --- /dev/null +++ b/lib/diaspora_federation/validators/reshare_validator.rb @@ -0,0 +1,17 @@ +module DiasporaFederation + module Validators + class ReshareValidator < Validation::Validator + include Validation + + rule :root_diaspora_id, %i(not_empty diaspora_id) + + rule :root_guid, :guid + + rule :guid, :guid + + rule :diaspora_id, %i(not_empty diaspora_id) + + rule :public, :boolean + end + end +end diff --git a/lib/diaspora_federation/validators/retraction_validator.rb b/lib/diaspora_federation/validators/retraction_validator.rb new file mode 100644 index 0000000..83897e6 --- /dev/null +++ b/lib/diaspora_federation/validators/retraction_validator.rb @@ -0,0 +1,13 @@ +module DiasporaFederation + module Validators + class RetractionValidator < Validation::Validator + include Validation + + rule :post_guid, :guid + + rule :diaspora_id, %i(not_empty diaspora_id) + + rule :type, :not_empty + end + end +end diff --git a/lib/diaspora_federation/validators/rules/diaspora_id_count.rb b/lib/diaspora_federation/validators/rules/diaspora_id_count.rb new file mode 100644 index 0000000..0a063c9 --- /dev/null +++ b/lib/diaspora_federation/validators/rules/diaspora_id_count.rb @@ -0,0 +1,32 @@ +module Validation + module Rule + # Rule for validating the number of Diaspora* ids in a string. + # The evaluated string is split at ";" and the result will be counted. + class DiasporaIdCount + attr_reader :params + + # @param [Hash] params + # @option params [Fixnum] :maximum maximum allowed id count + def initialize(params) + unless params.include?(:maximum) && params[:maximum].is_a?(Fixnum) + raise "A number has to be specified for :maximum" + end + + @params = params + end + + def error_key + :diaspora_id_count + end + + def valid_value?(value) + ids = value.split(";") + return false unless ids.count <= params[:maximum] + ids.each do |id| + return false unless DiasporaId.new.valid_value?(id) + end + true + end + end + end +end diff --git a/lib/diaspora_federation/validators/signed_retraction_validator.rb b/lib/diaspora_federation/validators/signed_retraction_validator.rb new file mode 100644 index 0000000..ebe041a --- /dev/null +++ b/lib/diaspora_federation/validators/signed_retraction_validator.rb @@ -0,0 +1,15 @@ +module DiasporaFederation + module Validators + class SignedRetractionValidator < Validation::Validator + include Validation + + rule :target_guid, :guid + + rule :target_type, :not_empty + + rule :sender_id, %i(not_empty diaspora_id) + + rule :target_author_signature, :not_empty + end + end +end diff --git a/spec/factories.rb b/spec/factories.rb index d68b25d..8c188cd 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -114,4 +114,78 @@ FactoryGirl.define do sender_id { generate(:diaspora_id) } recipient_id { generate(:diaspora_id) } end + + factory :comment_entity, class: DiasporaFederation::Entities::Comment do + guid + parent_guid { generate(:guid) } + parent_author_signature { generate(:signature) } + author_signature { generate(:signature) } + text "this is a very informative comment" + diaspora_id + end + + factory :like_entity, class: DiasporaFederation::Entities::Like do + positive 1 + guid + target_type "StatusMessage" + parent_guid { generate(:guid) } + parent_author_signature { generate(:signature) } + author_signature { generate(:signature) } + diaspora_id + end + + factory :account_deletion_entity, class: DiasporaFederation::Entities::AccountDeletion do + diaspora_id + end + + factory :conversation_entity, class: DiasporaFederation::Entities::Conversation do + guid + subject "this is a very informative subject" + created_at { DateTime.now.utc } + messages [] + diaspora_id + participant_ids { 3.times.map { generate(:diaspora_id) }.join(";") } + end + + factory :message_entity, class: DiasporaFederation::Entities::Message do + guid + parent_guid { generate(:guid) } + parent_author_signature { generate(:signature) } + author_signature { generate(:signature) } + text "this is a very informative text" + created_at { DateTime.now.utc } + diaspora_id + conversation_guid { generate(:guid) } + end + + factory :relayable_retraction_entity, class: DiasporaFederation::Entities::RelayableRetraction do + parent_author_signature { generate(:signature) } + target_guid { generate(:guid) } + target_type "StatusMessage" + sender_id { generate(:diaspora_id) } + target_author_signature { generate(:signature) } + end + + factory :reshare_entity, class: DiasporaFederation::Entities::Reshare do + root_diaspora_id { generate(:diaspora_id) } + root_guid { generate(:guid) } + guid + diaspora_id + public(true) + created_at { DateTime.now.utc } + provider_display_name { "the testsuite" } + end + + factory :retraction_entity, class: DiasporaFederation::Entities::Retraction do + post_guid { generate(:guid) } + diaspora_id + type "StatusMessage" + end + + factory :signed_retraction_entity, class: DiasporaFederation::Entities::SignedRetraction do + target_guid { generate(:guid) } + target_type "StatusMessage" + sender_id { generate(:diaspora_id) } + target_author_signature { generate(:signature) } + end end diff --git a/spec/lib/diaspora_federation/entities/account_deletion_spec.rb b/spec/lib/diaspora_federation/entities/account_deletion_spec.rb new file mode 100644 index 0000000..5b3a4a0 --- /dev/null +++ b/spec/lib/diaspora_federation/entities/account_deletion_spec.rb @@ -0,0 +1,17 @@ +module DiasporaFederation + describe Entities::AccountDeletion do + let(:data) { FactoryGirl.attributes_for(:account_deletion_entity) } + + let(:xml) { + <<-XML + + #{data[:diaspora_id]} + +XML + } + + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" + end +end diff --git a/spec/lib/diaspora_federation/entities/comment_spec.rb b/spec/lib/diaspora_federation/entities/comment_spec.rb new file mode 100644 index 0000000..525c0c6 --- /dev/null +++ b/spec/lib/diaspora_federation/entities/comment_spec.rb @@ -0,0 +1,22 @@ +module DiasporaFederation + describe Entities::Comment do + let(:data) { FactoryGirl.attributes_for(:comment_entity) } + + let(:xml) { + <<-XML + + #{data[:guid]} + #{data[:parent_guid]} + #{data[:parent_author_signature]} + #{data[:author_signature]} + #{data[:text]} + #{data[:diaspora_id]} + +XML + } + + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" + end +end diff --git a/spec/lib/diaspora_federation/entities/conversation_spec.rb b/spec/lib/diaspora_federation/entities/conversation_spec.rb new file mode 100644 index 0000000..efcfc45 --- /dev/null +++ b/spec/lib/diaspora_federation/entities/conversation_spec.rb @@ -0,0 +1,54 @@ +module DiasporaFederation + describe Entities::Conversation do + before do + @datetime = DateTime.now.utc + end + + let(:msg1) { Entities::Message.new(FactoryGirl.attributes_for(:message_entity)) } + let(:msg2) { Entities::Message.new(FactoryGirl.attributes_for(:message_entity)) } + let(:data) { + {guid: FactoryGirl.generate(:guid), + subject: "very interesting conversation subject", + created_at: @datetime, + messages: [msg1, msg2], + diaspora_id: FactoryGirl.generate(:diaspora_id), + participant_ids: "#{FactoryGirl.generate(:diaspora_id)};#{FactoryGirl.generate(:diaspora_id)}"} + } + + let(:xml) { + <<-XML + + #{data[:guid]} + #{data[:subject]} + #{data[:created_at]} + + #{msg1.guid} + #{msg1.parent_guid} + #{msg1.parent_author_signature} + #{msg1.author_signature} + #{msg1.text} + #{msg1.created_at} + #{msg1.diaspora_id} + #{msg1.conversation_guid} + + + #{msg2.guid} + #{msg2.parent_guid} + #{msg2.parent_author_signature} + #{msg2.author_signature} + #{msg2.text} + #{msg2.created_at} + #{msg2.diaspora_id} + #{msg2.conversation_guid} + + #{data[:diaspora_id]} + #{data[:participant_ids]} + +XML + } + + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" + end +end diff --git a/spec/lib/diaspora_federation/entities/like_spec.rb b/spec/lib/diaspora_federation/entities/like_spec.rb new file mode 100644 index 0000000..bc24952 --- /dev/null +++ b/spec/lib/diaspora_federation/entities/like_spec.rb @@ -0,0 +1,23 @@ +module DiasporaFederation + describe Entities::Like do + let(:data) { FactoryGirl.attributes_for(:like_entity) } + + let(:xml) { + <<-XML + + #{data[:positive]} + #{data[:guid]} + #{data[:target_type]} + #{data[:parent_guid]} + #{data[:parent_author_signature]} + #{data[:author_signature]} + #{data[:diaspora_id]} + +XML + } + + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" + end +end diff --git a/spec/lib/diaspora_federation/entities/message_spec.rb b/spec/lib/diaspora_federation/entities/message_spec.rb new file mode 100644 index 0000000..93fb53f --- /dev/null +++ b/spec/lib/diaspora_federation/entities/message_spec.rb @@ -0,0 +1,24 @@ +module DiasporaFederation + describe Entities::Message do + let(:data) { FactoryGirl.attributes_for(:message_entity) } + + let(:xml) { + <<-XML + + #{data[:guid]} + #{data[:parent_guid]} + #{data[:parent_author_signature]} + #{data[:author_signature]} + #{data[:text]} + #{data[:created_at]} + #{data[:diaspora_id]} + #{data[:conversation_guid]} + +XML + } + + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" + end +end diff --git a/spec/lib/diaspora_federation/entities/participation_spec.rb b/spec/lib/diaspora_federation/entities/participation_spec.rb index 5653c41..53c9db0 100644 --- a/spec/lib/diaspora_federation/entities/participation_spec.rb +++ b/spec/lib/diaspora_federation/entities/participation_spec.rb @@ -1,13 +1,6 @@ module DiasporaFederation describe Entities::Participation do - let(:data) { - {guid: "0123456789abcdef", - target_type: "Post", - parent_guid: "fedcba9876543210", - parent_author_signature: "BBBBBB==", - author_signature: "AAAAAA==", - diaspora_id: "luke@diaspora.example.tld"} - } + let(:data) { FactoryGirl.attributes_for(:participation_entity) } let(:xml) { <<-XML diff --git a/spec/lib/diaspora_federation/entities/relayable_retraction_spec.rb b/spec/lib/diaspora_federation/entities/relayable_retraction_spec.rb new file mode 100644 index 0000000..afb4cf1 --- /dev/null +++ b/spec/lib/diaspora_federation/entities/relayable_retraction_spec.rb @@ -0,0 +1,21 @@ +module DiasporaFederation + describe Entities::RelayableRetraction do + let(:data) { FactoryGirl.attributes_for(:relayable_retraction_entity) } + + let(:xml) { + <<-XML + + #{data[:parent_author_signature]} + #{data[:target_guid]} + #{data[:target_type]} + #{data[:sender_id]} + #{data[:target_author_signature]} + +XML + } + + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" + end +end diff --git a/spec/lib/diaspora_federation/entities/request_spec.rb b/spec/lib/diaspora_federation/entities/request_spec.rb index 62592fb..36968ad 100644 --- a/spec/lib/diaspora_federation/entities/request_spec.rb +++ b/spec/lib/diaspora_federation/entities/request_spec.rb @@ -1,15 +1,12 @@ module DiasporaFederation describe Entities::Request do - let(:data) { - {sender_id: "alice@somepod.org", - recipient_id: "bob@otherpod.net"} - } + let(:data) { FactoryGirl.attributes_for(:request_entity) } let(:xml) { <<-XML - alice@somepod.org - bob@otherpod.net + #{data[:sender_id]} + #{data[:recipient_id]} XML } diff --git a/spec/lib/diaspora_federation/entities/reshare_spec.rb b/spec/lib/diaspora_federation/entities/reshare_spec.rb new file mode 100644 index 0000000..2483291 --- /dev/null +++ b/spec/lib/diaspora_federation/entities/reshare_spec.rb @@ -0,0 +1,23 @@ +module DiasporaFederation + describe Entities::Reshare do + let(:data) { FactoryGirl.attributes_for(:reshare_entity) } + + let(:xml) { + <<-XML + + #{data[:root_diaspora_id]} + #{data[:root_guid]} + #{data[:guid]} + #{data[:diaspora_id]} + #{data[:public]} + #{data[:created_at]} + #{data[:provider_display_name]} + +XML + } + + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" + end +end diff --git a/spec/lib/diaspora_federation/entities/retraction_spec.rb b/spec/lib/diaspora_federation/entities/retraction_spec.rb new file mode 100644 index 0000000..fb67be3 --- /dev/null +++ b/spec/lib/diaspora_federation/entities/retraction_spec.rb @@ -0,0 +1,19 @@ +module DiasporaFederation + describe Entities::Retraction do + let(:data) { FactoryGirl.attributes_for(:retraction_entity) } + + let(:xml) { + <<-XML + + #{data[:post_guid]} + #{data[:diaspora_id]} + #{data[:type]} + +XML + } + + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" + end +end diff --git a/spec/lib/diaspora_federation/entities/signed_retraction_spec.rb b/spec/lib/diaspora_federation/entities/signed_retraction_spec.rb new file mode 100644 index 0000000..494592e --- /dev/null +++ b/spec/lib/diaspora_federation/entities/signed_retraction_spec.rb @@ -0,0 +1,20 @@ +module DiasporaFederation + describe Entities::SignedRetraction do + let(:data) { FactoryGirl.attributes_for(:signed_retraction_entity) } + + let(:xml) { + <<-XML + + #{data[:target_guid]} + #{data[:target_type]} + #{data[:sender_id]} + #{data[:target_author_signature]} + +XML + } + + it_behaves_like "an Entity subclass" + + it_behaves_like "an XML Entity" + end +end diff --git a/spec/lib/diaspora_federation/validators/account_deletion_validator_spec.rb b/spec/lib/diaspora_federation/validators/account_deletion_validator_spec.rb new file mode 100644 index 0000000..4c3f834 --- /dev/null +++ b/spec/lib/diaspora_federation/validators/account_deletion_validator_spec.rb @@ -0,0 +1,12 @@ +module DiasporaFederation + describe Validators::AccountDeletionValidator do + let(:entity) { :account_deletion_entity } + + it_behaves_like "a common validator" + + it_behaves_like "a diaspora id validator" do + let(:property) { :diaspora_id } + let(:mandatory) { true } + end + end +end diff --git a/spec/lib/diaspora_federation/validators/comment_validator_spec.rb b/spec/lib/diaspora_federation/validators/comment_validator_spec.rb new file mode 100644 index 0000000..cad4627 --- /dev/null +++ b/spec/lib/diaspora_federation/validators/comment_validator_spec.rb @@ -0,0 +1,34 @@ +module DiasporaFederation + describe Validators::CommentValidator do + let(:entity) { :comment_entity } + + it_behaves_like "a common validator" + + it_behaves_like "a diaspora id validator" do + let(:property) { :diaspora_id } + let(:mandatory) { true } + end + + %i(guid parent_guid).each do |prop| + it_behaves_like "a guid validator" do + let(:property) { prop } + end + end + + %i(author_signature parent_author_signature).each do |prop| + describe "##{prop}" do + it_behaves_like "a property that mustn't be empty" do + let(:property) { prop } + end + end + end + + describe "#text" do + it_behaves_like "a property with a value validation/restriction" do + let(:property) { :text } + let(:wrong_values) { ["", "a" * 65_536] } + let(:correct_values) { ["a" * 65_535] } + end + end + end +end diff --git a/spec/lib/diaspora_federation/validators/conversation_validator_spec.rb b/spec/lib/diaspora_federation/validators/conversation_validator_spec.rb new file mode 100644 index 0000000..3784902 --- /dev/null +++ b/spec/lib/diaspora_federation/validators/conversation_validator_spec.rb @@ -0,0 +1,25 @@ +module DiasporaFederation + describe Validators::ConversationValidator do + let(:entity) { :conversation_entity } + + it_behaves_like "a common validator" + + it_behaves_like "a diaspora id validator" do + let(:property) { :diaspora_id } + let(:mandatory) { true } + end + + it_behaves_like "a guid validator" do + let(:property) { :guid } + end + + describe "participant_ids" do + # must not contain more than 20 participant handles + it_behaves_like "a property with a value validation/restriction" do + let(:property) { :participant_ids } + let(:wrong_values) { [21.times.map { FactoryGirl.generate(:diaspora_id) }.join(";")] } + let(:correct_values) { [20.times.map { FactoryGirl.generate(:diaspora_id) }.join(";")] } + end + end + end +end diff --git a/spec/lib/diaspora_federation/validators/h_card_validator_spec.rb b/spec/lib/diaspora_federation/validators/h_card_validator_spec.rb index 3811808..7f9042d 100644 --- a/spec/lib/diaspora_federation/validators/h_card_validator_spec.rb +++ b/spec/lib/diaspora_federation/validators/h_card_validator_spec.rb @@ -2,10 +2,6 @@ module DiasporaFederation describe Validators::HCardValidator do let(:entity) { :h_card } - def hcard_stub(data={}) - entity_stub(entity, data) - end - it_behaves_like "a common validator" describe "#full_name" do @@ -26,13 +22,8 @@ module DiasporaFederation %i(photo_large_url photo_medium_url photo_small_url).each do |prop| describe "##{prop}" do - it "must not be nil or empty" do - [nil, ""].each do |val| - validator = Validators::HCardValidator.new(hcard_stub(prop => val)) - - expect(validator).not_to be_valid - expect(validator.errors).to include(prop) - end + it_behaves_like "a property that mustn't be empty" do + let(:property) { prop } end it_behaves_like "a url path validator" do diff --git a/spec/lib/diaspora_federation/validators/like_validator_spec.rb b/spec/lib/diaspora_federation/validators/like_validator_spec.rb new file mode 100644 index 0000000..798138b --- /dev/null +++ b/spec/lib/diaspora_federation/validators/like_validator_spec.rb @@ -0,0 +1,25 @@ +module DiasporaFederation + describe Validators::LikeValidator do + let(:entity) { :like_entity } + it_behaves_like "a common validator" + + %i(guid parent_guid).each do |prop| + it_behaves_like "a guid validator" do + let(:property) { prop } + end + end + + %i(author_signature parent_author_signature).each do |prop| + describe "##{prop}" do + it_behaves_like "a property that mustn't be empty" do + let(:property) { prop } + end + end + end + + it_behaves_like "a diaspora id validator" do + let(:property) { :diaspora_id } + let(:mandatory) { true } + end + end +end diff --git a/spec/lib/diaspora_federation/validators/location_validator_spec.rb b/spec/lib/diaspora_federation/validators/location_validator_spec.rb index 90e09eb..76bcc4e 100644 --- a/spec/lib/diaspora_federation/validators/location_validator_spec.rb +++ b/spec/lib/diaspora_federation/validators/location_validator_spec.rb @@ -3,12 +3,10 @@ module DiasporaFederation let(:entity) { :location_entity } it_behaves_like "a common validator" - context "#lat and #lng" do - %i(lat lng).each do |prop| - it "must not be empty" do - validator = Validators::LocationValidator.new(entity_stub(entity, prop => "")) - expect(validator).not_to be_valid - expect(validator.errors).to include(prop) + %i(lat lng).each do |prop| + describe "##{prop}" do + it_behaves_like "a property that mustn't be empty" do + let(:property) { prop } end end end diff --git a/spec/lib/diaspora_federation/validators/message_validator_spec.rb b/spec/lib/diaspora_federation/validators/message_validator_spec.rb new file mode 100644 index 0000000..ea530b2 --- /dev/null +++ b/spec/lib/diaspora_federation/validators/message_validator_spec.rb @@ -0,0 +1,27 @@ +module DiasporaFederation + describe Validators::MessageValidator do + let(:entity) { :message_entity } + it_behaves_like "a common validator" + + it_behaves_like "a diaspora id validator" do + let(:property) { :diaspora_id } + let(:mandatory) { true } + end + + %i(guid parent_guid conversation_guid).each do |prop| + describe "##{prop}" do + it_behaves_like "a guid validator" do + let(:property) { prop } + end + end + end + + %i(author_signature parent_author_signature).each do |prop| + describe "##{prop}" do + it_behaves_like "a property that mustn't be empty" do + let(:property) { prop } + end + end + end + end +end diff --git a/spec/lib/diaspora_federation/validators/participation_validator_spec.rb b/spec/lib/diaspora_federation/validators/participation_validator_spec.rb index 590688d..285889b 100644 --- a/spec/lib/diaspora_federation/validators/participation_validator_spec.rb +++ b/spec/lib/diaspora_federation/validators/participation_validator_spec.rb @@ -9,28 +9,18 @@ module DiasporaFederation let(:mandatory) { true } end - context "#target_type" do - it "must not be empty" do - validator = Validators::ParticipationValidator.new(entity_stub(entity, target_type: "")) - expect(validator).not_to be_valid - expect(validator.errors).to include(:target_type) - end - end - - context "#guid, #parent_guid" do - %i(guid parent_guid).each do |prop| + %i(guid parent_guid).each do |prop| + describe "##{prop}" do it_behaves_like "a guid validator" do let(:property) { prop } end end end - context "#author_signature and #parent_author_signature" do - %i(author_signature parent_author_signature).each do |prop| - it "must not be empty" do - validator = Validators::ParticipationValidator.new(entity_stub(entity, prop => "")) - expect(validator).not_to be_valid - expect(validator.errors).to include(prop) + %i(target_type author_signature parent_author_signature).each do |prop| + describe "##{prop}" do + it_behaves_like "a property that mustn't be empty" do + let(:property) { prop } end end end diff --git a/spec/lib/diaspora_federation/validators/person_validator_spec.rb b/spec/lib/diaspora_federation/validators/person_validator_spec.rb index b973472..83640f2 100644 --- a/spec/lib/diaspora_federation/validators/person_validator_spec.rb +++ b/spec/lib/diaspora_federation/validators/person_validator_spec.rb @@ -20,12 +20,10 @@ module DiasporaFederation end describe "#profile" do - it "fails if profile is nil" do - instance = OpenStruct.new(FactoryGirl.attributes_for(:person_entity, profile: nil)) - validator = Validators::PersonValidator.new(instance) - - expect(validator).not_to be_valid - expect(validator.errors).to include(:profile) + it_behaves_like "a property with a value validation/restriction" do + let(:property) { :profile } + let(:wrong_values) { [nil] } + let(:correct_values) { [] } end end diff --git a/spec/lib/diaspora_federation/validators/photo_validator_spec.rb b/spec/lib/diaspora_federation/validators/photo_validator_spec.rb index 626047b..a978c0c 100644 --- a/spec/lib/diaspora_federation/validators/photo_validator_spec.rb +++ b/spec/lib/diaspora_federation/validators/photo_validator_spec.rb @@ -9,8 +9,8 @@ module DiasporaFederation let(:mandatory) { true } end - context "#guid, #status_message_guid" do - %i(guid status_message_guid).each do |prop| + %i(guid status_message_guid).each do |prop| + describe "##{prop}" do it_behaves_like "a guid validator" do let(:property) { prop } end @@ -21,32 +21,20 @@ module DiasporaFederation let(:property) { :public } end - context "#remote_photo_path, #remote_photo_name" do - %i(remote_photo_name remote_photo_path).each do |prop| - it "must not be empty" do - validator = Validators::PhotoValidator.new(entity_stub(entity, prop => "")) - expect(validator).not_to be_valid - expect(validator.errors).to include(prop) + %i(remote_photo_name remote_photo_path).each do |prop| + describe "##{prop}" do + it_behaves_like "a property that mustn't be empty" do + let(:property) { prop } end end end - context "#height, #width" do - %i(height width).each do |prop| - it "validates an integer" do - [123, "123"].each do |val| - validator = Validators::PhotoValidator.new(entity_stub(entity, prop => val)) - expect(validator).to be_valid - expect(validator.errors).to be_empty - end - end - - it "fails for non numeric types" do - [true, :num, "asdf"].each do |val| - validator = Validators::PhotoValidator.new(entity_stub(entity, prop => val)) - expect(validator).not_to be_valid - expect(validator.errors).to include(prop) - end + %i(height width).each do |prop| + describe "##{prop}" do + it_behaves_like "a property with a value validation/restriction" do + let(:property) { prop } + let(:wrong_values) { [true, :num, "asdf"] } + let(:correct_values) { [123, "123"] } end end end diff --git a/spec/lib/diaspora_federation/validators/profile_validator_spec.rb b/spec/lib/diaspora_federation/validators/profile_validator_spec.rb index 321f3ae..0eb7929 100644 --- a/spec/lib/diaspora_federation/validators/profile_validator_spec.rb +++ b/spec/lib/diaspora_federation/validators/profile_validator_spec.rb @@ -2,10 +2,6 @@ module DiasporaFederation describe Validators::ProfileValidator do let(:entity) { :profile_entity } - def profile_stub(data={}) - entity_stub(entity, data) - end - it_behaves_like "a common validator" it_behaves_like "a diaspora id validator" do @@ -24,11 +20,10 @@ module DiasporaFederation %i(image_url image_url_medium image_url_small).each do |prop| describe "##{prop}" do - it "is allowed to be nil" do - validator = Validators::ProfileValidator.new(profile_stub(prop => nil)) - - expect(validator).to be_valid - expect(validator.errors).to be_empty + it_behaves_like "a property with a value validation/restriction" do + let(:property) { prop } + let(:wrong_values) { [] } + let(:correct_values) { [nil] } end it_behaves_like "a url path validator" do @@ -59,31 +54,10 @@ module DiasporaFederation end describe "#birthday" do - it "may be empty or nil" do - [nil, ""].each do |val| - validator = Validators::ProfileValidator.new(profile_stub(birthday: val)) - - expect(validator).to be_valid - expect(validator.errors).to be_empty - end - end - - it "may be a Date or date string" do - [Date.parse("2013-06-29"), "2013-06-29"].each do |val| - validator = Validators::ProfileValidator.new(profile_stub(birthday: val)) - - expect(validator).to be_valid - expect(validator.errors).to be_empty - end - end - - it "must not be an arbitrary string or other object" do - ["asdf asdf", true, 1234].each do |val| - validator = Validators::ProfileValidator.new(profile_stub(birthday: val)) - - expect(validator).not_to be_valid - expect(validator.errors).to include(:birthday) - end + it_behaves_like "a property with a value validation/restriction" do + let(:property) { :birthday } + let(:wrong_values) { ["asdf asdf", true, 1234] } + let(:correct_values) { [nil, "", Date.parse("2013-06-29"), "2013-06-29"] } end end @@ -96,12 +70,11 @@ module DiasporaFederation end describe "#tag_string" do - it "must not contain more than 5 tags" do - validator = Validators::ProfileValidator.new( - profile_stub(tag_string: "#i #have #too #many #tags #in #my #profile")) - - expect(validator).not_to be_valid - expect(validator.errors).to include(:tag_string) + # more than 5 tags are not allowed + it_behaves_like "a property with a value validation/restriction" do + let(:property) { :tag_string } + let(:wrong_values) { ["#i #have #too #many #tags #in #my #profile"] } + let(:correct_values) { [] } end end end diff --git a/spec/lib/diaspora_federation/validators/relayable_retraction_validator_spec.rb b/spec/lib/diaspora_federation/validators/relayable_retraction_validator_spec.rb new file mode 100644 index 0000000..2e1e88e --- /dev/null +++ b/spec/lib/diaspora_federation/validators/relayable_retraction_validator_spec.rb @@ -0,0 +1,23 @@ +module DiasporaFederation + describe Validators::RelayableRetractionValidator do + let(:entity) { :relayable_retraction_entity } + it_behaves_like "a common validator" + + it_behaves_like "a diaspora id validator" do + let(:property) { :sender_id } + let(:mandatory) { true } + end + + it_behaves_like "a guid validator" do + let(:property) { :target_guid } + end + + %i(parent_author_signature target_author_signature).each do |prop| + describe "##{prop}" do + it_behaves_like "a property that mustn't be empty" do + let(:property) { prop } + end + end + end + end +end diff --git a/spec/lib/diaspora_federation/validators/request_validator_spec.rb b/spec/lib/diaspora_federation/validators/request_validator_spec.rb index 79a34c4..d8e0dcc 100644 --- a/spec/lib/diaspora_federation/validators/request_validator_spec.rb +++ b/spec/lib/diaspora_federation/validators/request_validator_spec.rb @@ -4,8 +4,8 @@ module DiasporaFederation it_behaves_like "a common validator" - context "#sender_id, #recipient_id" do - %i(sender_id recipient_id).each do |prop| + %i(sender_id recipient_id).each do |prop| + describe "##{prop}" do it_behaves_like "a diaspora id validator" do let(:property) { prop } let(:mandatory) { true } diff --git a/spec/lib/diaspora_federation/validators/reshare_validator_spec.rb b/spec/lib/diaspora_federation/validators/reshare_validator_spec.rb new file mode 100644 index 0000000..4f32d7b --- /dev/null +++ b/spec/lib/diaspora_federation/validators/reshare_validator_spec.rb @@ -0,0 +1,27 @@ +module DiasporaFederation + describe Validators::ReshareValidator do + let(:entity) { :reshare_entity } + it_behaves_like "a common validator" + + %i(root_diaspora_id diaspora_id).each do |prop| + describe "##{prop}" do + it_behaves_like "a diaspora id validator" do + let(:property) { prop } + let(:mandatory) { true } + end + end + end + + %i(root_guid guid).each do |prop| + describe "##{prop}" do + it_behaves_like "a guid validator" do + let(:property) { prop } + end + end + end + + it_behaves_like "a boolean validator" do + let(:property) { :public } + end + end +end diff --git a/spec/lib/diaspora_federation/validators/retraction_validator_spec.rb b/spec/lib/diaspora_federation/validators/retraction_validator_spec.rb new file mode 100644 index 0000000..ac14653 --- /dev/null +++ b/spec/lib/diaspora_federation/validators/retraction_validator_spec.rb @@ -0,0 +1,21 @@ +module DiasporaFederation + describe Validators::RetractionValidator do + let(:entity) { :retraction_entity } + it_behaves_like "a common validator" + + it_behaves_like "a guid validator" do + let(:property) { :post_guid } + end + + it_behaves_like "a diaspora id validator" do + let(:property) { :diaspora_id } + let(:mandatory) { true } + end + + describe "#type" do + it_behaves_like "a property that mustn't be empty" do + let(:property) { :type } + end + end + end +end diff --git a/spec/lib/diaspora_federation/validators/rules/diaspora_id_count_spec.rb b/spec/lib/diaspora_federation/validators/rules/diaspora_id_count_spec.rb new file mode 100644 index 0000000..7e8ca66 --- /dev/null +++ b/spec/lib/diaspora_federation/validators/rules/diaspora_id_count_spec.rb @@ -0,0 +1,43 @@ +describe Validation::Rule::DiasporaIdCount do + let(:id_str) { 3.times.map { FactoryGirl.generate(:diaspora_id) }.join(";") } + + it "requires a parameter" do + validator = Validation::Validator.new({}) + expect { + validator.rule(:ids, :diaspora_id_count) + }.to raise_error ArgumentError + end + + it "validates less ids" do + validator = Validation::Validator.new(OpenStruct.new(ids: id_str)) + validator.rule(:ids, diaspora_id_count: {maximum: 5}) + + expect(validator).to be_valid + expect(validator.errors).to be_empty + end + + it "fails for less but non ids" do + bad_str = "user@example.com;i am a weird diaspora id @@@ ### 12345;shouldnt be reached by a rule" + validator = Validation::Validator.new(OpenStruct.new(ids: bad_str)) + validator.rule(:ids, diaspora_id_count: {maximum: 5}) + + expect(validator).not_to be_valid + expect(validator.errors).to include(:ids) + end + + it "validates exactly as many ids" do + validator = Validation::Validator.new(OpenStruct.new(ids: id_str)) + validator.rule(:ids, diaspora_id_count: {maximum: 3}) + + expect(validator).to be_valid + expect(validator.errors).to be_empty + end + + it "fails for too many ids" do + validator = Validation::Validator.new(OpenStruct.new(ids: id_str)) + validator.rule(:ids, diaspora_id_count: {maximum: 1}) + + expect(validator).not_to be_valid + expect(validator.errors).to include(:ids) + end +end diff --git a/spec/lib/diaspora_federation/validators/signed_retraction_validator_spec.rb b/spec/lib/diaspora_federation/validators/signed_retraction_validator_spec.rb new file mode 100644 index 0000000..6c59445 --- /dev/null +++ b/spec/lib/diaspora_federation/validators/signed_retraction_validator_spec.rb @@ -0,0 +1,23 @@ +module DiasporaFederation + describe Validators::SignedRetractionValidator do + let(:entity) { :signed_retraction_entity } + it_behaves_like "a common validator" + + it_behaves_like "a diaspora id validator" do + let(:property) { :sender_id } + let(:mandatory) { true } + end + + it_behaves_like "a guid validator" do + let(:property) { :target_guid } + end + + %i(target_type target_author_signature).each do |prop| + describe "##{prop}" do + it_behaves_like "a property that mustn't be empty" do + let(:property) { prop } + end + end + end + end +end diff --git a/spec/lib/diaspora_federation/validators/web_finger_validator_spec.rb b/spec/lib/diaspora_federation/validators/web_finger_validator_spec.rb index e1ec327..1d91e7e 100644 --- a/spec/lib/diaspora_federation/validators/web_finger_validator_spec.rb +++ b/spec/lib/diaspora_federation/validators/web_finger_validator_spec.rb @@ -2,20 +2,11 @@ module DiasporaFederation describe Validators::WebFingerValidator do let(:entity) { :webfinger } - def webfinger_stub(data={}) - entity_stub(entity, data) - end - it_behaves_like "a common validator" describe "#acct_uri" do - it "fails if it is nil or empty" do - [nil, ""].each do |val| - validator = Validators::WebFingerValidator.new(webfinger_stub(acct_uri: val)) - - expect(validator).not_to be_valid - expect(validator.errors).to include(:acct_uri) - end + it_behaves_like "a property that mustn't be empty" do + let(:property) { :acct_uri } end end @@ -34,32 +25,10 @@ module DiasporaFederation # optional urls %i(alias_url salmon_url).each do |prop| describe "##{prop}" do - it "is allowed to be nil" do - validator = described_class.new(webfinger_stub(prop => nil)) - - expect(validator).to be_valid - expect(validator.errors).to be_empty - end - - it "must not be empty" do - validator = described_class.new(webfinger_stub(prop => "")) - - expect(validator).not_to be_valid - expect(validator.errors).to include(prop) - end - - it "fails for url with special chars" do - validator = described_class.new(webfinger_stub(prop => "https://asdf$%.com")) - - expect(validator).not_to be_valid - expect(validator.errors).to include(prop) - end - - it "fails for url without scheme" do - validator = described_class.new(webfinger_stub(prop => "example.com")) - - expect(validator).not_to be_valid - expect(validator.errors).to include(prop) + it_behaves_like "a property with a value validation/restriction" do + let(:property) { prop } + let(:wrong_values) { ["", "https://asdf$%.com", "example.com"] } + let(:correct_values) { [nil] } end it_behaves_like "a url path validator" do diff --git a/spec/support/shared_validator_specs.rb b/spec/support/shared_validator_specs.rb index 13ec3b1..579beb5 100644 --- a/spec/support/shared_validator_specs.rb +++ b/spec/support/shared_validator_specs.rb @@ -16,6 +16,31 @@ shared_examples "a common validator" do end end +shared_examples "a property with a value validation/restriction" do + it "fails if a wrong value is supplied" do + wrong_values.each do |val| + validator = described_class.new(entity_stub(entity, property => val)) + expect(validator).not_to be_valid + expect(validator.errors).to include(property) + end + end + + it "validates if a correct value is supplied" do + correct_values.each do |val| + validator = described_class.new(entity_stub(entity, property => val)) + expect(validator).to be_valid + expect(validator.errors).to be_empty + end + end +end + +shared_examples "a property that mustn't be empty" do + it_behaves_like "a property with a value validation/restriction" do + let(:wrong_values) { ["", nil] } + let(:correct_values) { [] } + end +end + shared_examples "a diaspora id validator" do it "must not be nil or empty if mandatory" do [nil, ""].each do |val|