diaspora_federation/spec/support/shared_validator_specs.rb
Benjamin Neff 32a49cc549
Get optional props from validated object
This is much easier and safer than "guessing" the class name based on
the validator name. That can cause a problem when another class with the
same name is found. The "guessing" was only added because we used
OpenStruct in the tests, but we shouldn't change the code only to make
tests run. I changed the tests to use the real entities, with
auto-validation disabled in the constructor, so we can test the
validator manually.
2018-02-14 01:37:20 +01:00

293 lines
8.5 KiB
Ruby

def entity_stub(entity, data={})
entity_class = Fabricate.schematic(entity).options[:class_name]
allow_any_instance_of(entity_class).to receive(:freeze)
allow_any_instance_of(entity_class).to receive(:validate)
entity_class.new(Fabricate.attributes_for(entity).merge(data))
end
ALPHANUMERIC_RANGE = [*"0".."9", *"A".."Z", *"a".."z"].freeze
def alphanumeric_string(length)
Array.new(length) { ALPHANUMERIC_RANGE.sample }.join
end
shared_examples "a common validator" do
it "validates a well-formed instance" do
validator = described_class.new(entity_stub(entity))
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
end
shared_examples "a relayable validator" do
it_behaves_like "a diaspora* ID validator" do
let(:property) { :author }
end
describe "#guid" do
it_behaves_like "a guid validator" do
let(:property) { :guid }
end
end
describe "#parent_guid" do
it_behaves_like "a guid validator" do
let(:property) { :parent_guid }
end
end
describe "#parent" do
it_behaves_like "a property with a value validation/restriction" do
let(:property) { :parent }
let(:wrong_values) { [nil] }
let(:correct_values) { [Fabricate(:related_entity)] }
end
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|
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 a well-formed diaspora* ID" do
validator = described_class.new(entity_stub(entity, property => "alice@example.org"))
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "must be a valid diaspora* ID" do
validator = described_class.new(entity_stub(entity, property => "i am a weird diaspora* ID @@@ ### 12345"))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
end
shared_examples "common guid validator" do
it "validates a well-formed guid from redmatrix" do
validator = described_class.new(entity_stub(entity, property => "1234567890ABCDefgh_ijkl-mnopQR@example.com:3000"))
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "must be at least 16 chars" do
validator = described_class.new(entity_stub(entity, property => "aaaaaa"))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
it "must only contain [0-9a-z-_@.:]" do
validator = described_class.new(entity_stub(entity, property => "zzz+-#*$$"))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
end
shared_examples "a guid validator" do
include_examples "common guid validator"
it "must not be nil or empty" do
[nil, ""].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
end
shared_examples "a nilable guid validator" do
include_examples "common guid validator"
it "can be nil" do
validator = described_class.new(entity_stub(entity, property => nil))
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
end
shared_examples "a boolean validator" do
it "validates a well-formed boolean" do
[true, "true", false, "false"].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
it "must not be an arbitrary string or other object" do
["asdf", Date.today, 1234].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
end
shared_examples "a public key validator" do
it "fails for malformed rsa key" do
validator = described_class.new(entity_stub(entity, property => "ASDF"))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
it "must not be nil or empty" do
[nil, ""].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
end
shared_examples "a name validator" do
it "is allowed to be nil or empty" do
[nil, ""].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
it "is allowed to contain special chars" do
validator = described_class.new(entity_stub(entity, property => "cool name ©"))
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "validates the maximum number of chars" do
validator = described_class.new(entity_stub(entity, property => alphanumeric_string(length)))
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "must not exceed the maximum number of chars" do
validator = described_class.new(entity_stub(entity, property => alphanumeric_string(length + 1)))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
it "must not contain semicolons" do
validator = described_class.new(entity_stub(entity, property => "asdf;qwer;yxcv"))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
end
shared_examples "a length validator" do
it "is allowed to be nil or empty" do
[nil, ""].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
it "is allowed to contain special chars" do
validator = described_class.new(entity_stub(entity, property => "cool name ©;:#%"))
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "validates the maximum number of chars" do
validator = described_class.new(entity_stub(entity, property => alphanumeric_string(length)))
expect(validator).to be_valid
expect(validator.errors).to be_empty
end
it "must not exceed the maximum number of chars" do
validator = described_class.new(entity_stub(entity, property => alphanumeric_string(length + 1)))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
end
shared_examples "a url validator without path" do
it "must not be nil or empty" do
[nil, ""].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 "fails for url with special chars" do
validator = described_class.new(entity_stub(entity, property => "https://asdf$%.com"))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
it "fails for url without scheme" do
validator = described_class.new(entity_stub(entity, property => "example.com"))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
end
shared_examples "a url path validator" do
it "fails for url with special chars" do
validator = described_class.new(entity_stub(entity, property => "https://asdf$%.com/some/path"))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
it "fails for url without path" do
validator = described_class.new(entity_stub(entity, property => "https://example.com"))
expect(validator).not_to be_valid
expect(validator.errors).to include(property)
end
end