Add abstract OptionalAwareValidator class
This improves validation of optional fields and respects the `optional` option of properties
This commit is contained in:
parent
9081328d51
commit
6f936caddf
27 changed files with 114 additions and 25 deletions
|
|
@ -37,6 +37,7 @@ end
|
||||||
require "diaspora_federation/validators/related_entity_validator"
|
require "diaspora_federation/validators/related_entity_validator"
|
||||||
|
|
||||||
# abstract types
|
# abstract types
|
||||||
|
require "diaspora_federation/validators/optional_aware_validator"
|
||||||
require "diaspora_federation/validators/relayable_validator"
|
require "diaspora_federation/validators/relayable_validator"
|
||||||
|
|
||||||
# types
|
# types
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::AccountDeletion}.
|
# This validates a {Entities::AccountDeletion}.
|
||||||
class AccountDeletionValidator < Validation::Validator
|
class AccountDeletionValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :author, %i[not_empty diaspora_id]
|
rule :author, %i[not_empty diaspora_id]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::AccountMigration}.
|
# This validates a {Entities::AccountMigration}.
|
||||||
class AccountMigrationValidator < Validation::Validator
|
class AccountMigrationValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :author, %i[not_empty diaspora_id]
|
rule :author, %i[not_empty diaspora_id]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Comment}.
|
# This validates a {Entities::Comment}.
|
||||||
class CommentValidator < Validation::Validator
|
class CommentValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
include RelayableValidator
|
include RelayableValidator
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Contact}.
|
# This validates a {Entities::Contact}.
|
||||||
class ContactValidator < Validation::Validator
|
class ContactValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :author, %i[not_empty diaspora_id]
|
rule :author, %i[not_empty diaspora_id]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Conversation}.
|
# This validates a {Entities::Conversation}.
|
||||||
class ConversationValidator < Validation::Validator
|
class ConversationValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :author, %i[not_empty diaspora_id]
|
rule :author, %i[not_empty diaspora_id]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::EventParticipation}.
|
# This validates a {Entities::EventParticipation}.
|
||||||
class EventParticipationValidator < Validation::Validator
|
class EventParticipationValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
include RelayableValidator
|
include RelayableValidator
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Event}.
|
# This validates a {Entities::Event}.
|
||||||
class EventValidator < Validation::Validator
|
class EventValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :author, %i[not_empty diaspora_id]
|
rule :author, %i[not_empty diaspora_id]
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ module DiasporaFederation
|
||||||
# This validates a {Discovery::HCard}.
|
# This validates a {Discovery::HCard}.
|
||||||
#
|
#
|
||||||
# @note
|
# @note
|
||||||
class HCardValidator < Validation::Validator
|
class HCardValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :guid, :guid
|
rule :guid, :guid
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Like}.
|
# This validates a {Entities::Like}.
|
||||||
class LikeValidator < Validation::Validator
|
class LikeValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
include RelayableValidator
|
include RelayableValidator
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Location}.
|
# This validates a {Entities::Location}.
|
||||||
class LocationValidator < Validation::Validator
|
class LocationValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :lat, :not_empty
|
rule :lat, :not_empty
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Message}.
|
# This validates a {Entities::Message}.
|
||||||
class MessageValidator < Validation::Validator
|
class MessageValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :author, %i[not_empty diaspora_id]
|
rule :author, %i[not_empty diaspora_id]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
module DiasporaFederation
|
||||||
|
module Validators
|
||||||
|
# Abstract validator which only validates optional fields when they are not nil.
|
||||||
|
class OptionalAwareValidator < Validation::Validator
|
||||||
|
def rules
|
||||||
|
super.reject do |field, rules|
|
||||||
|
@obj.public_send(field).nil? &&
|
||||||
|
!rules.map(&:class).include?(Validation::Rule::NotNil) &&
|
||||||
|
optional_props.include?(field)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def optional_props
|
||||||
|
entity_name = self.class.name.split("::").last.sub("Validator", "")
|
||||||
|
return [] unless Entities.const_defined?(entity_name)
|
||||||
|
|
||||||
|
Entities.const_get(entity_name).optional_props
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Participation}.
|
# This validates a {Entities::Participation}.
|
||||||
class ParticipationValidator < Validation::Validator
|
class ParticipationValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :author, %i[not_empty diaspora_id]
|
rule :author, %i[not_empty diaspora_id]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Person}.
|
# This validates a {Entities::Person}.
|
||||||
class PersonValidator < Validation::Validator
|
class PersonValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :guid, :guid
|
rule :guid, :guid
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Photo}.
|
# This validates a {Entities::Photo}.
|
||||||
class PhotoValidator < Validation::Validator
|
class PhotoValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :guid, :guid
|
rule :guid, :guid
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::PollAnswer}.
|
# This validates a {Entities::PollAnswer}.
|
||||||
class PollAnswerValidator < Validation::Validator
|
class PollAnswerValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :guid, :guid
|
rule :guid, :guid
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::PollParticipation}.
|
# This validates a {Entities::PollParticipation}.
|
||||||
class PollParticipationValidator < Validation::Validator
|
class PollParticipationValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
include RelayableValidator
|
include RelayableValidator
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Poll}.
|
# This validates a {Entities::Poll}.
|
||||||
class PollValidator < Validation::Validator
|
class PollValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :guid, :guid
|
rule :guid, :guid
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Profile}.
|
# This validates a {Entities::Profile}.
|
||||||
class ProfileValidator < Validation::Validator
|
class ProfileValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :author, :diaspora_id
|
rule :author, :diaspora_id
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Reshare}.
|
# This validates a {Entities::Reshare}.
|
||||||
class ReshareValidator < Validation::Validator
|
class ReshareValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :root_author, :diaspora_id
|
rule :root_author, :diaspora_id
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::Retraction}.
|
# This validates a {Entities::Retraction}.
|
||||||
class RetractionValidator < Validation::Validator
|
class RetractionValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :author, %i[not_empty diaspora_id]
|
rule :author, %i[not_empty diaspora_id]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Validators
|
module Validators
|
||||||
# This validates a {Entities::StatusMessage}.
|
# This validates a {Entities::StatusMessage}.
|
||||||
class StatusMessageValidator < Validation::Validator
|
class StatusMessageValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :author, %i[not_empty diaspora_id]
|
rule :author, %i[not_empty diaspora_id]
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ module DiasporaFederation
|
||||||
#
|
#
|
||||||
# @note It does not validate the guid and public key, because it will be
|
# @note It does not validate the guid and public key, because it will be
|
||||||
# removed in the webfinger.
|
# removed in the webfinger.
|
||||||
class WebFingerValidator < Validation::Validator
|
class WebFingerValidator < OptionalAwareValidator
|
||||||
include Validation
|
include Validation
|
||||||
|
|
||||||
rule :acct_uri, :not_empty
|
rule :acct_uri, :not_empty
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ module DiasporaFederation
|
||||||
property :test5, :timestamp
|
property :test5, :timestamp
|
||||||
entity :test6, TestEntity
|
entity :test6, TestEntity
|
||||||
property :test7, :string, optional: true
|
property :test7, :string, optional: true
|
||||||
entity :multi, [OtherEntity]
|
entity :multi, [OtherEntity], optional: true
|
||||||
end
|
end
|
||||||
|
|
||||||
class TestEntityWithAuthorAndGuid < DiasporaFederation::Entity
|
class TestEntityWithAuthorAndGuid < DiasporaFederation::Entity
|
||||||
|
|
@ -94,5 +94,20 @@ module DiasporaFederation
|
||||||
rule :author, %i[not_empty diaspora_id]
|
rule :author, %i[not_empty diaspora_id]
|
||||||
rule :guid, :guid
|
rule :guid, :guid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class TestComplexEntityValidator < OptionalAwareValidator
|
||||||
|
include Validation
|
||||||
|
|
||||||
|
rule :test1, length: {minimum: 3}
|
||||||
|
rule :test2, :boolean
|
||||||
|
rule :test7, length: {minimum: 3}
|
||||||
|
rule :multi, :not_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
class TestUnknownEntityValidator < OptionalAwareValidator
|
||||||
|
include Validation
|
||||||
|
|
||||||
|
rule :test1, length: {minimum: 3}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
module DiasporaFederation
|
||||||
|
describe Validators::OptionalAwareValidator do
|
||||||
|
let(:entity_data) {
|
||||||
|
{test1: "abc", test2: true, test7: "abc", multi: []}
|
||||||
|
}
|
||||||
|
|
||||||
|
it "validates a valid object" do
|
||||||
|
validator = Validators::TestComplexEntityValidator.new(OpenStruct.new(entity_data))
|
||||||
|
expect(validator).to be_valid
|
||||||
|
expect(validator.errors).to be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails when a mandatory property is invalid" do
|
||||||
|
["ab", nil].each do |val|
|
||||||
|
entity = OpenStruct.new(entity_data.merge(test1: val))
|
||||||
|
validator = Validators::TestComplexEntityValidator.new(entity)
|
||||||
|
expect(validator).not_to be_valid
|
||||||
|
expect(validator.errors).to include(:test1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails when an optional property is invalid" do
|
||||||
|
entity = OpenStruct.new(entity_data.merge(test7: "ab"))
|
||||||
|
validator = Validators::TestComplexEntityValidator.new(entity)
|
||||||
|
expect(validator).not_to be_valid
|
||||||
|
expect(validator.errors).to include(:test7)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows an optional property to be nil" do
|
||||||
|
entity = OpenStruct.new(entity_data.merge(test7: nil))
|
||||||
|
validator = Validators::TestComplexEntityValidator.new(entity)
|
||||||
|
expect(validator).to be_valid
|
||||||
|
expect(validator.errors).to be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't ignore 'not_nil' rules for an optional property" do
|
||||||
|
entity = OpenStruct.new(entity_data.merge(multi: nil))
|
||||||
|
validator = Validators::TestComplexEntityValidator.new(entity)
|
||||||
|
expect(validator).not_to be_valid
|
||||||
|
expect(validator.errors).to include(:multi)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't fail when there is no entity for this validator" do
|
||||||
|
entity = OpenStruct.new(entity_data.merge(test1: nil))
|
||||||
|
validator = Validators::TestUnknownEntityValidator.new(entity)
|
||||||
|
expect(validator).not_to be_valid
|
||||||
|
expect(validator.errors).to include(:test1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -11,7 +11,7 @@ describe Validation::Rule::NotNil do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "validation" do
|
context "validation" do
|
||||||
it "validates a string " do
|
it "validates a string" do
|
||||||
validator = Validation::Validator.new(OpenStruct.new(not_nil: "abcd"))
|
validator = Validation::Validator.new(OpenStruct.new(not_nil: "abcd"))
|
||||||
validator.rule(:not_nil, :not_nil)
|
validator.rule(:not_nil, :not_nil)
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@ describe Validation::Rule::NotNil do
|
||||||
expect(validator.errors).to be_empty
|
expect(validator.errors).to be_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
it "validates a object " do
|
it "validates a object" do
|
||||||
validator = Validation::Validator.new(OpenStruct.new(not_nil: Object.new))
|
validator = Validation::Validator.new(OpenStruct.new(not_nil: Object.new))
|
||||||
validator.rule(:not_nil, :not_nil)
|
validator.rule(:not_nil, :not_nil)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue