diff --git a/docs/_entities/conversation.md b/docs/_entities/conversation.md index 41e2f36..4d099ca 100644 --- a/docs/_entities/conversation.md +++ b/docs/_entities/conversation.md @@ -6,14 +6,14 @@ This entity represents a private conversation between persons. ## Properties -| Property | Type (Length) | Description | -| -------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------- | -| `author` | [diaspora\* ID][diaspora-id] | The diaspora\* ID of the author of the conversation. | -| `guid` | [GUID][guid] | The GUID of the conversation. | -| `subject` | [String][string] (255) | The subject of the conversation. | -| `created_at` | [Timestamp][timestamp] | The create timestamp of the conversation. | -| `participants` | [diaspora\* ID][diaspora-id]s | diaspora\* IDs of all participants of this conversation, including the `author`, seperated by `;`, at most 20. | -| `message` | [Message][message] | The first Message in the conversation, needs to be the same `author`. | +| Property | Type (Length) | Description | +| -------------- | ----------------------------- | -------------------------------------------------------------------------------------------------- | +| `author` | [diaspora\* ID][diaspora-id] | The diaspora\* ID of the author of the conversation. | +| `guid` | [GUID][guid] | The GUID of the conversation. | +| `subject` | [String][string] (255) | The subject of the conversation. | +| `created_at` | [Timestamp][timestamp] | The create timestamp of the conversation. | +| `participants` | [diaspora\* ID][diaspora-id]s | diaspora\* IDs of all participants of this conversation, including the `author`, seperated by `;`. | +| `message` | [Message][message] | The first Message in the conversation, needs to be the same `author`. | ## Example diff --git a/lib/diaspora_federation/validators.rb b/lib/diaspora_federation/validators.rb index b5095ea..864ab8e 100644 --- a/lib/diaspora_federation/validators.rb +++ b/lib/diaspora_federation/validators.rb @@ -19,7 +19,7 @@ end require "diaspora_federation/validators/rules/birthday" require "diaspora_federation/validators/rules/boolean" require "diaspora_federation/validators/rules/diaspora_id" -require "diaspora_federation/validators/rules/diaspora_id_count" +require "diaspora_federation/validators/rules/diaspora_id_list" require "diaspora_federation/validators/rules/guid" require "diaspora_federation/validators/rules/not_nil" require "diaspora_federation/validators/rules/public_key" diff --git a/lib/diaspora_federation/validators/conversation_validator.rb b/lib/diaspora_federation/validators/conversation_validator.rb index 43e68cb..d3d63a9 100644 --- a/lib/diaspora_federation/validators/conversation_validator.rb +++ b/lib/diaspora_federation/validators/conversation_validator.rb @@ -9,7 +9,7 @@ module DiasporaFederation rule :subject, [:not_empty, length: {maximum: 255}] - rule :participants, diaspora_id_count: {maximum: 20} + rule :participants, diaspora_id_list: {minimum: 2} rule :messages, :not_nil end end diff --git a/lib/diaspora_federation/validators/rules/diaspora_id_count.rb b/lib/diaspora_federation/validators/rules/diaspora_id_count.rb deleted file mode 100644 index 1709b87..0000000 --- a/lib/diaspora_federation/validators/rules/diaspora_id_count.rb +++ /dev/null @@ -1,37 +0,0 @@ -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 - # This rule must have a +maximum+ param. - # @return [Hash] params - attr_reader :params - - # Creates a new rule for a maximum diaspora* ID count validation - # @param [Hash] params - # @option params [Integer] :maximum maximum allowed id count - def initialize(params) - unless params.include?(:maximum) && params[:maximum].is_a?(Integer) - raise ArgumentError, "A number has to be specified for :maximum" - end - - @params = params - end - - # The error key for this rule - # @return [Symbol] error key - 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 if DiasporaId::DIASPORA_ID.match(id).nil? - end - true - end - end - end -end diff --git a/lib/diaspora_federation/validators/rules/diaspora_id_list.rb b/lib/diaspora_federation/validators/rules/diaspora_id_list.rb new file mode 100644 index 0000000..85e1937 --- /dev/null +++ b/lib/diaspora_federation/validators/rules/diaspora_id_list.rb @@ -0,0 +1,41 @@ +module Validation + module Rule + # Rule for validating the number of diaspora* IDs in a string. + # The evaluated string is split at ";". + class DiasporaIdList + # This rule can have a +minimum+ or +maximum+ param. + # @return [Hash] params + attr_reader :params + + # Creates a new rule for a diaspora* ID list validation + # @param [Hash] params + # @option params [Integer] :minimum minimum allowed id count + # @option params [Integer] :maximum maximum allowed id count + def initialize(params={}) + %i[minimum maximum].each do |param| + if params.include?(param) && !params[param].is_a?(Integer) + raise ArgumentError, "The :#{param} needs to be an Integer" + end + end + + @params = params + end + + # The error key for this rule + # @return [Symbol] error key + def error_key + :diaspora_id_list + end + + def valid_value?(value) + ids = value.split(";") + return false if params.include?(:maximum) && ids.count > params[:maximum] + return false if params.include?(:minimum) && ids.count < params[:minimum] + ids.each do |id| + return false if DiasporaId::DIASPORA_ID.match(id).nil? + end + true + 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 index 49670ff..d5f93a9 100644 --- a/spec/lib/diaspora_federation/validators/conversation_validator_spec.rb +++ b/spec/lib/diaspora_federation/validators/conversation_validator_spec.rb @@ -29,11 +29,15 @@ module DiasporaFederation 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) { :participants } - let(:wrong_values) { [Array.new(21) { Fabricate.sequence(:diaspora_id) }.join(";")] } - let(:correct_values) { [Array.new(20) { Fabricate.sequence(:diaspora_id) }.join(";")] } + let(:wrong_values) { ["", "foo;bar", Fabricate.sequence(:diaspora_id)] } + let(:correct_values) { + [ + Array.new(2) { Fabricate.sequence(:diaspora_id) }.join(";"), + Array.new(21) { Fabricate.sequence(:diaspora_id) }.join(";") + ] + } 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 deleted file mode 100644 index 5d927b4..0000000 --- a/spec/lib/diaspora_federation/validators/rules/diaspora_id_count_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -describe Validation::Rule::DiasporaIdCount do - let(:id_str) { Array.new(3) { Fabricate.sequence(: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 "requires a integer as parameter" do - validator = Validation::Validator.new({}) - [nil, "", 5.5].each do |val| - expect { - validator.rule(:ids, diaspora_id_count: {maximum: val}) - }.to raise_error ArgumentError, "A number has to be specified for :maximum" - end - end - - it "has an error key" do - expect(described_class.new(maximum: 5).error_key).to eq(:diaspora_id_count) - end - - context "validation" do - 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 -end diff --git a/spec/lib/diaspora_federation/validators/rules/diaspora_id_list_spec.rb b/spec/lib/diaspora_federation/validators/rules/diaspora_id_list_spec.rb new file mode 100644 index 0000000..d6ad026 --- /dev/null +++ b/spec/lib/diaspora_federation/validators/rules/diaspora_id_list_spec.rb @@ -0,0 +1,90 @@ +describe Validation::Rule::DiasporaIdList do + let(:id_str) { Array.new(3) { Fabricate.sequence(:diaspora_id) }.join(";") } + + it "does not require a parameter" do + validator = Validation::Validator.new({}) + expect { + validator.rule(:ids, :diaspora_id_list) + }.not_to raise_error + end + + it "allows a :maximum parameter" do + validator = Validation::Validator.new({}) + expect { + validator.rule(:ids, diaspora_id_list: {maximum: 20}) + }.not_to raise_error + end + + it "requires a integer as :maximum" do + validator = Validation::Validator.new({}) + [nil, "", 5.5].each do |val| + expect { + validator.rule(:ids, diaspora_id_list: {maximum: val}) + }.to raise_error ArgumentError, "The :maximum needs to be an Integer" + end + end + + it "requires a integer as :minimum" do + validator = Validation::Validator.new({}) + [nil, "", 5.5].each do |val| + expect { + validator.rule(:ids, diaspora_id_list: {minimum: val}) + }.to raise_error ArgumentError, "The :minimum needs to be an Integer" + end + end + + it "has an error key" do + expect(described_class.new(maximum: 5).error_key).to eq(:diaspora_id_list) + end + + context "validation" do + it "validates less ids" do + validator = Validation::Validator.new(OpenStruct.new(ids: id_str)) + validator.rule(:ids, diaspora_id_list: {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_list: {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_list: {minimum: 3, maximum: 3}) + + expect(validator).to be_valid + expect(validator.errors).to be_empty + end + + it "validates without params" do + validator = Validation::Validator.new(OpenStruct.new(ids: id_str)) + validator.rule(:ids, :diaspora_id_list) + + 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_list: {maximum: 2}) + + expect(validator).not_to be_valid + expect(validator.errors).to include(:ids) + end + + it "fails for too less ids" do + validator = Validation::Validator.new(OpenStruct.new(ids: id_str)) + validator.rule(:ids, diaspora_id_list: {minimum: 4}) + + expect(validator).not_to be_valid + expect(validator.errors).to include(:ids) + end + end +end