hydra-validations 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 435663a78ed5e8ae4eed2d29cebbee6860792ed2
4
- data.tar.gz: 85cf53d256c12174cda539c5193afff0a0e08a8a
3
+ metadata.gz: b9dfa48b0a0b2e0a48f98c2e74997eb01561f0e9
4
+ data.tar.gz: e079173cde687fd5330d95899159f3770ecbe033
5
5
  SHA512:
6
- metadata.gz: cb3a7917caf907655fdfdcb3f1f304294c1cd4ea32abd73792b4301ac5b889b07a5c88e78c5519d8de86666c6d7419559fc6cbe3e82345cc81d16de833f9dd35
7
- data.tar.gz: 906c190556c2aecb9ecd23c9dc123398551725f032b0616481d497d956b5382ce56c116da718b21d882641de370348e2d9085a0a3a0e68b57be913db79c5b5cb
6
+ metadata.gz: d3bf062ad4331cbbf804944742f837b4e6c8bb1fdf79281e9f2d5438b51f29a10bedad490df5e7ce3fb321cd63a92eca683ddb74310b1c7f1aaf0b86b10b4612
7
+ data.tar.gz: c436515ce8b56ac20c3c50331b800a8fef0d891a31398f3d02f5f833c02523f72f8e154af0e352504860cc71549efeccf390a20ad64cf800c4d20dc1ea79effa
data/.travis.yml CHANGED
@@ -3,3 +3,6 @@ rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
5
  - 2.1
6
+ # ActiveFedora raises RuntimeError w/o this setting
7
+ env:
8
+ - environment="test"
data/README.md CHANGED
@@ -1,15 +1,18 @@
1
1
  hydra-validations
2
2
  =======================
3
3
 
4
- Custom validators for Hydra applications based on ActiveModel::Validations.
4
+ Custom validators for Hydra applications, based on ActiveModel::Validations.
5
5
 
