mongoid 4.0.1 → 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -926,8 +926,13 @@ describe Mongoid::Contextual::Memory do
926
926
  Address.new(street: "lenau", number: 5, name: "lenau")
927
927
  end
928
928
 
929
+ let(:kampuchea_krom) do
930
+ Address.new(street: "kampuchea krom", number: 5, name: "kampuchea krom")
931
+ end
932
+
929
933
  before do
930
934
  criteria.documents.unshift(lenau)
935
+ criteria.documents.unshift(kampuchea_krom)
931
936
  end
932
937
 
933
938
  context "when the sort is ascending" do
@@ -937,7 +942,7 @@ describe Mongoid::Contextual::Memory do
937
942
  end
938
943
 
939
944
  it "sorts the documents" do
940
- expect(context.entries).to eq([ friedel, lenau, pfluger, hobrecht ])
945
+ expect(context.entries).to eq([ friedel, kampuchea_krom, lenau, pfluger, hobrecht ])
941
946
  end
942
947
 
943
948
  it "returns the context" do
@@ -952,7 +957,7 @@ describe Mongoid::Contextual::Memory do
952
957
  end
953
958
 
954
959
  it "sorts the documents" do
955
- expect(context.entries).to eq([ hobrecht, pfluger, lenau, friedel ])
960
+ expect(context.entries).to eq([ hobrecht, pfluger, lenau, kampuchea_krom, friedel ])
956
961
  end
957
962
 
958
963
  it "returns the context" do
@@ -934,12 +934,9 @@ describe Mongoid::Criteria::Modifiable do
934
934
 
935
935
  context "when the relation is a references many" do
936
936
 
937
- let!(:post_one) do
938
- person.posts.create(title: "First")
939
- end
940
-
941
- let!(:post_two) do
942
- person.posts.create(title: "Second")
937
+ before do
938
+ person.posts.create!(title: "First")
939
+ person.posts.create!(title: "Second")
943
940
  end
944
941
 
945
942
  context "when updating the relation directly" do
@@ -948,12 +945,12 @@ describe Mongoid::Criteria::Modifiable do
948
945
  person.posts.update(title: "London")
949
946
  end
950
947
 
951
- let!(:from_db) do
948
+ let(:from_db) do
952
949
  Person.first
953
950
  end
954
951
 
955
952
  it "updates the first document" do
956
- expect(from_db.posts.first.title).to eq("London")
953
+ expect(from_db.posts.map(&:title)).to eq(["London", "Second"])
957
954
  end
958
955
 
959
956
  it "does not update the last document" do
@@ -529,11 +529,15 @@ describe Mongoid::Document do
529
529
  context "when the document is not new" do
530
530
 
531
531
  let(:person) do
532
- Person.instantiate("_id" => BSON::ObjectId.new)
532
+ Person.create!
533
533
  end
534
534
 
535
535
  it "returns the id in an array" do
536
- expect(person.to_key).to eq([ person.id ])
536
+ expect(person.to_key).to eq([ person.id.to_s ])
537
+ end
538
+
539
+ it "can query using the key" do
540
+ expect(person.id).to eq Person.find(person.to_key).first.id
537
541
  end
538
542
  end
539
543
 
@@ -546,7 +550,7 @@ describe Mongoid::Document do
546
550
  end
547
551
 
548
552
  it "returns the id in an array" do
549
- expect(person.to_key).to eq([ person.id ])
553
+ expect(person.to_key).to eq([ person.id.to_s ])
550
554
  end
551
555
  end
552
556
  end
@@ -13,3 +13,17 @@ describe BSON::ObjectId do
13
13
  end
14
14
  end
15
15
  end
16
+
17
+ describe BSON::Document do
18
+
19
+ describe "#symbolize_keys" do
20
+
21
+ let(:doc) do
22
+ described_class.new("foo" => "bar")
23
+ end
24
+
25
+ it "returns key as symbol" do
26
+ expect(doc.symbolize_keys.keys).to eq [:foo]
27
+ end
28
+ end
29
+ end
@@ -53,6 +53,55 @@ describe Mongoid::Findable do
53
53
 
54
54
  describe ".find_by" do
55
55
 
