add validators from raven24
This commit is contained in:
parent
7be77154dc
commit
2301b1433e
19 changed files with 735 additions and 2 deletions
|
|
@ -3,6 +3,7 @@ require "diaspora_federation/logging"
|
|||
require "diaspora_federation/callbacks"
|
||||
require "diaspora_federation/properties_dsl"
|
||||
require "diaspora_federation/entity"
|
||||
require "diaspora_federation/validators"
|
||||
|
||||
require "diaspora_federation/fetcher"
|
||||
|
||||
|
|
|
|||
32
lib/diaspora_federation/validators.rb
Normal file
32
lib/diaspora_federation/validators.rb
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
require "validation"
|
||||
require "validation/rule/not_empty"
|
||||
require "validation/rule/email"
|
||||
require "validation/rule/regular_expression"
|
||||
require "validation/rule/uri"
|
||||
|
||||
# +valid+ gem namespace
|
||||
module Validation
|
||||
# This module contains custom validation rules for various data field types.
|
||||
# That includes types for which there are no provided rules by the +valid+ gem
|
||||
# or types that are very specific to Diaspora* federation and need special handling.
|
||||
# The rules are used inside the {DiasporaFederation::Validators validator classes}
|
||||
# to perform basic sanity-checks on {DiasporaFederation::Entities federation entities}.
|
||||
module Rule
|
||||
end
|
||||
end
|
||||
|
||||
require "diaspora_federation/validators/rules/birthday"
|
||||
require "diaspora_federation/validators/rules/boolean"
|
||||
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"
|
||||
|
||||
module DiasporaFederation
|
||||
# Validators to perform basic sanity-checks on {DiasporaFederation::Entities federation entities}.
|
||||
module Validators
|
||||
end
|
||||
end
|
||||
|
||||
require "diaspora_federation/validators/person_validator"
|
||||
require "diaspora_federation/validators/profile_validator"
|
||||
17
lib/diaspora_federation/validators/person_validator.rb
Normal file
17
lib/diaspora_federation/validators/person_validator.rb
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
module DiasporaFederation
|
||||
module Validators
|
||||
class PersonValidator < Validation::Validator
|
||||
include Validation
|
||||
|
||||
rule :guid, :guid
|
||||
|
||||
rule :diaspora_handle, %i(not_empty email)
|
||||
|
||||
rule :url, :u_r_i # WTF? :uri -> Uri -> "uninitialized constant Uri", :u_r_i -> URI -> \o/
|
||||
|
||||
rule :profile, :not_nil
|
||||
|
||||
rule :exported_key, :public_key
|
||||
end
|
||||
end
|
||||
end
|
||||
22
lib/diaspora_federation/validators/profile_validator.rb
Normal file
22
lib/diaspora_federation/validators/profile_validator.rb
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
module DiasporaFederation
|
||||
module Validators
|
||||
class ProfileValidator < Validation::Validator
|
||||
include Validation
|
||||
|
||||
rule :diaspora_handle, %i(not_empty email)
|
||||
|
||||
# the name must not contain a semicolon because of mentions
|
||||
# @{<name> ; <handle>}
|
||||
rule :first_name, regular_expression: {regex: /\A[^;]{,32}\z/}
|
||||
rule :last_name, regular_expression: {regex: /\A[^;]{,32}\z/}
|
||||
|
||||
rule :tag_string, tag_count: {maximum: 5}
|
||||
|
||||
rule :birthday, :birthday
|
||||
|
||||
rule :searchable, :boolean
|
||||
|
||||
rule :nsfw, :boolean
|
||||
end
|
||||
end
|
||||
end
|
||||
30
lib/diaspora_federation/validators/rules/birthday.rb
Normal file
30
lib/diaspora_federation/validators/rules/birthday.rb
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
require "date"
|
||||
|
||||
module Validation
|
||||
module Rule
|
||||
class Birthday
|
||||
attr_reader :params
|
||||
|
||||
# no parameters
|
||||
def initialize
|
||||
@params = {}
|
||||
end
|
||||
|
||||
def error_key
|
||||
:birthday
|
||||
end
|
||||
|
||||
def valid_value?(value)
|
||||
return true if value.nil? || (value.is_a?(String) && value.empty?)
|
||||
return true if value.is_a? Date
|
||||
|
||||
if value =~ /[0-9]{4}\-[0-9]{2}\-[0-9]{2}/
|
||||
date_field = value.split("-").map(&:to_i)
|
||||
return Date.valid_civil?(date_field[0], date_field[1], date_field[2])
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
30
lib/diaspora_federation/validators/rules/boolean.rb
Normal file
30
lib/diaspora_federation/validators/rules/boolean.rb
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
module Validation
|
||||
module Rule
|
||||
class Boolean
|
||||
attr_reader :params
|
||||
|
||||
# no parameters
|
||||
def initialize
|
||||
@params = {}
|
||||
end
|
||||
|
||||
def error_key
|
||||
:numeric
|
||||
end
|
||||
|
||||
def valid_value?(value)
|
||||
return false if value.nil?
|
||||
|
||||
if value.is_a?(String)
|
||||
true if value =~ /\A(true|false|t|f|yes|no|y|n|1|0)\z/i
|
||||
elsif value.is_a?(Fixnum)
|
||||
true if value == 1 || value == 0
|
||||
elsif value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
20
lib/diaspora_federation/validators/rules/guid.rb
Normal file
20
lib/diaspora_federation/validators/rules/guid.rb
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
module Validation
|
||||
module Rule
|
||||
class Guid
|
||||
attr_reader :params
|
||||
|
||||
# no parameters
|
||||
def initialize
|
||||
@params = {}
|
||||
end
|
||||
|
||||
def error_key
|
||||
:guid
|
||||
end
|
||||
|
||||
def valid_value?(value)
|
||||
value.is_a?(String) && value.downcase =~ /\A[0-9a-z\-_@.:]{16,}\z/
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
20
lib/diaspora_federation/validators/rules/not_nil.rb
Normal file
20
lib/diaspora_federation/validators/rules/not_nil.rb
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
module Validation
|
||||
module Rule
|
||||
class NotNil
|
||||
attr_reader :params
|
||||
|
||||
# no parameters
|
||||
def initialize
|
||||
@params = {}
|
||||
end
|
||||
|
||||
def error_key
|
||||
:not_nil
|
||||
end
|
||||
|
||||
def valid_value?(value)
|
||||
!value.nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
lib/diaspora_federation/validators/rules/public_key.rb
Normal file
24
lib/diaspora_federation/validators/rules/public_key.rb
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
module Validation
|
||||
module Rule
|
||||
class PublicKey
|
||||
attr_reader :params
|
||||
|
||||
# no parameters
|
||||
def initialize
|
||||
@params = {}
|
||||
end
|
||||
|
||||
def error_key
|
||||
:public_key
|
||||
end
|
||||
|
||||
# allow both "PUBLIC KEY" and "RSA PUBLIC KEY"
|
||||
def valid_value?(value)
|
||||
(value.strip.start_with?("-----BEGIN PUBLIC KEY-----") &&
|
||||
value.strip.end_with?("-----END PUBLIC KEY-----")) ||
|
||||
(value.strip.start_with?("-----BEGIN RSA PUBLIC KEY-----") &&
|
||||
value.strip.end_with?("-----END RSA PUBLIC KEY-----"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
27
lib/diaspora_federation/validators/rules/tag_count.rb
Normal file
27
lib/diaspora_federation/validators/rules/tag_count.rb
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
module Validation
|
||||
module Rule
|
||||
# Rule for validating the number of tags in a string.
|
||||
# Only the "#" characters will be counted.
|
||||
class TagCount
|
||||
attr_reader :params
|
||||
|
||||
# @param [Hash] params
|
||||
# @option params [Fixnum] :maximum maximum allowed tag 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
|
||||
:tag_count
|
||||
end
|
||||
|
||||
def valid_value?(value)
|
||||
value.count("#") <= params[:maximum]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -5,12 +5,36 @@ def r_str
|
|||
end
|
||||
|
||||
FactoryGirl.define do
|
||||
sequence(:diaspora_handle) {|n| "person-#{n}-#{r_str}@localhost:3000" }
|
||||
sequence(:public_key) { OpenSSL::PKey::RSA.generate(1024).public_key.export }
|
||||
|
||||
factory :person do
|
||||
sequence(:diaspora_handle) {|n| "person-#{n}-#{r_str}@localhost:3000" }
|
||||
diaspora_handle
|
||||
url "http://localhost:3000/"
|
||||
serialized_public_key OpenSSL::PKey::RSA.generate(1024).public_key.export
|
||||
serialized_public_key { generate(:public_key) }
|
||||
after(:create) do |u|
|
||||
u.save
|
||||
end
|
||||
end
|
||||
|
||||
factory :person_entity, class: DiasporaFederation::Entities::Person do
|
||||
guid UUID.generate :compact
|
||||
diaspora_handle "testing@example.com"
|
||||
url "http://localhost:3000/"
|
||||
exported_key { generate(:public_key) }
|
||||
profile {
|
||||
DiasporaFederation::Entities::Profile.new(
|
||||
FactoryGirl.attributes_for(:profile_entity, diaspora_handle: diaspora_handle))
|
||||
}
|
||||
end
|
||||
|
||||
factory :profile_entity, class: DiasporaFederation::Entities::Profile do
|
||||
diaspora_handle "testing@example.com"
|
||||
first_name "my_name"
|
||||
last_name nil
|
||||
tag_string "#i #love #tags"
|
||||
birthday "1988-07-15"
|
||||
searchable true
|
||||
nsfw false
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
module DiasporaFederation
|
||||
describe Validators::PersonValidator do
|
||||
it "validates a well-formed instance" do
|
||||
instance = OpenStruct.new(FactoryGirl.attributes_for(:person_entity))
|
||||
validator = Validators::PersonValidator.new(instance)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it_behaves_like "a diaspora_handle validator" do
|
||||
let(:entity) { :person_entity }
|
||||
let(:validator_class) { Validators::PersonValidator }
|
||||
let(:property) { :diaspora_handle }
|
||||
end
|
||||
|
||||
it_behaves_like "a guid validator" do
|
||||
let(:entity) { :person_entity }
|
||||
let(:validator_class) { Validators::PersonValidator }
|
||||
let(:property) { :guid }
|
||||
end
|
||||
|
||||
context "#exported_key" do
|
||||
it "fails for malformed rsa key" do
|
||||
instance = OpenStruct.new(FactoryGirl.attributes_for(:person_entity, exported_key: "ASDF"))
|
||||
validator = Validators::PersonValidator.new(instance)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:exported_key)
|
||||
end
|
||||
|
||||
it "must not be empty" do
|
||||
instance = OpenStruct.new(FactoryGirl.attributes_for(:person_entity, exported_key: ""))
|
||||
validator = Validators::PersonValidator.new(instance)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:exported_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
module DiasporaFederation
|
||||
describe Validators::ProfileValidator do
|
||||
def profile_stub(data={})
|
||||
OpenStruct.new(FactoryGirl.attributes_for(:profile_entity).merge(data))
|
||||
end
|
||||
|
||||
it "validates a well-formed instance" do
|
||||
validator = Validators::ProfileValidator.new(profile_stub)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it_behaves_like "a diaspora_handle validator" do
|
||||
let(:entity) { :profile_entity }
|
||||
let(:validator_class) { Validators::ProfileValidator }
|
||||
let(:property) { :diaspora_handle }
|
||||
end
|
||||
|
||||
%i(first_name last_name).each do |prop|
|
||||
describe "##{prop}" do
|
||||
it "allowed to contain special chars" do
|
||||
validator = Validators::ProfileValidator.new(profile_stub(prop => "cool name ©"))
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "must not exceed 32 chars" do
|
||||
validator = Validators::ProfileValidator.new(profile_stub(prop => "abcdefghijklmnopqrstuvwxyz_aaaaaaaaaa"))
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(prop)
|
||||
end
|
||||
|
||||
it "must not contain semicolons" do
|
||||
validator = Validators::ProfileValidator.new(profile_stub(prop => "asdf;qwer;yxcv"))
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(prop)
|
||||
end
|
||||
end
|
||||
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)
|
||||
end
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
%i(searchable nsfw).each do |prop|
|
||||
describe "##{prop}" do
|
||||
it_behaves_like "a boolean validator" do
|
||||
let(:entity) { :profile_entity }
|
||||
let(:validator_class) { Validators::ProfileValidator }
|
||||
let(:property) { prop }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
describe Validation::Rule::Birthday do
|
||||
it "will not accept parameters" do
|
||||
validator = Validation::Validator.new({})
|
||||
expect {
|
||||
validator.rule(:birthday, birthday: {param: true})
|
||||
}.to raise_error ArgumentError
|
||||
end
|
||||
|
||||
context "validation" do
|
||||
it "validates a date object" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(birthday: Date.new))
|
||||
validator.rule(:birthday, :birthday)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "validates a string" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(birthday: "2015-07-19"))
|
||||
validator.rule(:birthday, :birthday)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "validates an empty string" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(birthday: ""))
|
||||
validator.rule(:birthday, :birthday)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "validates nil" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(birthday: nil))
|
||||
validator.rule(:birthday, :birthday)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "fails for invalid date string" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(birthday: "i'm no date"))
|
||||
validator.rule(:birthday, :birthday)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:birthday)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
describe Validation::Rule::Boolean do
|
||||
it "will not accept parameters" do
|
||||
validator = Validation::Validator.new({})
|
||||
expect {
|
||||
validator.rule(:number, numeric: {param: true})
|
||||
}.to raise_error ArgumentError
|
||||
end
|
||||
|
||||
context "validation" do
|
||||
context "strings" do
|
||||
it "validates boolean-esque strings" do
|
||||
%w(true false yes no t f y n 1 0).each do |str|
|
||||
validator = Validation::Validator.new(OpenStruct.new(boolean: str))
|
||||
validator.rule(:boolean, :boolean)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
it "fails for non-boolean-esque strings" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(boolean: "asdf"))
|
||||
validator.rule(:boolean, :boolean)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:boolean)
|
||||
end
|
||||
end
|
||||
|
||||
context "numbers" do
|
||||
it "validates 0 and 1 to boolean" do
|
||||
[0, 1].each do |num|
|
||||
validator = Validation::Validator.new(OpenStruct.new(boolean: num))
|
||||
validator.rule(:boolean, :boolean)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
it "fails for all other numbers" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(boolean: 1234))
|
||||
validator.rule(:boolean, :boolean)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:boolean)
|
||||
end
|
||||
end
|
||||
|
||||
context "boolean types" do
|
||||
it "validates true and false" do
|
||||
[true, false].each do |bln|
|
||||
validator = Validation::Validator.new(OpenStruct.new(boolean: bln))
|
||||
validator.rule(:boolean, :boolean)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "fails for nil" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(boolean: nil))
|
||||
validator.rule(:boolean, :boolean)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:boolean)
|
||||
end
|
||||
end
|
||||
end
|
||||
59
spec/lib/diaspora_federation/validators/rules/guid_spec.rb
Normal file
59
spec/lib/diaspora_federation/validators/rules/guid_spec.rb
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
describe Validation::Rule::Guid do
|
||||
it "will not accept parameters" do
|
||||
validator = Validation::Validator.new({})
|
||||
expect {
|
||||
validator.rule(:guid, guid: {param: true})
|
||||
}.to raise_error ArgumentError
|
||||
end
|
||||
|
||||
context "validation" do
|
||||
it "validates a string at least 16 chars long, consisting of [0-9a-f] (diaspora)" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(guid: "abcdef0123456789"))
|
||||
validator.rule(:guid, :guid)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "validates a long string with random characters and [-_@.:] (redmatrix)" do
|
||||
validator = Validation::Validator.new(
|
||||
OpenStruct.new(guid: "1234567890ABCDefgh_ijkl-mnopqrSTUVwxyz@example.com:3000"))
|
||||
validator.rule(:guid, :guid)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "fails if the string is too short" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(guid: "012345"))
|
||||
validator.rule(:guid, :guid)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:guid)
|
||||
end
|
||||
|
||||
it "fails if the string contains invalid chars" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(guid: "ghijklmnopqrstuvwxyz++"))
|
||||
validator.rule(:guid, :guid)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:guid)
|
||||
end
|
||||
|
||||
it "fails if the string is empty" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(guid: ""))
|
||||
validator.rule(:guid, :guid)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:guid)
|
||||
end
|
||||
|
||||
it "fails if the string is nil" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(guid: nil))
|
||||
validator.rule(:guid, :guid)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:guid)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
describe Validation::Rule::Guid do
|
||||
it "will not accept parameters" do
|
||||
validator = Validation::Validator.new({})
|
||||
expect {
|
||||
validator.rule(:key, public_key: {param: true})
|
||||
}.to raise_error ArgumentError
|
||||
end
|
||||
|
||||
context "validation" do
|
||||
["PUBLIC KEY", "RSA PUBLIC KEY"].each do |key_type|
|
||||
context key_type do
|
||||
let(:prefix) { "-----BEGIN #{key_type}-----" }
|
||||
let(:suffix) { "-----END #{key_type}-----" }
|
||||
|
||||
let(:key) { "#{prefix}\nAAAAAA==\n#{suffix}\n" }
|
||||
|
||||
it "validates an exported RSA key" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(key: key))
|
||||
validator.rule(:key, :public_key)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "strips whitespace" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(key: " \n #{key}\n \n "))
|
||||
validator.rule(:key, :public_key)
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "fails if the prefix is missing" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(key: "\nAAAAAA==\n#{suffix}\n"))
|
||||
validator.rule(:key, :public_key)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:key)
|
||||
end
|
||||
|
||||
it "fails if the suffix is missing" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(key: "#{prefix}\nAAAAAA==\n\n"))
|
||||
validator.rule(:key, :public_key)
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
describe Validation::Rule::TagCount do
|
||||
it "requires a parameter" do
|
||||
validator = Validation::Validator.new({})
|
||||
expect {
|
||||
validator.rule(:tags, :tag_count)
|
||||
}.to raise_error ArgumentError
|
||||
end
|
||||
|
||||
context "validation" do
|
||||
let(:tag_str) { "#i #love #tags" }
|
||||
|
||||
it "validates less tags" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(tags: tag_str))
|
||||
validator.rule(:tags, tag_count: {maximum: 5})
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "validates exactly as many tags" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(tags: tag_str))
|
||||
validator.rule(:tags, tag_count: {maximum: 3})
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "fails for too many tags" do
|
||||
validator = Validation::Validator.new(OpenStruct.new(tags: tag_str))
|
||||
validator.rule(:tags, tag_count: {maximum: 1})
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(:tags)
|
||||
end
|
||||
end
|
||||
end
|
||||
85
spec/support/shared_validator_specs.rb
Normal file
85
spec/support/shared_validator_specs.rb
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
def entity_stub(entity, property, val=nil)
|
||||
instance = OpenStruct.new(FactoryGirl.attributes_for(entity))
|
||||
instance.public_send("#{property}=", val) unless val.nil?
|
||||
instance
|
||||
end
|
||||
|
||||
shared_examples "a diaspora_handle validator" do
|
||||
it "validates a well-formed diaspora_handle" do
|
||||
validator = validator_class.new(entity_stub(entity, property))
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "must not be empty" do
|
||||
validator = validator_class.new(entity_stub(entity, property, ""))
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(property)
|
||||
end
|
||||
|
||||
it "must resemble an email address" do
|
||||
validator = validator_class.new(entity_stub(entity, property, "i am a weird handle @@@ ### 12345"))
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(property)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "a guid validator" do
|
||||
it "validates a well-formed guid" do
|
||||
validator = validator_class.new(entity_stub(entity, property))
|
||||
|
||||
expect(validator).to be_valid
|
||||
expect(validator.errors).to be_empty
|
||||
end
|
||||
|
||||
it "validates a well-formed guid from redmatrix" do
|
||||
validator = validator_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 = validator_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 = validator_class.new(entity_stub(entity, property, "zzz+-#*$$"))
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(property)
|
||||
end
|
||||
|
||||
it "must not be empty" do
|
||||
validator = validator_class.new(entity_stub(entity, property, ""))
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(property)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "a boolean validator" do
|
||||
it "validates a well-formed boolean" do
|
||||
[true, "true", false, "false"].each do |val|
|
||||
validator = validator_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", Time.zone.today, 1234].each do |val|
|
||||
validator = validator_class.new(entity_stub(entity, property, val))
|
||||
|
||||
expect(validator).not_to be_valid
|
||||
expect(validator.errors).to include(property)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue