mongoid 4.0.1 → 4.0.2

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.
@@ -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