56
+ context "when collection is a embeds_many" do
57
+
58
+ let(:person) do
59
+ Person.create(title: "sir")
60
+ end
61
+
62
+ let!(:message) do
63
+ person.messages.create!(body: 'foo')
64
+ end
65
+
66
+ context "when the document is found" do
67
+
68
+ it "returns the document" do
69
+ expect(person.messages.find_by(body: 'foo')).to eq(message)
70
+ end
71
+ end
72
+
73
+ context "when the document is not found" do
74
+
75
+ context "when raising a not found error" do
76
+
77
+ let!(:raise_option) { Mongoid.raise_not_found_error }
78
+
79
+ before { Mongoid.raise_not_found_error = true }
80
+
81
+ after { Mongoid.raise_not_found_error = raise_option }
82
+
83
+ it "raises an error" do
84
+ expect {
85
+ person.messages.find_by(body: 'bar')
86
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
87
+ end
88
+ end
89
+
90
+ context "when raising no error" do
91
+
92
+ let!(:raise_option) { Mongoid.raise_not_found_error }
93
+
94
+ before { Mongoid.raise_not_found_error = false }
95
+
96
+ after { Mongoid.raise_not_found_error = raise_option }
97
+
98
+ it "returns nil" do
99
+ expect(person.messages.find_by(body: 'bar')).to be_nil
100
+ end
101
+ end
102
+ end
103
+ end
104
+
56
105
  context "when the document is found" do
57
106
 
58
107
  let!(:person) do
@@ -84,9 +133,11 @@ describe Mongoid::Findable do
84
133
 
85
134
  context "when raising a not found error" do
86
135
 
87
- before do
88
- Mongoid.raise_not_found_error = true
89
- end
136
+ let!(:raise_option) { Mongoid.raise_not_found_error }
137
+
138
+ before { Mongoid.raise_not_found_error = true }
139
+
140
+ after { Mongoid.raise_not_found_error = raise_option }
90
141
 
91
142
  it "raises an error" do
92
143
  expect {
@@ -97,13 +148,11 @@ describe Mongoid::Findable do
97
148
 
98
149
  context "when raising no error" do
99
150
 
100
- before do
101
- Mongoid.raise_not_found_error = false
102
- end
151
+ let!(:raise_option) { Mongoid.raise_not_found_error }
103
152
 
104
- after do
105
- Mongoid.raise_not_found_error = true
106
- end
153
+ before { Mongoid.raise_not_found_error = false }
154
+
155
+ after { Mongoid.raise_not_found_error = raise_option }
107
156
 
108
157
  context "when no block is provided" do
109
158
 
@@ -128,6 +177,45 @@ describe Mongoid::Findable do
128
177
  end
129
178
  end
130
179
 
180
+ describe "find_by!" do
181
+
182
+ context "when the document is found" do
183
+
184
+ let!(:person) do
185
+ Person.create(title: "sir")
186
+ end
187
+
188
+ context "when no block is provided" do
189
+
190
+ it "returns the document" do
191
+ expect(Person.find_by!(title: "sir")).to eq(person)
192
+ end
193
+ end
194
+
195
+ context "when a block is provided" do
196
+
197
+ let(:result) do
198
+ Person.find_by!(title: "sir") do |peep|
199
+ peep.age = 50
200
+ end
201
+ end
202
+
203
+ it "yields the returned document" do
204
+ expect(result.age).to eq(50)
205
+ end
206
+ end
207
+ end
208
+
209
+ context "when the document is not found" do
210
+
211
+ it "raises an error" do
212
+ expect {
213
+ Person.find_by!(ssn: "333-22-1111")
214
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
215
+ end
216
+ end
217
+ end
218
+
131
219
  [ :first, :one ].each do |method|
132
220
 
133
221
  describe "##{method}" do
@@ -394,6 +394,47 @@ describe Mongoid::Persistable::Creatable do
394
394
  end
395
395
  end
396
396
  end
397
+
398
+ context "#find_or_create_by!" do
399
+
400
+ before do
401
+ container.vehicles.find_or_create_by!({ driver_id: driver.id }, Car)
402
+ end
403
+
404
+ it "creates the given type document" do
405
+ expect(container.vehicles.map(&:class)).to eq([ Car ])
406
+ end
407
+
408
+ it "creates with the given attributes" do
409
+ expect(container.vehicles.map(&:driver)).to eq([ driver ])
410
+ end
411
+
412
+ it "creates the correct number of documents" do
413
+ expect(container.vehicles.size).to eq(1)
414
+ end
415
+
416
+ context "when executing with a found document" do
417
+
418
+ before do
419
+ container.vehicles.find_or_create_by!({ driver_id: driver.id }, Car)
420
+ end
421
+
422
+ it "does not create an additional document" do
423
+ expect(container.vehicles.size).to eq(1)
424
+ end
425
+ end
426
+
427
+ context "when executing with an additional new document" do
428
+
429
+ before do
430
+ container.vehicles.find_or_create_by!({ driver_id: driver.id }, Truck)
431
+ end
432
+
433
+ it "creates the new additional document" do
434
+ expect(container.vehicles.size).to eq(2)
435
+ end
436
+ end
437
+ end
397
438
  end
398
439
  end
399
440
 
@@ -8,6 +8,14 @@ describe Mongoid::Persistable::Savable do
8
8
  Person.create
9
9
  end
10
10
 
11
+ let(:contextable_item) do
12
+ ContextableItem.new
13
+ end
14
+
15
+ let(:persisted_contextable_item) do
16
+ ContextableItem.create(title: 'sir')
17
+ end
18
+
11
19
  context "when skipping validation" do
12
20
 
13
21
  context "when no relations are involved" do
@@ -285,6 +293,35 @@ describe Mongoid::Persistable::Savable do
285
293
  }.to raise_error(Mongoid::Errors::ReadonlyDocument)
286
294
  end
287
295
  end
296
+
297
+ context "when validation context isn't assigned" do
298
+ it "returns true" do
299
+ expect(contextable_item.save).to be true
300
+ end
301
+ end
302
+
303
+ context "when validation context exists" do
304
+ context "on new document" do
305
+ it "returns true" do
306
+ contextable_item.title = "sir"
307
+ expect(contextable_item.save(context: :in_context)).to be true
308
+ end
309
+ it "returns false" do
310
+ expect(contextable_item.save(context: :in_context)).to be false
311
+ end
312
+ end
313
+
314
+ context "on persisted document" do
315
+ it "returns true" do
316
+ persisted_contextable_item.title = "lady"
317
+ expect(persisted_contextable_item.save(context: :in_context)).to be true
318
+ end
319
+ it "returns false" do
320
+ persisted_contextable_item.title = nil
321
+ expect(persisted_contextable_item.save(context: :in_context)).to be false
322
+ end
323
+ end
324
+ end
288
325
  end
289
326
 
290
327
  describe "save!" do
@@ -136,4 +136,27 @@ describe Mongoid::Persistable::Settable do
136
136
  end
137
137
  end
138
138
  end
139
+
140
+ context "when dynamic attributes are not enabled" do
141
+ let(:account) do
142
+ Account.create
143
+ end
144
+
145
+ it "raises exception for an unknown attribute " do
146
+ expect {
147
+ account.set(somethingnew: "somethingnew")
148
+ }.to raise_error(Mongoid::Errors::UnknownAttribute)
149
+ end
150
+ end
151
+
152
+ context "when dynamic attributes enabled" do
153
+ let(:person) do
154
+ Person.create
155
+ end
156
+
157
+ it "updates non existing attribute" do
158
+ person.set(somethingnew: "somethingnew")
159
+ expect(person.reload.somethingnew).to eq "somethingnew"
160
+ end
161
+ end
139
162
  end
@@ -2120,6 +2120,80 @@ describe Mongoid::Relations::Embedded::Many do
2120
2120
  end
2121
2121
  end
2122
2122
 
2123
+ describe "#find_or_create_by!" do
2124
+
2125
+ let(:person) do
2126
+ Person.create
2127
+ end
2128
+
2129
+ let!(:address) do
2130
+ person.addresses.build(street: "Bourke", city: "Melbourne")
2131
+ end
2132
+
2133
+ context "when the document exists" do
2134
+
2135
+ let(:found) do
2136
+ person.addresses.find_or_create_by!(street: "Bourke")
2137
+ end
2138
+
2139
+ it "returns the document" do
2140
+ expect(found).to eq(address)
2141
+ end
2142
+ end
2143
+
2144
+ context "when the document does not exist" do
2145
+
2146
+ let(:found) do
2147
+ person.addresses.find_or_create_by!(street: "King") do |address|
2148
+ address.state = "CA"
2149
+ end
2150
+ end
2151
+
2152
+ it "sets the new document attributes" do
2153
+ expect(found.street).to eq("King")
2154
+ end
2155
+
2156
+ it "returns a newly persisted document" do
2157
+ expect(found).to be_persisted
2158
+ end
2159
+
2160
+ it "calls the passed block" do
2161
+ expect(found.state).to eq("CA")
2162
+ end
2163
+
2164
+ context "when validation fails" do
2165
+
2166
+ it "raises an error" do
2167
+ expect {
2168
+ person.addresses.find_or_create_by!(street: "1")
2169
+ }.to raise_error(Mongoid::Errors::Validations)
2170
+ end
2171
+ end
2172
+ end
2173
+
2174
+ context "when the child belongs to another document" do
2175
+
2176
+ let(:product) do
2177
+ Product.create
2178
+ end
2179
+
2180
+ let(:purchase) do
2181
+ Purchase.create
2182
+ end
2183
+
2184
+ let(:line_item) do
2185
+ purchase.line_items.find_or_create_by(
2186
+ product_id: product.id,
2187
+ product_type: product.class.name
2188
+ )
2189
+ end
2190
+
2191
+ it "properly creates the document" do
2192
+ expect(line_item.product).to eq(product)
2193
+ end
2194
+ end
2195
+ end
2196
+
2123
2197
  describe "#find_or_initialize_by" do
2124
2198
 
2125
2199
  let(:person) do