mongoid 4.0.2 → 5.0.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.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -1
  3. data/README.md +11 -19
  4. data/lib/config/locales/en.yml +33 -30
  5. data/lib/mongoid/atomic.rb +2 -4
  6. data/lib/mongoid/attributes/processing.rb +4 -1
  7. data/lib/mongoid/attributes/readonly.rb +2 -2
  8. data/lib/mongoid/attributes.rb +7 -7
  9. data/lib/mongoid/changeable.rb +4 -6
  10. data/lib/mongoid/clients/factory.rb +78 -0
  11. data/lib/mongoid/{sessions → clients}/options.rb +30 -19
  12. data/lib/mongoid/{sessions → clients}/storage_options.rb +27 -13
  13. data/lib/mongoid/{sessions → clients}/thread_options.rb +6 -3
  14. data/lib/mongoid/{sessions → clients}/validators/storage.rb +5 -2
  15. data/lib/mongoid/clients/validators.rb +2 -0
  16. data/lib/mongoid/clients.rb +141 -0
  17. data/lib/mongoid/composable.rb +3 -3
  18. data/lib/mongoid/config/environment.rb +1 -1
  19. data/lib/mongoid/config/options.rb +1 -1
  20. data/lib/mongoid/config/validators/{session.rb → client.rb} +31 -28
  21. data/lib/mongoid/config/validators/option.rb +1 -1
  22. data/lib/mongoid/config/validators.rb +1 -1
  23. data/lib/mongoid/config.rb +39 -41
  24. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  25. data/lib/mongoid/contextual/atomic.rb +11 -11
  26. data/lib/mongoid/contextual/command.rb +9 -6
  27. data/lib/mongoid/contextual/geo_near.rb +17 -1
  28. data/lib/mongoid/contextual/map_reduce.rb +12 -11
  29. data/lib/mongoid/contextual/memory.rb +2 -5
  30. data/lib/mongoid/contextual/mongo.rb +92 -82
  31. data/lib/mongoid/contextual/none.rb +13 -0
  32. data/lib/mongoid/copyable.rb +6 -1
  33. data/lib/mongoid/criteria.rb +37 -4
  34. data/lib/mongoid/document.rb +3 -4
  35. data/lib/mongoid/errors/{mixed_session_configuration.rb → mixed_client_configuration.rb} +5 -5
  36. data/lib/mongoid/errors/mongoid_error.rb +15 -9
  37. data/lib/mongoid/errors/no_client_config.rb +22 -0
  38. data/lib/mongoid/errors/{no_session_database.rb → no_client_database.rb} +4 -4
  39. data/lib/mongoid/errors/{no_session_hosts.rb → no_client_hosts.rb} +4 -4
  40. data/lib/mongoid/errors/{no_sessions_config.rb → no_clients_config.rb} +4 -4
  41. data/lib/mongoid/errors/no_default_client.rb +23 -0
  42. data/lib/mongoid/errors.rb +6 -6
  43. data/lib/mongoid/extensions/hash.rb +5 -1
  44. data/lib/mongoid/extensions/object.rb +3 -2
  45. data/lib/mongoid/extensions/set.rb +5 -5
  46. data/lib/mongoid/factory.rb +4 -2
  47. data/lib/mongoid/fields.rb +7 -2
  48. data/lib/mongoid/findable.rb +4 -1
  49. data/lib/mongoid/indexable.rb +15 -9
  50. data/lib/mongoid/persistable/creatable.rb +2 -2
  51. data/lib/mongoid/persistable/deletable.rb +3 -3
  52. data/lib/mongoid/persistable/incrementable.rb +1 -1
  53. data/lib/mongoid/persistable/logical.rb +1 -1
  54. data/lib/mongoid/persistable/poppable.rb +1 -1
  55. data/lib/mongoid/persistable/pullable.rb +2 -2
  56. data/lib/mongoid/persistable/pushable.rb +2 -2
  57. data/lib/mongoid/persistable/renamable.rb +1 -1
  58. data/lib/mongoid/persistable/settable.rb +1 -1
  59. data/lib/mongoid/persistable/unsettable.rb +1 -1
  60. data/lib/mongoid/persistable/updatable.rb +2 -2
  61. data/lib/mongoid/persistable/upsertable.rb +1 -1
  62. data/lib/mongoid/persistable.rb +1 -2
  63. data/lib/mongoid/query_cache.rb +98 -104
  64. data/lib/mongoid/railtie.rb +4 -25
  65. data/lib/mongoid/railties/database.rake +1 -1
  66. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +3 -2
  67. data/lib/mongoid/relations/builders.rb +3 -1
  68. data/lib/mongoid/relations/counter_cache.rb +1 -1
  69. data/lib/mongoid/relations/embedded/batchable.rb +3 -10
  70. data/lib/mongoid/relations/embedded/many.rb +4 -2
  71. data/lib/mongoid/relations/embedded/one.rb +1 -0
  72. data/lib/mongoid/relations/many.rb +1 -0
  73. data/lib/mongoid/relations/metadata.rb +14 -0
  74. data/lib/mongoid/relations/proxy.rb +6 -6
  75. data/lib/mongoid/relations/referenced/many.rb +2 -1
  76. data/lib/mongoid/relations/targets/enumerable.rb +11 -11
  77. data/lib/mongoid/relations/touchable.rb +1 -1
  78. data/lib/mongoid/reloadable.rb +2 -2
  79. data/lib/mongoid/scopable.rb +6 -17
  80. data/lib/mongoid/selectable.rb +1 -36
  81. data/lib/mongoid/serializable.rb +2 -2
  82. data/lib/mongoid/stateful.rb +0 -1
  83. data/lib/mongoid/tasks/database.rake +2 -2
  84. data/lib/mongoid/tasks/database.rb +24 -17
  85. data/lib/mongoid/threaded/lifecycle.rb +21 -16
  86. data/lib/mongoid/threaded.rb +54 -33
  87. data/lib/mongoid/traversable.rb +17 -1
  88. data/lib/mongoid/validatable/queryable.rb +1 -1
  89. data/lib/mongoid/validatable/uniqueness.rb +3 -20
  90. data/lib/mongoid/validatable.rb +1 -1
  91. data/lib/mongoid/version.rb +1 -1
  92. data/lib/mongoid.rb +28 -21
  93. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +91 -57
  94. data/lib/rails/mongoid.rb +2 -2
  95. data/spec/app/models/audio.rb +1 -1
  96. data/spec/app/models/band.rb +1 -0
  97. data/spec/app/models/code.rb +6 -0
  98. data/spec/app/models/company.rb +5 -0
  99. data/spec/app/models/label.rb +7 -0
  100. data/spec/app/models/pub.rb +6 -0
  101. data/spec/app/models/staff.rb +7 -0
  102. data/spec/app/models/store_as_dup_test1.rb +5 -0
  103. data/spec/app/models/store_as_dup_test2.rb +5 -0
  104. data/spec/config/mongoid.yml +7 -25
  105. data/spec/mongoid/atomic/paths_spec.rb +3 -11
  106. data/spec/mongoid/attributes/nested_spec.rb +16 -16
  107. data/spec/mongoid/attributes/readonly_spec.rb +80 -18
  108. data/spec/mongoid/attributes_spec.rb +3 -3
  109. data/spec/mongoid/changeable_spec.rb +156 -0
  110. data/spec/mongoid/clients/factory_spec.rb +284 -0
  111. data/spec/mongoid/{sessions → clients}/options_spec.rb +4 -6
  112. data/spec/mongoid/clients_spec.rb +754 -0
  113. data/spec/mongoid/config/environment_spec.rb +14 -11
  114. data/spec/mongoid/config_spec.rb +33 -48
  115. data/spec/mongoid/contextual/atomic_spec.rb +1 -17
  116. data/spec/mongoid/contextual/geo_near_spec.rb +35 -0
  117. data/spec/mongoid/contextual/mongo_spec.rb +26 -83
  118. data/spec/mongoid/contextual/none_spec.rb +15 -0
  119. data/spec/mongoid/copyable_spec.rb +35 -1
  120. data/spec/mongoid/criteria/findable_spec.rb +197 -0
  121. data/spec/mongoid/criteria/modifiable_spec.rb +7 -29
  122. data/spec/mongoid/criteria_spec.rb +74 -91
  123. data/spec/mongoid/document_spec.rb +1 -1
  124. data/spec/mongoid/errors/{mixed_session_configuration_spec.rb → mixed_client_configuration_spec.rb} +1 -1
  125. data/spec/mongoid/errors/mongoid_error_spec.rb +19 -3
  126. data/spec/mongoid/errors/{no_session_config_spec.rb → no_client_config_spec.rb} +4 -4
  127. data/spec/mongoid/errors/{no_session_database_spec.rb → no_client_database_spec.rb} +4 -4
  128. data/spec/mongoid/errors/{no_session_hosts_spec.rb → no_client_hosts_spec.rb} +3 -3
  129. data/spec/mongoid/errors/{no_sessions_config_spec.rb → no_clients_config_spec.rb} +2 -2
  130. data/spec/mongoid/fields/localized_spec.rb +1 -0
  131. data/spec/mongoid/fields_spec.rb +1 -0
  132. data/spec/mongoid/findable_spec.rb +2 -23
  133. data/spec/mongoid/indexable_spec.rb +12 -8
  134. data/spec/mongoid/interceptable_spec.rb +15 -0
  135. data/spec/mongoid/persistable/settable_spec.rb +16 -0
  136. data/spec/mongoid/persistable/updatable_spec.rb +3 -2
  137. data/spec/mongoid/persistable_spec.rb +4 -4
  138. data/spec/mongoid/query_cache_spec.rb +13 -8
  139. data/spec/mongoid/relations/auto_save_spec.rb +1 -1
  140. data/spec/mongoid/relations/counter_cache_spec.rb +34 -0
  141. data/spec/mongoid/relations/eager/belongs_to_spec.rb +9 -0
  142. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +3 -3
  143. data/spec/mongoid/relations/embedded/many_spec.rb +123 -1
  144. data/spec/mongoid/relations/embedded/one_spec.rb +3 -3
  145. data/spec/mongoid/relations/proxy_spec.rb +28 -0
  146. data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
  147. data/spec/mongoid/relations/referenced/many_spec.rb +47 -23
  148. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +1 -1
  149. data/spec/mongoid/relations/referenced/one_spec.rb +1 -1
  150. data/spec/mongoid/relations/targets/enumerable_spec.rb +9 -2
  151. data/spec/mongoid/reloadable_spec.rb +6 -6
  152. data/spec/mongoid/scopable_spec.rb +41 -28
  153. data/spec/mongoid/selectable_spec.rb +6 -16
  154. data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
  155. data/spec/mongoid/tasks/database_spec.rb +2 -2
  156. data/spec/mongoid/threaded_spec.rb +0 -7
  157. data/spec/mongoid/traversable_spec.rb +2 -2
  158. data/spec/mongoid/validatable/uniqueness_spec.rb +30 -1
  159. data/spec/mongoid_spec.rb +13 -15
  160. data/spec/rails/mongoid_spec.rb +13 -4
  161. data/spec/spec_helper.rb +44 -27
  162. data/spec/support/authorization.rb +12 -0
  163. data/spec/support/expectations.rb +14 -0
  164. metadata +50 -57
  165. data/lib/mongoid/contextual/find_and_modify.rb +0 -69
  166. data/lib/mongoid/contextual/text_search.rb +0 -178
  167. data/lib/mongoid/criteria/#findable.rb# +0 -141
  168. data/lib/mongoid/errors/no_default_session.rb +0 -23
  169. data/lib/mongoid/errors/no_session_config.rb +0 -22
  170. data/lib/mongoid/log_subscriber.rb +0 -55
  171. data/lib/mongoid/positional.rb +0 -71
  172. data/lib/mongoid/sessions/factory.rb +0 -131
  173. data/lib/mongoid/sessions/mongo_uri.rb +0 -93
  174. data/lib/mongoid/sessions/validators.rb +0 -2
  175. data/lib/mongoid/sessions.rb +0 -125
  176. data/lib/mongoid/support/query_counter.rb +0 -23
  177. data/spec/helpers.rb +0 -18
  178. data/spec/mongoid/#atomic_spec.rb# +0 -365
  179. data/spec/mongoid/contextual/find_and_modify_spec.rb +0 -220
  180. data/spec/mongoid/contextual/text_search_spec.rb +0 -209
  181. data/spec/mongoid/log_subscriber_spec.rb +0 -75
  182. data/spec/mongoid/positional_spec.rb +0 -222
  183. data/spec/mongoid/sessions/factory_spec.rb +0 -333
  184. data/spec/mongoid/sessions/mongo_uri_spec.rb +0 -103
  185. data/spec/mongoid/sessions_spec.rb +0 -1252
