contentful_model 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/contentful_model.rb +17 -13
- data/lib/contentful_model/asset.rb +30 -0
- data/lib/contentful_model/asset_dimension_query.rb +70 -0
- data/lib/contentful_model/asset_dimensions.rb +54 -0
- data/lib/contentful_model/associations/associations.rb +10 -4
- data/lib/contentful_model/associations/belongs_to.rb +9 -4
- data/lib/contentful_model/associations/belongs_to_many.rb +22 -45
- data/lib/contentful_model/associations/has_many.rb +15 -13
- data/lib/contentful_model/associations/has_many_nested.rb +39 -37
- data/lib/contentful_model/associations/has_one.rb +22 -14
- data/lib/contentful_model/base.rb +115 -74
- data/lib/contentful_model/client.rb +14 -3
- data/lib/contentful_model/errors.rb +0 -1
- data/lib/contentful_model/manageable.rb +49 -21
- data/lib/contentful_model/management.rb +1 -0
- data/lib/contentful_model/migrations/content_type.rb +24 -24
- data/lib/contentful_model/migrations/content_type_factory.rb +9 -6
- data/lib/contentful_model/migrations/migration.rb +9 -4
- data/lib/contentful_model/queries.rb +60 -9
- data/lib/contentful_model/query.rb +148 -5
- data/lib/contentful_model/validations/lambda_validation.rb +17 -0
- data/lib/contentful_model/validations/validates_presence_of.rb +4 -1
- data/lib/contentful_model/validations/validations.rb +56 -8
- data/lib/contentful_model/version.rb +1 -1
- data/spec/asset_spec.rb +141 -0
- data/spec/associations/belongs_to_many_spec.rb +38 -0
- data/spec/associations/belongs_to_spec.rb +22 -0
- data/spec/associations/has_many_nested_spec.rb +321 -0
- data/spec/associations/has_many_spec.rb +33 -0
- data/spec/associations/has_one_spec.rb +32 -0
- data/spec/base_spec.rb +199 -0
- data/spec/chainable_queries_spec.rb +199 -0
- data/spec/client_spec.rb +11 -0
- data/spec/contentful_model_spec.rb +25 -0
- data/spec/fixtures/vcr_cassettes/asset/all.yml +161 -0
- data/spec/fixtures/vcr_cassettes/asset/find.yml +118 -0
- data/spec/fixtures/vcr_cassettes/association/belongs_to_many.yml +439 -0
- data/spec/fixtures/vcr_cassettes/association/has_many.yml +161 -0
- data/spec/fixtures/vcr_cassettes/association/has_one.yml +161 -0
- data/spec/fixtures/vcr_cassettes/association/nested_with_root_root.yml +240 -0
- data/spec/fixtures/vcr_cassettes/association/nested_without_root_child_higher_include.yml +123 -0
- data/spec/fixtures/vcr_cassettes/association/nested_without_root_child_parent.yml +609 -0
- data/spec/fixtures/vcr_cassettes/association/nested_without_root_childless.yml +688 -0
- data/spec/fixtures/vcr_cassettes/association/nested_without_root_middle.yml +319 -0
- data/spec/fixtures/vcr_cassettes/association/nested_without_root_middle_higher_include.yml +161 -0
- data/spec/fixtures/vcr_cassettes/association/nested_without_root_middle_parent.yml +489 -0
- data/spec/fixtures/vcr_cassettes/association/nested_without_root_parentless.yml +331 -0
- data/spec/fixtures/vcr_cassettes/association/nested_without_root_parentless_higher_include.yml +82 -0
- data/spec/fixtures/vcr_cassettes/associations/nested_without_root_middle.yml +161 -0
- data/spec/fixtures/vcr_cassettes/associations/nested_without_root_middle_higher_include.yml +82 -0
- data/spec/fixtures/vcr_cassettes/base/content_type.yml +185 -0
- data/spec/fixtures/vcr_cassettes/base/return_nil_for_empty.yml +202 -0
- data/spec/fixtures/vcr_cassettes/base/return_nil_for_empty_with_value.yml +124 -0
- data/spec/fixtures/vcr_cassettes/client.yml +98 -0
- data/spec/fixtures/vcr_cassettes/dog.yml +161 -0
- data/spec/fixtures/vcr_cassettes/human.yml +199 -0
- data/spec/fixtures/vcr_cassettes/management/client.yml +1362 -0
- data/spec/fixtures/vcr_cassettes/management/nyancat.yml +1449 -0
- data/spec/fixtures/vcr_cassettes/management/nyancat_2.yml +1449 -0
- data/spec/fixtures/vcr_cassettes/management/nyancat_publish.yml +481 -0
- data/spec/fixtures/vcr_cassettes/management/nyancat_refetch_and_fail.yml +558 -0
- data/spec/fixtures/vcr_cassettes/management/nyancat_refetch_and_save.yml +620 -0
- data/spec/fixtures/vcr_cassettes/management/nyancat_save.yml +479 -0
- data/spec/fixtures/vcr_cassettes/management/nyancat_save_2.yml +479 -0
- data/spec/fixtures/vcr_cassettes/nyancat.yml +196 -0
- data/spec/fixtures/vcr_cassettes/playground/nyancat.yml +177 -0
- data/spec/fixtures/vcr_cassettes/query/each_entry.yml +319 -0
- data/spec/fixtures/vcr_cassettes/query/each_page.yml +319 -0
- data/spec/fixtures/vcr_cassettes/query/empty.yml +180 -0
- data/spec/fixtures/vcr_cassettes/query/load.yml +197 -0
- data/spec/fixtures/vcr_cassettes/query/manual_pagination.yml +161 -0
- data/spec/fixtures/vcr_cassettes/query/nyancat_invalid_elements.yml +247 -0
- data/spec/manageable_spec.rb +186 -0
- data/spec/management_spec.rb +17 -0
- data/spec/migrations/content_type_factory_spec.rb +41 -0
- data/spec/migrations/content_type_spec.rb +176 -0
- data/spec/migrations/migration_spec.rb +75 -0
- data/spec/queries_spec.rb +85 -0
- data/spec/query_spec.rb +126 -0
- data/spec/spec_helper.rb +58 -0
- data/spec/validations/validations_spec.rb +182 -0
- metadata +213 -19
- data/lib/contentful_model/chainable_queries.rb +0 -104
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class NameValidation
|
4
|
+
def validate(entry)
|
5
|
+
return [] if entry.name == 'Nyan Cat'
|
6
|
+
['Invalid Entry']
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class InvalidatedCat < ContentfulModel::Base
|
11
|
+
self.content_type_id = 'cat'
|
12
|
+
|
13
|
+
validate_with NameValidation.new, on_load: true
|
14
|
+
end
|
15
|
+
|
16
|
+
describe ContentfulModel::Queries do
|
17
|
+
before :each do
|
18
|
+
ContentfulModel.configure do |config|
|
19
|
+
config.space = 'cfexampleapi'
|
20
|
+
config.access_token = 'b4c0n73n7fu1'
|
21
|
+
config.entry_mapping = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
Cat.client = nil
|
25
|
+
Cat.instance_variable_set(:@query, ContentfulModel::Query.new(Cat))
|
26
|
+
|
27
|
+
InvalidatedCat.client = nil
|
28
|
+
InvalidatedCat.instance_variable_set(:@query, ContentfulModel::Query.new(InvalidatedCat))
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'class methods' do
|
32
|
+
describe '::load' do
|
33
|
+
it 'returns the base query "/entries"' do
|
34
|
+
vcr('query/load') {
|
35
|
+
response = Cat.load
|
36
|
+
expect(response).to be_a ::Contentful::Array
|
37
|
+
expect(response.items.size).to eq 3
|
38
|
+
expect(response.total).to eq 3
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'filters out invalid elements' do
|
43
|
+
vcr('query/load') {
|
44
|
+
response = InvalidatedCat.load
|
45
|
+
expect(response).to be_a ::Contentful::Array
|
46
|
+
expect(response.items.size).to eq 1
|
47
|
+
expect(response.total).to eq 3
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it '::find' do
|
53
|
+
vcr('nyancat') {
|
54
|
+
nyancat = Cat.find('nyancat')
|
55
|
+
expect(nyancat).to be_a Cat
|
56
|
+
expect(nyancat.name).to eq 'Nyan Cat'
|
57
|
+
expect(nyancat.id).to eq 'nyancat'
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
it '::paginate' do
|
62
|
+
vcr('query/manual_pagination') {
|
63
|
+
happy_cat = Cat.paginate(2, 2).load.first
|
64
|
+
expect(happy_cat.name).to eq 'Happy Cat'
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
it '::each_page' do
|
69
|
+
vcr('query/each_page') {
|
70
|
+
Cat.each_page(2) do |page|
|
71
|
+
expect(page).to be_a ::Contentful::Array
|
72
|
+
expect(page.first).to be_a Cat
|
73
|
+
end
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
it '::each_entry' do
|
78
|
+
vcr('query/each_entry') {
|
79
|
+
Cat.each_entry(2) do |cat|
|
80
|
+
expect(cat).to be_a Cat
|
81
|
+
end
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/spec/query_spec.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Foo < ContentfulModel::Base
|
4
|
+
end
|
5
|
+
|
6
|
+
class OneInclude < ContentfulModel::Base
|
7
|
+
has_one :foo
|
8
|
+
end
|
9
|
+
|
10
|
+
class MultiInclude < ContentfulModel::Base
|
11
|
+
has_one :one_include
|
12
|
+
end
|
13
|
+
|
14
|
+
class CircularInclude < ContentfulModel::Base
|
15
|
+
has_many :to_circulars
|
16
|
+
end
|
17
|
+
|
18
|
+
class ToCircular < ContentfulModel::Base
|
19
|
+
has_one :circular_include
|
20
|
+
end
|
21
|
+
|
22
|
+
class Bar < ContentfulModel::Base
|
23
|
+
end
|
24
|
+
|
25
|
+
class MultiIncludeWithVaryingReferenceDepth < ContentfulModel::Base
|
26
|
+
has_one :one_include
|
27
|
+
has_one :bar
|
28
|
+
end
|
29
|
+
|
30
|
+
describe ContentfulModel::Query do
|
31
|
+
let(:parameters) { { 'sys.id' => 'foo' } }
|
32
|
+
let(:entry) { vcr('nyancat') { Cat.find('nyancat') } }
|
33
|
+
subject { described_class.new(Cat, parameters) }
|
34
|
+
|
35
|
+
before :each do
|
36
|
+
ContentfulModel.configure do |config|
|
37
|
+
config.space = 'cfexampleapi'
|
38
|
+
config.access_token = 'b4c0n73n7fu1'
|
39
|
+
config.entry_mapping = {}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'attributes' do
|
44
|
+
it ':parameters' do
|
45
|
+
expect(subject.parameters).to eq parameters
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'instance_methods' do
|
50
|
+
before :each do
|
51
|
+
Cat.client = nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it '#<< updates parameters' do
|
55
|
+
expect(subject.parameters).to eq parameters
|
56
|
+
|
57
|
+
subject << {foo: 'bar'}
|
58
|
+
|
59
|
+
expect(subject.parameters).to eq parameters.merge(foo: 'bar')
|
60
|
+
end
|
61
|
+
|
62
|
+
it '#default_parameters' do
|
63
|
+
expect(subject.default_parameters).to eq('content_type' => 'cat')
|
64
|
+
end
|
65
|
+
|
66
|
+
it '#client' do
|
67
|
+
vcr('client') {
|
68
|
+
expect(subject.client).to eq Cat.client
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
it '#reset' do
|
73
|
+
subject << {'foo' => 'bar'}
|
74
|
+
|
75
|
+
subject.reset
|
76
|
+
|
77
|
+
expect(subject.parameters).to eq subject.default_parameters
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#execute' do
|
81
|
+
it 'when response is empty' do
|
82
|
+
vcr('query/empty') {
|
83
|
+
expect(subject.execute.items).to eq []
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'when response contains items' do
|
88
|
+
query = described_class.new(Cat, 'sys.id' => 'nyancat')
|
89
|
+
vcr('nyancat') {
|
90
|
+
entries = query.execute
|
91
|
+
expect(entries.first.id).to eq 'nyancat'
|
92
|
+
}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#discover_includes' do
|
97
|
+
it 'defaults to 1 for a class without associations' do
|
98
|
+
query = described_class.new(Cat)
|
99
|
+
expect(query.discover_includes).to eq 1
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'adds an include level if it finds another nested item' do
|
103
|
+
query = described_class.new(OneInclude)
|
104
|
+
expect(query.discover_includes).to eq 2
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'follows the include chain' do
|
108
|
+
query = described_class.new(MultiInclude)
|
109
|
+
expect(query.discover_includes).to eq 3
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'can support circular references' do
|
113
|
+
query = described_class.new(CircularInclude)
|
114
|
+
expect(query.discover_includes).to eq 2
|
115
|
+
|
116
|
+
query = described_class.new(ToCircular)
|
117
|
+
expect(query.discover_includes).to eq 2
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'when having multiple reference chains, include is set to the maximum chain legth' do
|
121
|
+
query = described_class.new(MultiIncludeWithVaryingReferenceDepth)
|
122
|
+
expect(query.discover_includes).to eq 3
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
|
4
|
+
require 'contentful_model'
|
5
|
+
require 'rspec'
|
6
|
+
require 'vcr'
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.filter_run :focus => true
|
10
|
+
config.run_all_when_everything_filtered = true
|
11
|
+
end
|
12
|
+
|
13
|
+
VCR.configure do |c|
|
14
|
+
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
|
15
|
+
c.ignore_localhost = true
|
16
|
+
c.hook_into :webmock
|
17
|
+
c.default_cassette_options = { record: :once }
|
18
|
+
end
|
19
|
+
|
20
|
+
def vcr(name, &block)
|
21
|
+
VCR.use_cassette(name, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
class MockSpace
|
25
|
+
attr_reader :id
|
26
|
+
|
27
|
+
def initialize(id)
|
28
|
+
@id = id
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class MockClient
|
33
|
+
attr_accessor :response
|
34
|
+
|
35
|
+
def initialize(response = [])
|
36
|
+
@response = response
|
37
|
+
end
|
38
|
+
|
39
|
+
def entries(query = {})
|
40
|
+
response
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Cat < ContentfulModel::Base
|
45
|
+
self.content_type_id = 'cat'
|
46
|
+
end
|
47
|
+
|
48
|
+
class CoercedCat < ContentfulModel::Base
|
49
|
+
self.content_type_id = 'cat'
|
50
|
+
|
51
|
+
coerce_field name: -> (name) { name.gsub('Nyan', 'Fat') }
|
52
|
+
coerce_field created_at: 'String'
|
53
|
+
coerce_field updated_at: 'Date'
|
54
|
+
end
|
55
|
+
|
56
|
+
class TestModel < ContentfulModel::Base
|
57
|
+
self.content_type_id = 'testModel'
|
58
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class MockValidatableNoFields
|
4
|
+
include ContentfulModel::Validations
|
5
|
+
end
|
6
|
+
|
7
|
+
class MockValidatable
|
8
|
+
include ContentfulModel::Validations
|
9
|
+
|
10
|
+
attr_reader :fields
|
11
|
+
|
12
|
+
def initialize(fields = [])
|
13
|
+
@fields = fields
|
14
|
+
fields.each do |f|
|
15
|
+
define_singleton_method f do
|
16
|
+
"#{f}_value"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class MockValidatableWithAdditionalValidation < MockValidatable
|
23
|
+
validates_presence_of 'foo'
|
24
|
+
end
|
25
|
+
|
26
|
+
class BestFriendValidation
|
27
|
+
def validate(entry)
|
28
|
+
return ['Best Friend is not happycat'] unless entry.best_friend.try(:id) == 'happycat'
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class LivesValidation
|
34
|
+
def initialize(lives)
|
35
|
+
@lives = lives
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate(entry)
|
39
|
+
return ["Lives are not #{@lives}"] unless entry.lives == @lives
|
40
|
+
[]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class ValidationsCat < ContentfulModel::Base
|
45
|
+
self.content_type_id = 'cat'
|
46
|
+
|
47
|
+
# validation lambda
|
48
|
+
validate :name, -> (e) { e.name == 'Nyan Cat' }, on_load: true
|
49
|
+
|
50
|
+
# validation block
|
51
|
+
validate :id, on_load: true do |e|
|
52
|
+
e.id == 'nyancat'
|
53
|
+
end
|
54
|
+
|
55
|
+
# validation class
|
56
|
+
validate_with BestFriendValidation, on_load: true
|
57
|
+
|
58
|
+
# validation object
|
59
|
+
validate_with LivesValidation.new(1337), on_load: true
|
60
|
+
|
61
|
+
# validation only on save
|
62
|
+
validate :name, -> (e) { e.name == 'foobar' }
|
63
|
+
|
64
|
+
# presence validation
|
65
|
+
validates_presence_of :likes
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
describe ContentfulModel::Validations do
|
70
|
+
let(:validatable) { MockValidatable.new }
|
71
|
+
let(:non_validatable) { MockValidatableNoFields.new }
|
72
|
+
let(:validatable_with_fields) { MockValidatable.new(['foo']) }
|
73
|
+
let(:validatable_with_validations) { MockValidatableWithAdditionalValidation.new }
|
74
|
+
|
75
|
+
describe 'class methods' do
|
76
|
+
describe '::validations' do
|
77
|
+
it 'is nil by default' do
|
78
|
+
expect(validatable.class.validations).to eq nil
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'is an array of validations' do
|
82
|
+
expect(validatable_with_validations.class.validations).to be_a Array
|
83
|
+
expect(validatable_with_validations.class.validations.size).to eq 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'instance methods' do
|
89
|
+
describe '#validate' do
|
90
|
+
it 'returns false and sets error if its not an entry (aka. has no fields)' do
|
91
|
+
expect(non_validatable.validate).to be_falsey
|
92
|
+
expect(non_validatable.errors).to eq ["Entity doesn't respond to the fields() method"]
|
93
|
+
expect(non_validatable.valid?).to be_falsey
|
94
|
+
expect(non_validatable.invalid?).to be_truthy
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'returns false and sets error if validation does not pass' do
|
98
|
+
expect(validatable_with_validations.validate).to be_falsey
|
99
|
+
expect(validatable_with_validations.errors).to eq ["foo is required"]
|
100
|
+
expect(validatable_with_validations.valid?).to be_falsey
|
101
|
+
expect(validatable_with_validations.invalid?).to be_truthy
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'returns true if validations pass' do
|
105
|
+
ok_validatable = MockValidatableWithAdditionalValidation.new(['foo'])
|
106
|
+
|
107
|
+
expect(ok_validatable.validate).to be_truthy
|
108
|
+
expect(ok_validatable.errors).to be_empty
|
109
|
+
expect(ok_validatable.valid?).to be_truthy
|
110
|
+
expect(ok_validatable.invalid?).to be_falsey
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe 'integration' do
|
116
|
+
before :each do
|
117
|
+
ContentfulModel.configure do |config|
|
118
|
+
config.space = 'cfexampleapi'
|
119
|
+
config.access_token = 'b4c0n73n7fu1'
|
120
|
+
config.entry_mapping = {}
|
121
|
+
end
|
122
|
+
|
123
|
+
ValidationsCat.client = nil
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'can have many kinds of validations' do
|
127
|
+
expect(ValidationsCat.validations.size).to eq 5
|
128
|
+
expect(ValidationsCat.save_validations.size).to eq 1
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'can pass all validations' do
|
132
|
+
vcr('nyancat') {
|
133
|
+
nyancat = ValidationsCat.find('nyancat')
|
134
|
+
expect(nyancat.validate).to be_truthy
|
135
|
+
expect(nyancat.invalid?).to be_falsey
|
136
|
+
expect(nyancat.valid?).to be_truthy
|
137
|
+
expect(nyancat.errors).to be_empty
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'can validate save validations' do
|
142
|
+
vcr('nyancat') {
|
143
|
+
nyancat = ValidationsCat.find('nyancat')
|
144
|
+
|
145
|
+
expect(nyancat.validate(true)).to be_falsey
|
146
|
+
expect(nyancat.invalid?(true)).to be_truthy
|
147
|
+
expect(nyancat.valid?(true)).to be_falsey
|
148
|
+
expect(nyancat.errors.size).to eq 1
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'can fail a validation' do
|
153
|
+
vcr('nyancat') {
|
154
|
+
nyancat = ValidationsCat.find('nyancat')
|
155
|
+
nyancat.name = 'foobar'
|
156
|
+
expect(nyancat.validate).to be_falsey
|
157
|
+
expect(nyancat.invalid?).to be_truthy
|
158
|
+
expect(nyancat.errors).to eq ["name: validation not met"]
|
159
|
+
}
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'can fail multiple validations' do
|
163
|
+
vcr('nyancat') {
|
164
|
+
nyancat = ValidationsCat.find('nyancat')
|
165
|
+
nyancat.name = 'foobar'
|
166
|
+
nyancat.lives = 1000
|
167
|
+
nyancat.best_friend = nil
|
168
|
+
nyancat.sys[:id] = 'foo'
|
169
|
+
nyancat.likes = nil
|
170
|
+
|
171
|
+
expect(nyancat.validate).to be_falsey
|
172
|
+
expect(nyancat.errors).to match_array [
|
173
|
+
"name: validation not met",
|
174
|
+
"Lives are not 1337",
|
175
|
+
"Best Friend is not happycat",
|
176
|
+
"id: validation not met",
|
177
|
+
"likes is required"
|
178
|
+
]
|
179
|
+
}
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|