6
- ### Dependencies
6
+ [![Build Status](https://travis-ci.org/projecthydra-labs/hydra-validations.svg?branch=master)](https://travis-ci.org/projecthydra-labs/hydra-validations)
7
+ [![Gem Version](https://badge.fury.io/rb/hydra-validations.svg)](http://badge.fury.io/rb/hydra-validations)
8
+
9
+ ## Dependencies
7
10
 
8
11
  * Ruby >= 1.9.3
9
12
  * ActiveModel 4.x
10
13
  * ActiveFedora 7.x
11
14
 
12
- ### Installation
15
+ ## Installation
13
16
 
14
17
  Include in your Gemfile:
15
18
 
@@ -23,14 +26,34 @@ and
23
26
  bundle install
24
27
  ```
25
28
 
26
- ### Example
29
+ ## Validators
30
+
31
+ See also the source code andn spec tests.
32
+
33
+ ### UniquenessValidator (ActiveFedora)
34
+
35
+ ```ruby
36
+ class Validatable < ActiveFedora::Base
37
+ include Hydra::Validations
38
+ has_metadata name: 'descMetadata', type: ActiveFedora::QualifiedDublinCoreDatastream
39
+ has_attributes :title, datastream: 'descMetadata', multiple: false
40
+ # Can use with multi-value attributes, but single cardinality is required.
41
+ # See SingleCardinalityValidator below.
42
+ has_attributes :source, datastream: 'descMetadata', multiple: true
43
+
44
+ # validates_uniqueness_of helper method
45
+ validates_uniqueness_of :title, solr_name: "title_ssi"
46
+
47
+ # Using `validates' with options
48
+ validates :source, uniqueness: { solr_name: "subject_ssim" }
49
+ end
50
+ ```
27
51
 
28
- With a PORO, we have to include ActiveModel::Validations.
29
- ActiveRecord::Base and ActiveFedora::Base already include ActiveModel::Validations.
52
+ ### SingleCardinalityValidatory (Can be used with POROs)
30
53
 
31
54
  ```ruby
32
55
  class Validatable
33
- include ActiveModel::Validations
56
+ include ActiveModel::Validations # required if not already included in class
34
57
  include Hydra::Validations
35
58
  attr_accessor :field
36
59
  validates :field, single_cardinality: true
@@ -1,8 +1,11 @@
1
1
  #
2
2
  # SingleCardinalityValidator - validates that an enumerator value has size 0 or 1
3
3
  #
4
- # validates :my_attr, single_cardinality: true
5
- # validates_single_cardinality_of :my_attr
4
+ # validates :myattr, single_cardinality: true
5
+ # validates_single_cardinality_of :myattr
6
+ #
7
+ # Blank and nil values are considered valid (even without :allow_blank or :allow_nil
8
+ # validator options).
6
9
  #
7
10
  module Hydra
8
11
  module Validations
@@ -1,3 +1,5 @@
1
+ require 'hydra/validations'
2
+
1
3
  module Hydra
2
4
  module Validations
3
5
  #
@@ -11,28 +13,26 @@ module Hydra
11
13
  # Restrictions:
12
14
  #
13
15
  # - Accepts only one attribute (can have more than one UniquenessValidator on a model, however)
14
- # - Attribute cannot be multi-valued (:multiple=>true option of `has_attributes')
15
16
  # - :solr_name option must be present
17
+ # - Can be used on enumerable values (attribute defined with :multiple=>true option), but
18
+ # validator subclasses SingleCardinalityValidator, so will not pass validation if enumerable
19
+ # has more than one member.
16
20
  #
17
21
  # CAVEAT: The determination of uniqueness depends on a Solr query.
18
22
  # False negatives (record invalid) may result if, for example,
19
23
  # querying a Solr field of type "text".
20
24
  #
21
- class UniquenessValidator < ActiveModel::EachValidator
22
-
23
- def initialize(options = {})
24
- super
25
- attributes.each do |attr|
26
- raise ArgumentError, "Cannot validate uniqueness on a multi-valued attribute: #{attribute}." if options[:class].multiple?(attr)
27
- end
28
- end
25
+ class UniquenessValidator < SingleCardinalityValidator
29
26
 
30
27
  def check_validity!
28
+ super
31
29
  raise ArgumentError, "UniquenessValidator accepts only a single attribute: #{attribues}" if attributes.length > 1
32
30
  raise ArgumentError, "UniquenessValidator requires the :solr_name option be present." unless options[:solr_name].present?
33
31
  end
34
32
 
35
33
  def validate_each(record, attribute, value)
34
+ super
35
+ value = value.first if record.class.multiple?(attribute)
36
36
  conditions = {options[:solr_name] => value}
37
37
  conditions.merge!("-id" => record.id) if record.persisted?
38
38
  if record.class.exists? conditions
@@ -1,5 +1,5 @@
1
1
  module Hydra
2
2
  module Validations
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'active_model'
2
1
  require 'hydra/validations'
3
2
 
4
3
  RSpec.configure do |config|
@@ -0,0 +1,33 @@
1
+ shared_examples "it validates the single cardinality of an enumerable attribute" do
2
+ it "should be valid when the attribute value is nil" do
3
+ subject.send("#{attribute}=", nil)
4
+ expect(subject).to be_valid
5
+ end
6
+ it "should be valid if the value is empty" do
7
+ subject.send("#{attribute}=", [])
8
+ expect(subject).to be_valid
9
+ end
10
+ it "should be valid if the value has one element" do
11
+ subject.send("#{attribute}=", ["foo"])
12
+ expect(subject).to be_valid
13
+ end
14
+ it "should be invalid if the value has more than one element" do
15
+ subject.send("#{attribute}=", ["foo", "bar"])
16
+ expect(subject).not_to be_valid
17
+ end
18
+ end
19
+
20
+ shared_examples "it validates the single cardinality of a scalar attribute" do
21
+ it "should be valid when the attribute value is nil" do
22
+ subject.send("#{attribute}=", nil)
23
+ expect(subject).to be_valid
24
+ end
25
+ it "should be valid when the value is blank" do
26
+ subject.send("#{attribute}=", "")
27
+ expect(subject).to be_valid
28
+ end
29
+ it "should be valid when the value is present" do
30
+ subject.send("#{attribute}=", "foo")
31
+ expect(subject).to be_valid
32
+ end
33
+ end
@@ -1,28 +1,9 @@
1
1
  require 'spec_helper'
2
+ require 'support/shared_examples_for_validators'
2
3
 
3
- shared_examples "it validates the single cardinality of the field" do
4
- it "should be valid when the field value is nil" do
5
- subject.field = nil
6
- expect(subject).to be_valid
7
- end
8
- it "should be valid when the field value is a scalar" do
9
- subject.field = "foo"
10
- expect(subject).to be_valid
11
- end
12
- context "when the field value is an enumerable" do
13
- it "should be valid if the value is empty" do
14
- subject.field = []
15
- expect(subject).to be_valid
16
- end
17
- it "should be valid if the value has one element" do
18
- subject.field = ["foo"]
19
- expect(subject).to be_valid
20
- end
21
- it "should be invalid if the value has more than one element" do
22
- subject.field = ["foo", "bar"]
23
- expect(subject).not_to be_valid
24
- end
25
- end
4
+ shared_examples "it validates the single cardinality of the attribute" do
5
+ it_behaves_like "it validates the single cardinality of a scalar attribute"
6
+ it_behaves_like "it validates the single cardinality of an enumerable attribute"
26
7
  end
27
8
 
28
9
  describe Hydra::Validations::SingleCardinalityValidator do
@@ -38,11 +19,15 @@ describe Hydra::Validations::SingleCardinalityValidator do
38
19
  subject { Validatable.new }
39
20
  describe ".validates" do
40
21
  before { Validatable.validates :field, single_cardinality: true }
41
- it_behaves_like "it validates the single cardinality of the field"
22
+ it_behaves_like "it validates the single cardinality of the attribute" do
23
+ let(:attribute) { :field }
24
+ end
42
25
  end
43
26
  describe ".validates_single_cardinality_of" do
44
27
  before { Validatable.validates_single_cardinality_of :field }
45
- it_behaves_like "it validates the single cardinality of the field"
28
+ it_behaves_like "it validates the single cardinality of the attribute" do
29
+ let(:attribute) { :field }
30
+ end
46
31
  end
47
32
  end
48
33
 
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'active_fedora'
3
+ require 'support/shared_examples_for_validators'
3
4
 
4
5
  shared_examples "it validates the uniqueness of the attribute value" do
5
6
  context "when the value is not taken" do
@@ -23,8 +24,7 @@ describe Hydra::Validations::UniquenessValidator do
23
24
  include Hydra::Validations
24
25
  has_metadata name: 'descMetadata', type: ActiveFedora::QualifiedDublinCoreDatastream
25
26
  has_attributes :title, datastream: 'descMetadata', multiple: false
26
- has_attributes :creator, datastream: 'descMetadata', multiple: false
27
- has_attributes :subject, datastream: 'descMetadata', multiple: true
27
+ has_attributes :source, datastream: 'descMetadata', multiple: true
28
28
  end
29
29
  end
30
30
 
@@ -32,11 +32,8 @@ describe Hydra::Validations::UniquenessValidator do
32
32
 
33
33
  describe "exceptions" do
34
34
  before { Validatable.clear_validators! }
35
- it "cannot be used on a multi-valued attribute" do
36
- expect { Validatable.validates :subject, uniqueness: { solr_name: "subject_ssim" } }.to raise_error
37
- end
38
35
  it "cannot be used on more than one attribute at a time" do
39
- expect { Validatable.validates :title, :creator, uniqueness: { solr_name: "snafu_ssim" } }.to raise_error
36
+ expect { Validatable.validates :title, :source, uniqueness: { solr_name: "snafu_ssim" } }.to raise_error
40
37
  end
41
38
  it "cannot be used without the :solr_name option" do
42
39
  expect { Validatable.validates :title, uniqueness: true }.to raise_error
@@ -44,23 +41,54 @@ describe Hydra::Validations::UniquenessValidator do
44
41
  end
45
42
 
46
43
  describe "validation" do
47
- subject { Validatable.new(pid: "foobar:1", title: "I am Unique!") }
48
- let(:solr_name) { "title_ssi" }
49
- before do
50
- Validatable.clear_validators!
51
- Validatable.validates_uniqueness_of :title, solr_name: solr_name
52
- end
53
- context "when the record is new" do
54
- before { allow(subject).to receive(:persisted?) { false } }
55
- it_behaves_like "it validates the uniqueness of the attribute value" do
56
- let(:conditions) { {solr_name => subject.title} }
44
+ subject { Validatable.new(pid: "foobar:1", title: "I am Unique!", source: ["Outer Space"]) }
45
+ context "with a scalar attribute (:multiple=>false)" do
46
+ before(:all) do
47
+ Validatable.clear_validators!
48
+ Validatable.validates_uniqueness_of :title, solr_name: "title_ssi"
49
+ end
50
+ context "cardinality validation" do
51
+ before { allow(Validatable).to receive(:exists?) { false } }
52
+ it_behaves_like "it validates the single cardinality of a scalar attribute" do
53
+ let(:attribute) { :title }
54
+ end
55
+ end
56
+ context "when the record is new" do
57
+ before { allow(subject).to receive(:persisted?) { false } }
58
+ it_behaves_like "it validates the uniqueness of the attribute value" do
59
+ let(:conditions) { {"title_ssi" => subject.title} }
60
+ end
61
+ end
62
+ context "when the record is persisted" do
63
+ before { allow(subject).to receive(:persisted?) { true } }
64
+ it_behaves_like "it validates the uniqueness of the attribute value" do
65
+ let(:conditions) { {"title_ssi" => subject.title, "-id" => subject.pid} }
66
+ end
57
67
  end
58
68
  end
59
- context "when the record is persisted" do
60
- before { allow(subject).to receive(:persisted?) { true } }
61
- it_behaves_like "it validates the uniqueness of the attribute value" do
62
- let(:conditions) { {solr_name => subject.title, "-id" => subject.pid} }
69
+ context "with an enumerable attribute (:multiple=>true)" do
70
+ before(:all) do
71
+ Validatable.clear_validators!
72
+ Validatable.validates_uniqueness_of :source, solr_name: "source_ssim"
73
+ end
74
+ context "cardinality validation" do
75
+ before { allow(Validatable).to receive(:exists?) { false } }
76
+ it_behaves_like "it validates the single cardinality of an enumerable attribute" do
77
+ let(:attribute) { :source }
78
+ end
79
+ end
80
+ context "when the record is new" do
81
+ before { allow(subject).to receive(:persisted?) { false } }
82
+ it_behaves_like "it validates the uniqueness of the attribute value" do
83
+ let(:conditions) { {"source_ssim" => subject.source.first} }
84
+ end
63
85
  end
86
+ context "when the record is persisted" do
87
+ before { allow(subject).to receive(:persisted?) { true } }
88
+ it_behaves_like "it validates the uniqueness of the attribute value" do
89
+ let(:conditions) { {"source_ssim" => subject.source.first, "-id" => subject.pid} }
90
+ end
91
+ end
64
92
  end
65
93
  end
66
94
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hydra-validations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dchandekstark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-16 00:00:00.000000000 Z
11
+ date: 2014-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -102,6 +102,7 @@ files:
102
102
  - lib/hydra/validations/uniqueness_validator.rb
103
103
  - lib/hydra/validations/version.rb
104
104
  - spec/spec_helper.rb
105
+ - spec/support/shared_examples_for_validators.rb
105
106
  - spec/validators/single_cardinality_validator_spec.rb
106
107
  - spec/validators/uniqueness_validator_spec.rb
107
108
  homepage: https://github.com/duke-libraries/hydra-validations
@@ -131,5 +132,6 @@ specification_version: 4
131
132
  summary: Validations for Hydra applications, based on ActiveModel::Validations
132
133
  test_files:
133
134
  - spec/spec_helper.rb
135
+ - spec/support/shared_examples_for_validators.rb
134
136
  - spec/validators/single_cardinality_validator_spec.rb
135
137
  - spec/validators/uniqueness_validator_spec.rb