@@ -0,0 +1,754 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Clients do
4
+
5
+ describe "#collection" do
6
+
7
+ shared_examples_for "an overridden collection at the class level" do
8
+
9
+ let(:band) do
10
+ klass.new
11
+ end
12
+
13
+ it "returns the collection for the model" do
14
+ expect(band.collection).to be_a(Mongo::Collection)
15
+ end
16
+
17
+ it "sets the correct collection name" do
18
+ expect(band.collection.name).to eq("artists")
19
+ end
20
+
21
+ context "when accessing from the class level" do
22
+
23
+ it "returns the collection for the model" do
24
+ expect(klass.collection).to be_a(Mongo::Collection)
25
+ end
26
+
27
+ it "sets the correct collection name" do
28
+ expect(klass.collection.name).to eq("artists")
29
+ end
30
+ end
31
+ end
32
+
33
+ context "when overriding the persistence options" do
34
+
35
+ let(:klass) do
36
+ Band.with(collection: "artists")
37
+ end
38
+
39
+ it_behaves_like "an overridden collection at the class level"
40
+ end
41
+
42
+ context "when overriding store_in and persistence options" do
43
+
44
+ let(:klass) do
45
+ Band.with(collection: "artists")
46
+ end
47
+
48
+ before do
49
+ Band.store_in collection: "foo"
50
+ end
51
+
52
+ after do
53
+ Band.reset_storage_options!
54
+ end
55
+
56
+ it_behaves_like "an overridden collection at the class level"
57
+ end
58
+
59
+ context "when overriding the default with store_in" do
60
+
61
+ after do
62
+ Band.reset_storage_options!
63
+ end
64
+
65
+ context "when called multiple times with different options" do
66
+
67
+ before do
68
+ Band.store_in collection: "artists"
69
+ Band.store_in client: "another"
70
+ end
71
+
72
+ it "should merge the options together" do
73
+ expect(Band.storage_options[:collection]).to eq("artists")
74
+ expect(Band.storage_options[:client]).to eq("another")
75
+ end
76
+ end
77
+
78
+ context "when overriding with a proc" do
79
+
80
+ let(:klass) { Band }
81
+
82
+ before do
83
+ Band.store_in(collection: ->{ "artists" })
84
+ end
85
+
86
+ it_behaves_like "an overridden collection at the class level"
87
+ end
88
+
89
+ context "when overriding with a string" do
90
+
91
+ let(:klass) { Band }
92
+
93
+ before do
94
+ Band.store_in(collection: "artists")
95
+ end
96
+
97
+ after do
98
+ Band.reset_storage_options!
99
+ end
100
+
101
+ it_behaves_like "an overridden collection at the class level"
102
+ end
103
+
104
+ context "when overriding with a symbol" do
105
+
106
+ let(:klass) { Band }
107
+
108
+ before do
109
+ klass.store_in(collection: :artists)
110
+ end
111
+
112
+ after do
113
+ klass.reset_storage_options!
114
+ end
115
+
116
+ it_behaves_like "an overridden collection at the class level"
117
+ end
118
+ end
119
+
120
+ context "when not overriding the default" do
121
+
122
+ let(:band) do
123
+ Band.new
124
+ end
125
+
126
+ it "returns the collection for the model" do
127
+ expect(band.collection).to be_a(Mongo::Collection)
128
+ end
129
+
130
+ it "sets the correct collection name" do
131
+ expect(band.collection.name.to_s).to eq("bands")
132
+ end
133
+
134
+ context "when accessing from the class level" do
135
+
136
+ it "returns the collection for the model" do
137
+ expect(Band.collection).to be_a(Mongo::Collection)
138
+ end
139
+
140
+ it "sets the correct collection name" do
141
+ expect(Band.collection.name.to_s).to eq("bands")
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "#collection_name" do
148
+
149
+ shared_examples_for "an overridden collection name at the class level" do
150
+
151
+ let(:band) do
152
+ klass.new
153
+ end
154
+
155
+ context "when accessing from the instance" do
156
+
157
+ it "returns the overridden value" do
158
+ expect(band.collection_name).to eq(:artists)
159
+ end
160
+ end
161
+
162
+ context "when accessing from the class level" do
163
+
164
+ it "returns the overridden value" do
165
+ expect(klass.collection_name).to eq(:artists)
166
+ end
167
+ end
168
+ end
169
+
170
+ context "when overriding the persistence options" do
171
+
172
+ let(:klass) do
173
+ Band.with(collection: "artists")
174
+ end
175
+
176
+ it_behaves_like "an overridden collection name at the class level"
177
+ end
178
+
179
+ context "when overriding store_in and persistence options" do
180
+
181
+ let(:klass) do
182
+ Band.with(collection: "artists")
183
+ end
184
+
185
+ before do
186
+ Band.store_in collection: "foo"
187
+ end
188
+
189
+ after do
190
+ Band.reset_storage_options!
191
+ end
192
+
193
+ it_behaves_like "an overridden collection name at the class level"
194
+ end
195
+
196
+ context "when overriding the default with store_in" do
197
+
198
+ let(:klass) { Band }
199
+
200
+ after do
201
+ Band.reset_storage_options!
202
+ end
203
+
204
+ context "when overriding with a proc" do
205
+
206
+ before do
207
+ Band.store_in(collection: ->{ "artists" })
208
+ end
209
+
210
+ it_behaves_like "an overridden collection name at the class level"
211
+ end
212
+
213
+ context "when overriding with a string" do
214
+
215
+ before do
216
+ Band.store_in(collection: "artists")
217
+ end
218
+
219
+ it_behaves_like "an overridden collection name at the class level"
220
+ end
221
+
222
+ context "when overriding with a symbol" do
223
+
224
+ before do
225
+ Band.store_in(collection: :artists)
226
+ end
227
+
228
+ it_behaves_like "an overridden collection name at the class level"
229
+ end
230
+ end
231
+
232
+ context "when not overriding the default" do
233
+
234
+ let(:band) do
235
+ Band.new
236
+ end
237
+
238
+ it "returns the pluralized model name" do
239
+ expect(band.collection_name).to eq(:bands)
240
+ end
241
+
242
+ context "when accessing from the class level" do
243
+
244
+ it "returns the pluralized model name" do
245
+ expect(Band.collection_name).to eq(:bands)
246
+ end
247
+ end
248
+ end
249
+
250
+ context "when the model is a subclass" do
251
+
252
+ let(:firefox) do
253
+ Firefox.new
254
+ end
255
+
256
+ it "returns the root class pluralized model name" do
257
+ expect(firefox.collection_name).to eq(:canvases)
258
+ end
259
+
260
+ context "when accessing from the class level" do
261
+
262
+ it "returns the root class pluralized model name" do
263
+ expect(Firefox.collection_name).to eq(:canvases)
264
+ end
265
+ end
266
+ end
267
+ end
268
+
269
+ describe "#database_name", if: non_legacy_server? do
270
+
271
+ shared_examples_for "an overridden database name" do
272
+
273
+ let(:band) do
274
+ klass.new
275
+ end
276
+
277
+ context "when accessing from the instance" do
278
+
279
+ it "returns the overridden value" do
280
+ # @todo
281
+ # expect(band.mongo_client.options[:database].to_s).to eq(database_id_alt)
282
+ end
283
+ end
284
+
285
+ context "when accessing from the class level" do
286
+
287
+ it "returns the overridden value" do
288
+ expect(klass.database_name.to_s).to eq(database_id_alt)
289
+ end
290
+
291
+ it "client returns the overridden value" do
292
+ expect(klass.mongo_client.options[:database].to_s).to eq(database_id_alt)
293
+ end
294
+ end
295
+ end
296
+
297
+ context "when overriding the persistence options" do
298
+
299
+ let(:klass) do
300
+ Band.with(database: database_id_alt)
301
+ end
302
+
303
+ it_behaves_like "an overridden database name"
304
+ end
305
+
306
+ context "when overriding with store_in" do
307
+
308
+ let(:klass) { Band }
309
+
310
+ before do
311
+ Band.store_in database: database_id_alt
312
+ end
313
+
314
+ after do
315
+ Band.reset_storage_options!
316
+ end
317
+
318
+ it_behaves_like "an overridden database name"
319
+ end
320
+
321
+ context "when overriding store_in and persistence options" do
322
+
323
+ let(:klass) do
324
+ Band.with(database: database_id_alt)
325
+ end
326
+
327
+ before do
328
+ Band.store_in database: "foo"
329
+ end
330
+
331
+ after do
332
+ Band.reset_storage_options!
333
+ end
334
+
335
+ it_behaves_like "an overridden database name"
336
+ end
337
+
338
+ context "when overriding using the client" do
339
+
340
+ let(:client_name) { :alternative }
341
+
342
+ before do
343
+ Mongoid.clients[client_name] = { database: database_id_alt, hosts: [ "#{HOST}:#{PORT}" ] }
344
+ end
345
+
346
+ after do
347
+ Mongoid.clients.delete(client_name)
348
+ end
349
+
350
+ context "when overriding the persistence options" do
351
+
352
+ let(:klass) do
353
+ Band.with(client: client_name)
354
+ end
355
+
356
+ it_behaves_like "an overridden database name"
357
+ end
358
+
359
+ context "when overriding with store_in" do
360
+
361
+ let(:klass) { Band }
362
+
363
+ before do
364
+ Band.store_in(client: client_name)
365
+ end
366
+
367
+ after do
368
+ Band.reset_storage_options!
369
+ end
370
+
371
+ it_behaves_like "an overridden database name"
372
+ end
373
+ end
374
+ end
375
+
376
+ describe "#mongo_client", if: non_legacy_server? do
377
+
378
+ let(:file) do
379
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
380
+ end
381
+
382
+ before do
383
+ described_class.clear
384
+ Mongoid.load!(file, :test)
385
+ Mongoid.clients[:default][:database] = database_id
386
+ end
387
+
388
+ context "when getting the default" do
389
+
390
+ let(:file) do
391
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
392
+ end
393
+
394
+ before do
395
+ described_class.clear
396
+ Mongoid.load!(file, :test)
397
+ Mongoid.clients[:default][:database] = database_id
398
+ end
399
+
400
+ let!(:band) do
401
+ Band.new
402
+ end
403
+
404
+ let!(:mongo_client) do
405
+ band.mongo_client
406
+ end
407
+
408
+ it "returns the default client" do
409
+ expect(mongo_client.options[:database].to_s).to eq(database_id)
410
+ end
411
+ end
412
+
413
+ context "when no client exists with the key" do
414
+
415
+ before(:all) do
416
+ Band.store_in(client: :nonexistant)
417
+ end
418
+
419
+ let(:band) do
420
+ Band.new
421
+ end
422
+
423
+ it "raises an error" do
424
+ expect {
425
+ band.mongo_client
426
+ }.to raise_error(Mongoid::Errors::NoClientConfig)
427
+ end
428
+ end
429
+ end
430
+
431
+ describe ".mongo_client", if: non_legacy_server? do
432
+
433
+ let(:file) do
434
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
435
+ end
436
+
437
+ before do
438
+ described_class.clear
439
+ Mongoid.load!(file, :test)
440
+ Mongoid.clients[:default][:database] = database_id
441
+ end
442
+
443
+ after do
444
+ Band.reset_storage_options!
445
+ end
446
+
447
+ context "when getting the default" do
448
+
449
+ let(:file) do
450
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
451
+ end
452
+
453
+ before do
454
+ Band.reset_storage_options!
455
+ described_class.clear
456
+ Mongoid.load!(file, :test)
457
+ Mongoid.clients[:default][:database] = database_id
458
+ end
459
+
460
+ let!(:mongo_client) do
461
+ Band.mongo_client
462
+ end
463
+
464
+ it "returns the default client" do
465
+ expect(mongo_client.options[:database].to_s).to eq(database_id)
466
+ end
467
+ end
468
+
469
+ context "when no client exists with the key" do
470
+
471
+ before(:all) do
472
+ Band.store_in(client: :nonexistant)
473
+ end
474
+
475
+ it "raises an error" do
476
+ expect {
477
+ Band.mongo_client
478
+ }.to raise_error(Mongoid::Errors::NoClientConfig)
479
+ end
480
+ end
481
+ end
482
+
483
+ describe ".store_in", if: non_legacy_server? do
484
+
485
+ context "when provided a non hash" do
486
+
487
+ it "raises an error" do
488
+ expect {
489
+ Band.store_in :artists
490
+ }.to raise_error(Mongoid::Errors::InvalidStorageOptions)
491
+ end
492
+ end
493
+
494
+ context "when provided a class that extend another document" do
495
+
496
+ let(:klass) do
497
+ Class.new(Band)
498
+ end
499
+
500
+ it "raises an error" do
501
+ expect {
502
+ klass.store_in(database: :artists)
503
+ }.to raise_error(Mongoid::Errors::InvalidStorageParent)
504
+ end
505
+ end
506
+
507
+ context "when provided a hash" do
508
+
509
+ context "when the hash is not valid" do
510
+
511
+ it "raises an error" do
512
+ expect {
513
+ Band.store_in coll: "artists"
514
+ }.to raise_error(Mongoid::Errors::InvalidStorageOptions)
515
+ end
516
+ end
517
+ end
518
+ end
519
+
520
+ describe ".with", if: non_legacy_server? do
521
+
522
+ context "when changing write concern options" do
523
+
524
+ let(:client_one) do
525
+ Band.with(write: { w: 2 }).mongo_client
526
+ end
527
+
528
+ let(:client_two) do
529
+ Band.mongo_client
530
+ end
531
+
532
+ it "does not carry over the options" do
533
+ expect(client_one.write_concern).to_not eq(client_two.write_concern)
534
+ end
535
+ end
536
+
537
+ context "when sending operations to a different database" do
538
+
539
+ after do
540
+ Band.with(database: database_id_alt).delete_all
541
+ end
542
+
543
+ describe ".create" do
544
+
545
+ let!(:band) do
546
+ Band.with(database: database_id_alt).create
547
+ end
548
+
549
+ it "does not persist to the default database" do
550
+ expect {
551
+ Band.find(band.id)
552
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
553
+ end
554
+
555
+ let(:from_db) do
556
+ Band.with(database: database_id_alt).find(band.id)
557
+ end
558
+
559
+ it "persists to the specified database" do
560
+ expect(from_db).to eq(band)
561
+ end
562
+
563
+ it "persists the correct number of documents" do
564
+ expect(Band.with(database: database_id_alt).count).to eq(1)
565
+ end
566
+ end
567
+ end
568
+
569
+ context "when sending operations to a different collection" do
570
+
571
+ describe ".create" do
572
+
573
+ let!(:band) do
574
+ Band.with(collection: "artists").create
575
+ end
576
+
577
+ it "does not persist to the default database" do
578
+ expect {
579
+ Band.find(band.id)
580
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
581
+ end
582
+
583
+ let(:from_db) do
584
+ Band.with(collection: "artists").find(band.id)
585
+ end
586
+
587
+ it "persists to the specified database" do
588
+ expect(from_db).to eq(band)
589
+ end
590
+
591
+ it "persists the correct number of documents" do
592
+ expect(Band.with(collection: "artists").count).to eq(1)
593
+ end
594
+ end
595
+ end
596
+
597
+ context "when sending operations with safe mode" do
598
+
599
+ describe ".create" do
600
+
601
+ before do
602
+ Person.create_indexes
603
+ Person.create(ssn: "432-97-1111")
604
+ end
605
+
606
+ context "when no error occurs" do
607
+
608
+ it "inserts the document" do
609
+ expect(Person.count).to eq(1)
610
+ end
611
+ end
612
+
613
+ context "when a mongodb error occurs" do
614
+
615
+ it "bubbles up to the caller" do
616
+ expect {
617
+ Person.create(ssn: "432-97-1111")
618
+ }.to raise_error(Mongo::Error::OperationFailure)
619
+ end
620
+ end
621
+ end
622
+
623
+ describe ".create!" do
624
+
625
+ before do
626
+ Person.create!(ssn: "432-97-1112")
627
+ end
628
+
629
+ context "when no error occurs" do
630
+
631
+ it "inserts the document" do
632
+ expect(Person.count).to eq(1)
633
+ end
634
+ end
635
+
636
+ context "when a mongodb error occurs" do
637
+
638
+ before do
639
+ Person.create_indexes
640
+ end
641
+
642
+ it "bubbles up to the caller" do
643
+ expect {
644
+ Person.create!(ssn: "432-97-1112")
645
+ }.to raise_error(Mongo::Error::OperationFailure)
646
+ end
647
+ end
648
+
649
+ context "when a validation error occurs" do
650
+
651
+ it "raises the validation error" do
652
+ expect {
653
+ Account.create!(name: "this name is way too long")
654
+ }.to raise_error(Mongoid::Errors::Validations)
655
+ end
656
+ end
657
+ end
658
+
659
+ describe ".save" do
660
+
661
+ before do
662
+ Person.create(ssn: "432-97-1113")
663
+ end
664
+
665
+ context "when a mongodb error occurs" do
666
+
667
+ let(:person) do
668
+ Person.new(ssn: "432-97-1113")
669
+ end
670
+
671
+ before do
672
+ Person.create_indexes
673
+ end
674
+
675
+ it "bubbles up to the caller" do
676
+ expect {
677
+ person.save
678
+ }.to raise_error(Mongo::Error::OperationFailure)
679
+ end
680
+ end
681
+ end
682
+
683
+ describe ".save!" do
684
+
685
+ before do
686
+ Person.create!(ssn: "432-97-1114")
687
+ end
688
+
689
+ context "when a mongodb error occurs" do
690
+
691
+ let(:person) do
692
+ Person.new(ssn: "432-97-1114")
693
+ end
694
+
695
+ before do
696
+ Person.create_indexes
697
+ end
698
+
699
+ it "bubbles up to the caller" do
700
+ expect {
701
+ person.save!
702
+ }.to raise_error(Mongo::Error::OperationFailure)
703
+ end
704
+ end
705
+
706
+ context "when a validation error occurs" do
707
+
708
+ let(:account) do
709
+ Account.new(name: "this name is way too long")
710
+ end
711
+
712
+ it "raises the validation error" do
713
+ expect {
714
+ account.save!
715
+ }.to raise_error(Mongoid::Errors::Validations)
716
+ end
717
+ end
718
+ end
719
+ end
720
+ end
721
+
722
+ context "when overriding the default database", if: non_legacy_server? do
723
+
724
+ let(:file) do
725
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid.yml")
726
+ end
727
+
728
+ before do
729
+ Mongoid::Config.load!(file, :test)
730
+ end
731
+
732
+ context "when the override is global" do
733
+
734
+ before do
735
+ Mongoid.override_database(:mongoid_optional)
736
+ end
737
+
738
+ after do
739
+ Band.delete_all
740
+ Mongoid.override_database(nil)
741
+ end
742
+
743
+ let!(:band) do
744
+ Band.create(name: "Tool")
745
+ end
746
+
747
+ it "persists to the overridden database" do
748
+ Band.mongo_client.with(database: :mongoid_optional) do |sess|
749
+ expect(sess[:bands].find(name: "Tool")).to_not be_nil
750
+ end
751
+ end
752
+ end
753
+ end
754
+ end