forked from mongoid/mongoid-slug
-
Notifications
You must be signed in to change notification settings - Fork 0
/
criteria_spec.rb
209 lines (182 loc) · 8.01 KB
/
criteria_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# frozen_string_literal: true
require 'spec_helper'
describe Mongoid::Slug::Criteria do
describe '.find' do
let!(:book) { Book.create(title: 'A Working Title').tap { |d| d.update_attribute(:title, 'A Thousand Plateaus') } }
let!(:book2) { Book.create(title: 'Difference and Repetition') }
let!(:friend) { Friend.create(name: 'Jim Bob') }
let!(:friend2) { Friend.create(name: friend.id.to_s) }
let!(:integer_id) { IntegerId.new(name: 'I have integer ids').tap { |d| d.id = 123; d.save! } }
let!(:integer_id2) { IntegerId.new(name: integer_id.id.to_s).tap { |d| d.id = 456; d.save! } }
let!(:string_id) { StringId.new(name: 'I have string ids').tap { |d| d.id = 'abc'; d.save! } }
let!(:string_id2) { StringId.new(name: string_id.id.to_s).tap { |d| d.id = 'def'; d.save! } }
let!(:subject) { Subject.create(name: 'A Subject', book: book) }
let!(:subject2) { Subject.create(name: 'A Subject', book: book2) }
let!(:without_slug) { WithoutSlug.new.tap { |d| d.id = 456; d.save! } }
context 'when the model does not use mongoid slugs' do
it "should not use mongoid slug's custom find methods" do
expect_any_instance_of(Mongoid::Slug::Criteria).not_to receive(:find)
expect(WithoutSlug.find(without_slug.id.to_s)).to eq(without_slug)
end
end
context 'using slugs' do
context '(single)' do
context 'and a document is found' do
it 'returns the document as an object' do
expect(Book.find(book.slugs.first)).to eq(book)
end
end
context 'but no document is found' do
it 'raises a Mongoid::Errors::DocumentNotFound error' do
expect do
Book.find('Anti Oedipus')
end.to raise_error(Mongoid::Errors::DocumentNotFound)
end
end
end
context '(multiple)' do
context 'and all documents are found' do
it 'returns the documents as an array without duplication' do
expect(Book.find(book.slugs + book2.slugs)).to match_array([book, book2])
end
end
context 'but not all documents are found' do
it 'raises a Mongoid::Errors::DocumentNotFound error' do
expect do
Book.find(book.slugs + ['something-nonexistent'])
end.to raise_error(Mongoid::Errors::DocumentNotFound)
end
end
end
context 'when no documents match' do
it 'raises a Mongoid::Errors::DocumentNotFound error' do
expect do
Book.find('Anti Oedipus')
end.to raise_error(Mongoid::Errors::DocumentNotFound)
end
end
context 'when ids are BSON::ObjectIds and the supplied argument looks like a BSON::ObjectId' do
it 'it should find based on ids not slugs' do # i.e. it should type cast the argument
expect(Friend.find(friend.id.to_s)).to eq(friend)
end
end
context 'when ids are Strings' do
it 'it should find based on ids not slugs' do # i.e. string ids should take precedence over string slugs
expect(StringId.find(string_id.id.to_s)).to eq(string_id)
end
end
context 'when ids are Integers and the supplied arguments looks like an Integer' do
it 'it should find based on slugs not ids' do # i.e. it should not type cast the argument
expect(IntegerId.find(integer_id.id.to_s)).to eq(integer_id2)
end
end
context 'models that does not use slugs, should find using the original find' do
it 'it should find based on ids' do # i.e. it should not type cast the argument
expect(WithoutSlug.find(without_slug.id.to_s)).to eq(without_slug)
end
end
context 'when scoped' do
context 'and a document is found' do
it 'returns the document as an object' do
expect(book.subjects.find(subject.slugs.first)).to eq(subject)
expect(book2.subjects.find(subject.slugs.first)).to eq(subject2)
end
end
context 'but no document is found' do
it 'raises a Mongoid::Errors::DocumentNotFound error' do
expect do
book.subjects.find('Another Subject')
end.to raise_error(Mongoid::Errors::DocumentNotFound)
end
end
end
end
context 'using ids' do
it 'raises a Mongoid::Errors::DocumentNotFound error if no document is found' do
expect do
Book.find(friend.id)
end.to raise_error(Mongoid::Errors::DocumentNotFound)
end
context 'given a single document' do
it 'returns the document' do
expect(Friend.find(friend.id)).to eq(friend)
end
end
context 'given multiple documents' do
it 'returns the documents' do
expect(Book.find([book.id, book2.id])).to match_array([book, book2])
end
end
end
end
describe '.find_by_slug!' do
let!(:book) { Book.create(title: 'A Working Title').tap { |d| d.update_attribute(:title, 'A Thousand Plateaus') } }
let!(:book2) { Book.create(title: 'Difference and Repetition') }
let!(:friend) { Friend.create(name: 'Jim Bob') }
let!(:friend2) { Friend.create(name: friend.id.to_s) }
let!(:integer_id) { IntegerId.new(name: 'I have integer ids').tap { |d| d.id = 123; d.save! } }
let!(:integer_id2) { IntegerId.new(name: integer_id.id.to_s).tap { |d| d.id = 456; d.save! } }
let!(:string_id) { StringId.new(name: 'I have string ids').tap { |d| d.id = 'abc'; d.save! } }
let!(:string_id2) { StringId.new(name: string_id.id.to_s).tap { |d| d.id = 'def'; d.save! } }
let!(:subject) { Subject.create(name: 'A Subject', book: book) }
let!(:subject2) { Subject.create(name: 'A Subject', book: book2) }
context '(single)' do
context 'and a document is found' do
it 'returns the document as an object' do
expect(Book.find_by_slug!(book.slugs.first)).to eq(book)
end
end
context 'but no document is found' do
it 'raises a Mongoid::Errors::DocumentNotFound error' do
expect do
Book.find_by_slug!('Anti Oedipus')
end.to raise_error(Mongoid::Errors::DocumentNotFound)
end
end
end
context '(multiple)' do
context 'and all documents are found' do
it 'returns the documents as an array without duplication' do
expect(Book.find_by_slug!(book.slugs + book2.slugs)).to match_array([book, book2])
end
end
context 'but not all documents are found' do
it 'raises a Mongoid::Errors::DocumentNotFound error' do
expect do
Book.find_by_slug!(book.slugs + ['something-nonexistent'])
end.to raise_error(Mongoid::Errors::DocumentNotFound)
end
end
end
context 'when scoped' do
context 'and a document is found' do
it 'returns the document as an object' do
expect(book.subjects.find_by_slug!(subject.slugs.first)).to eq(subject)
expect(book2.subjects.find_by_slug!(subject.slugs.first)).to eq(subject2)
end
end
context 'but no document is found' do
it 'raises a Mongoid::Errors::DocumentNotFound error' do
expect do
book.subjects.find_by_slug!('Another Subject')
end.to raise_error(Mongoid::Errors::DocumentNotFound)
end
end
end
end
describe '.where' do
let!(:artist1) { Artist.create!(name: 'Leonardo') }
let!(:artist2) { Artist.create!(name: 'Malevich') }
let!(:artwork1) { Artwork.create!(title: 'Mona Lisa', artist_ids: [artist1.id], published: true) }
let!(:artwork2) { Artwork.create!(title: 'Black Square', artist_ids: [artist2.id], published: false) }
let!(:artwork3) { Artwork.create! }
it 'counts artworks' do
expect(Artwork.in(artist_ids: artist1.id).count).to eq 1
expect(Artwork.in(artist_ids: artist2.id).count).to eq 1
end
it 'counts published artworks' do
expect(Artwork.in(artist_ids: artist1.id).published.count).to eq 1
expect(Artwork.in(artist_ids: artist2.id).published.count).to eq 0
end
end
end