mongo 2.3.1 → 2.4.0.rc0

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 (170) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -3
  4. data/lib/mongo/bulk_write.rb +8 -7
  5. data/lib/mongo/bulk_write/combineable.rb +4 -0
  6. data/lib/mongo/bulk_write/transformable.rb +17 -5
  7. data/lib/mongo/bulk_write/validatable.rb +1 -0
  8. data/lib/mongo/client.rb +3 -0
  9. data/lib/mongo/cluster.rb +8 -0
  10. data/lib/mongo/cluster/app_metadata.rb +135 -0
  11. data/lib/mongo/collection.rb +42 -10
  12. data/lib/mongo/collection/view.rb +15 -1
  13. data/lib/mongo/collection/view/aggregation.rb +5 -0
  14. data/lib/mongo/collection/view/builder/aggregation.rb +13 -3
  15. data/lib/mongo/collection/view/builder/find_command.rb +7 -21
  16. data/lib/mongo/collection/view/builder/map_reduce.rb +22 -5
  17. data/lib/mongo/collection/view/iterable.rb +1 -0
  18. data/lib/mongo/collection/view/map_reduce.rb +5 -0
  19. data/lib/mongo/collection/view/readable.rb +35 -14
  20. data/lib/mongo/collection/view/writable.rb +54 -23
  21. data/lib/mongo/cursor/builder/get_more_command.rb +2 -3
  22. data/lib/mongo/database.rb +10 -2
  23. data/lib/mongo/error.rb +2 -0
  24. data/lib/mongo/error/invalid_application_name.rb +38 -0
  25. data/lib/mongo/error/invalid_server_preference.rb +24 -3
  26. data/lib/mongo/error/unsupported_collation.rb +51 -0
  27. data/lib/mongo/index/view.rb +28 -15
  28. data/lib/mongo/operation.rb +6 -0
  29. data/lib/mongo/operation/commands.rb +3 -0
  30. data/lib/mongo/operation/commands/aggregate.rb +10 -10
  31. data/lib/mongo/operation/commands/create.rb +45 -0
  32. data/lib/mongo/operation/commands/drop.rb +45 -0
  33. data/lib/mongo/operation/commands/drop_database.rb +45 -0
  34. data/lib/mongo/operation/commands/map_reduce.rb +12 -1
  35. data/lib/mongo/operation/commands/parallel_scan.rb +1 -0
  36. data/lib/mongo/operation/read_preference.rb +9 -9
  37. data/lib/mongo/operation/specifiable.rb +34 -0
  38. data/lib/mongo/operation/takes_write_concern.rb +35 -0
  39. data/lib/mongo/operation/write/bulk/bulkable.rb +1 -1
  40. data/lib/mongo/operation/write/command/create_index.rb +6 -0
  41. data/lib/mongo/operation/write/command/drop_index.rb +6 -0
  42. data/lib/mongo/operation/write/command/insert.rb +1 -1
  43. data/lib/mongo/operation/write/command/update.rb +1 -0
  44. data/lib/mongo/operation/write/command/writable.rb +2 -2
  45. data/lib/mongo/operation/write/create_index.rb +2 -2
  46. data/lib/mongo/operation/write/create_user.rb +1 -1
  47. data/lib/mongo/operation/write/delete.rb +5 -1
  48. data/lib/mongo/operation/write/gle.rb +1 -1
  49. data/lib/mongo/operation/write/insert.rb +2 -2
  50. data/lib/mongo/operation/write/remove_user.rb +1 -1
  51. data/lib/mongo/operation/write/update.rb +5 -1
  52. data/lib/mongo/operation/write/update_user.rb +1 -1
  53. data/lib/mongo/operation/write/write_command_enabled.rb +10 -2
  54. data/lib/mongo/protocol/insert.rb +1 -2
  55. data/lib/mongo/protocol/query.rb +3 -7
  56. data/lib/mongo/server.rb +8 -3
  57. data/lib/mongo/server/connection.rb +17 -11
  58. data/lib/mongo/server/description.rb +22 -0
  59. data/lib/mongo/server/description/features.rb +2 -0
  60. data/lib/mongo/server/monitor.rb +5 -0
  61. data/lib/mongo/server/monitor/connection.rb +11 -0
  62. data/lib/mongo/server_selector/nearest.rb +9 -6
  63. data/lib/mongo/server_selector/primary.rb +4 -0
  64. data/lib/mongo/server_selector/primary_preferred.rb +7 -1
  65. data/lib/mongo/server_selector/secondary.rb +5 -0
  66. data/lib/mongo/server_selector/secondary_preferred.rb +7 -2
  67. data/lib/mongo/server_selector/selectable.rb +57 -10
  68. data/lib/mongo/socket/ssl.rb +1 -0
  69. data/lib/mongo/uri.rb +4 -0
  70. data/lib/mongo/version.rb +1 -1
  71. data/lib/mongo/write_concern.rb +1 -0
  72. data/mongo.gemspec +1 -1
  73. data/spec/mongo/auth/cr_spec.rb +7 -1
  74. data/spec/mongo/auth/ldap_spec.rb +7 -1
  75. data/spec/mongo/auth/scram_spec.rb +7 -1
  76. data/spec/mongo/auth/x509_spec.rb +7 -1
  77. data/spec/mongo/bulk_write_spec.rb +598 -5
  78. data/spec/mongo/client_spec.rb +47 -1
  79. data/spec/mongo/cluster/app_metadata_spec.rb +104 -0
  80. data/spec/mongo/cluster/topology/replica_set_spec.rb +14 -8
  81. data/spec/mongo/cluster/topology/sharded_spec.rb +9 -3
  82. data/spec/mongo/cluster/topology/single_spec.rb +10 -4
  83. data/spec/mongo/cluster_spec.rb +29 -0
  84. data/spec/mongo/collection/view/aggregation_spec.rb +139 -0
  85. data/spec/mongo/collection/view/builder/find_command_spec.rb +6 -243
  86. data/spec/mongo/collection/view/map_reduce_spec.rb +104 -0
  87. data/spec/mongo/collection/view/readable_spec.rb +83 -0
  88. data/spec/mongo/collection/view/writable_spec.rb +447 -1
  89. data/spec/mongo/collection/view_spec.rb +57 -0
  90. data/spec/mongo/collection_spec.rb +926 -101
  91. data/spec/mongo/crud_spec.rb +4 -5
  92. data/spec/mongo/database_spec.rb +99 -1
  93. data/spec/mongo/index/view_spec.rb +360 -31
  94. data/spec/mongo/max_staleness_spec.rb +108 -0
  95. data/spec/mongo/operation/read_preference_spec.rb +8 -8
  96. data/spec/mongo/operation/write/command/delete_spec.rb +1 -1
  97. data/spec/mongo/operation/write/command/insert_spec.rb +1 -1
  98. data/spec/mongo/operation/write/command/update_spec.rb +1 -1
  99. data/spec/mongo/server/connection_pool_spec.rb +3 -1
  100. data/spec/mongo/server/connection_spec.rb +17 -7
  101. data/spec/mongo/server/description/features_spec.rb +50 -0
  102. data/spec/mongo/server/description_spec.rb +9 -3
  103. data/spec/mongo/server_selection_spec.rb +5 -3
  104. data/spec/mongo/server_selector/nearest_spec.rb +73 -0
  105. data/spec/mongo/server_selector/primary_preferred_spec.rb +73 -0
  106. data/spec/mongo/server_selector/primary_spec.rb +36 -0
  107. data/spec/mongo/server_selector/secondary_preferred_spec.rb +73 -0
  108. data/spec/mongo/server_selector/secondary_spec.rb +73 -0
  109. data/spec/mongo/server_selector_spec.rb +53 -0
  110. data/spec/mongo/server_spec.rb +3 -1
  111. data/spec/mongo/uri_spec.rb +54 -0
  112. data/spec/mongo/write_concern_spec.rb +18 -0
  113. data/spec/spec_helper.rb +10 -0
  114. data/spec/support/authorization.rb +8 -1
  115. data/spec/support/crud.rb +15 -0
  116. data/spec/support/crud/read.rb +27 -19
  117. data/spec/support/crud/write.rb +28 -3
  118. data/spec/support/crud_tests/read/aggregate.yml +15 -3
  119. data/spec/support/crud_tests/read/count.yml +14 -3
  120. data/spec/support/crud_tests/read/distinct.yml +13 -1
  121. data/spec/support/crud_tests/read/find.yml +12 -2
  122. data/spec/support/crud_tests/write/deleteMany.yml +22 -1
  123. data/spec/support/crud_tests/write/deleteOne.yml +20 -1
  124. data/spec/support/crud_tests/write/findOneAndDelete.yml +27 -2
  125. data/spec/support/crud_tests/write/findOneAndReplace.yml +43 -14
  126. data/spec/support/crud_tests/write/findOneAndUpdate.yml +50 -8
  127. data/spec/support/crud_tests/write/replaceOne.yml +34 -10
  128. data/spec/support/crud_tests/write/updateMany.yml +42 -11
  129. data/spec/support/crud_tests/write/updateOne.yml +32 -7
  130. data/spec/support/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +26 -0
  131. data/spec/support/max_staleness/ReplicaSetNoPrimary/Incompatible.yml +25 -0
  132. data/spec/support/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +33 -0
  133. data/spec/support/max_staleness/ReplicaSetNoPrimary/Nearest.yml +33 -0
  134. data/spec/support/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +33 -0
  135. data/spec/support/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +27 -0
  136. data/spec/support/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +36 -0
  137. data/spec/support/max_staleness/ReplicaSetNoPrimary/Secondary.yml +51 -0
  138. data/spec/support/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +26 -0
  139. data/spec/support/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +51 -0
  140. data/spec/support/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +26 -0
  141. data/spec/support/max_staleness/ReplicaSetWithPrimary/Incompatible.yml +25 -0
  142. data/spec/support/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +35 -0
  143. data/spec/support/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +25 -0
  144. data/spec/support/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +23 -0
  145. data/spec/support/max_staleness/ReplicaSetWithPrimary/Nearest.yml +33 -0
  146. data/spec/support/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +33 -0
  147. data/spec/support/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +36 -0
  148. data/spec/support/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +27 -0
  149. data/spec/support/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.yml +27 -0
  150. data/spec/support/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +26 -0
  151. data/spec/support/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +59 -0
  152. data/spec/support/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +43 -0
  153. data/spec/support/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +59 -0
  154. data/spec/support/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +43 -0
  155. data/spec/support/max_staleness/ReplicaSetWithPrimary/ShortHeartbeartShortMaxStaleness.yml +29 -0
  156. data/spec/support/max_staleness/ReplicaSetWithPrimary/ShortHeartbeartShortMaxStaleness2.yml +29 -0
  157. data/spec/support/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +27 -0
  158. data/spec/support/max_staleness/Sharded/Incompatible.yml +25 -0
  159. data/spec/support/max_staleness/Sharded/SmallMaxStaleness.yml +20 -0
  160. data/spec/support/max_staleness/Single/Incompatible.yml +18 -0
  161. data/spec/support/max_staleness/Single/SmallMaxStaleness.yml +20 -0
  162. data/spec/support/server_selection.rb +25 -0
  163. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_multiple.yml +27 -0
  164. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_multi_tags.yml +31 -0
  165. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_multi_tags2.yml +31 -0
  166. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_multiple.yml +34 -0
  167. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred_tags.yml +28 -0
  168. data/spec/support/shared/server_selector.rb +4 -3
  169. metadata +91 -6
  170. metadata.gz.sig +0 -0
@@ -25,15 +25,14 @@ describe 'CRUD' do
25
25
  end
26
26
 
27
27
  it "returns the correct result" do
28
- skip 'Test results only match with server version >= 2.6' if test.requires_2_6?(write_command_enabled?,
29
- authorized_collection)
28
+ skip 'Test cannot be run on this server version' unless test.feature_enabled?(authorized_collection)
30
29
  expect(results).to eq(test.result)
31
30
  end
32
31
 
33
32
  it 'has the correct data in the collection' do
34
- skip 'Test results only match with server version >= 2.6' if test.requires_2_6?(write_command_enabled?,
35
- authorized_collection)
36
- expect(test.run(authorized_collection)).to match_collection_data(test)
33
+ skip 'Test cannot be run on this server version' unless test.feature_enabled?(authorized_collection)
34
+ results
35
+ expect(authorized_collection.find.to_a).to match_collection_data(test)
37
36
  end
38
37
  end
39
38
  end
@@ -327,6 +327,70 @@ describe Mongo::Database do
327
327
  }.to raise_error(Mongo::Error::NoServerAvailable)
328
328
  end
329
329
  end
330
+
331
+ context 'when a write concern is not defined on the client/database object' do
332
+
333
+ context 'when a write concern is provided in the selector', if: standalone? do
334
+
335
+ let(:cmd) do
336
+ {
337
+ insert: TEST_COLL,
338
+ documents: [ { a: 1 } ],
339
+ writeConcern: { w: WRITE_CONCERN[:w]+1 }
340
+ }
341
+ end
342
+
343
+ it 'uses the write concern' do
344
+ expect {
345
+ database.command(cmd)
346
+ }.to raise_exception(Mongo::Error::OperationFailure)
347
+ end
348
+ end
349
+ end
350
+
351
+ context 'when a write concern is defined on the client/database object' do
352
+
353
+ let(:client_options) do
354
+ {
355
+ write: { w: WRITE_CONCERN[:w] + 1 }
356
+ }
357
+ end
358
+
359
+ let(:database) do
360
+ described_class.new(authorized_client.with(client_options), TEST_DB)
361
+ end
362
+
363
+ context 'when a write concern is not in the command selector', if: write_command_enabled? do
364
+
365
+ let(:cmd) do
366
+ {
367
+ insert: TEST_COLL,
368
+ documents: [ { a: 1 } ]
369
+ }
370
+ end
371
+
372
+ it 'does not apply a write concern' do
373
+ expect(database.command(cmd).written_count).to eq(1)
374
+ end
375
+ end
376
+
377
+ context 'when a write concern is provided in the command selector', if: write_command_enabled? && standalone? do
378
+
379
+ let(:cmd) do
380
+ {
381
+ insert: TEST_COLL,
382
+ documents: [ { a: 1 } ],
383
+ writeConcern: { w: WRITE_CONCERN[:w]+1 }
384
+ }
385
+ end
386
+
387
+ it 'uses the write concern' do
388
+ expect {
389
+ database.command(cmd)
390
+ }.to raise_exception(Mongo::Error::OperationFailure)
391
+ end
392
+ end
393
+ end
330
394
  end
331
395
 
332
396
  describe '#drop' do
@@ -339,11 +403,45 @@ describe Mongo::Database do
339
403
  expect(database.drop).to be_successful
340
404
  end
341
405
 
342
- it 'raises an exception', unless: write_command_enabled? do
406
+ it 'raises an exception', if: (!write_command_enabled? && auth_enabled?) do
343
407
  expect {
344
408
  database.drop
345
409
  }.to raise_error(Mongo::Error::OperationFailure)
346
410
  end
411
+
412
+ context 'when the client/database has a write concern' do
413
+
414
+ let(:client_options) do
415
+ {
416
+ write: { w: WRITE_CONCERN[:w] + 1 },
417
+ database: :safe_to_drop
418
+ }
419
+ end
420
+
421
+ let(:client) do
422
+ root_authorized_client.with(client_options)
423
+ end
424
+
425
+ let(:database_with_write_options) do
426
+ client.database
427
+ end
428
+
429
+ context 'when the server supports write concern on the dropDatabase command', if: (collation_enabled? && standalone?) do
430
+
431
+ it 'applies the write concern' do
432
+ expect{
433
+ database_with_write_options.drop
434
+ }.to raise_exception(Mongo::Error::OperationFailure)
435
+ end
436
+ end
437
+
438
+ context 'when the server does not support write concern on the dropDatabase command', unless: collation_enabled? do
439
+
440
+ it 'does not apply the write concern' do
441
+ expect(database_with_write_options.drop).to be_successful
442
+ end
443
+ end
444
+ end
347
445
  end
348
446
 
349
447
  describe '#initialize' do
@@ -16,6 +16,10 @@ describe Mongo::Index::View do
16
16
  view.create_one(spec, unique: true)
17
17
  end
18
18
 
19
+ after do
20
+ begin; view.drop_one('another_-1'); rescue; end
21
+ end
22
+
19
23
  context 'when the index exists' do
20
24
 
21
25
  let(:result) do
@@ -35,6 +39,68 @@ describe Mongo::Index::View do
35
39
  }.to raise_error(Mongo::Error::MultiIndexDrop)
36
40
  end
37
41
  end
42
+
43
+ context 'when the collection has a write concern' do
44
+
45
+ let(:collection) do
46
+ authorized_collection.with(write: { w: WRITE_CONCERN[:w] + 1})
47
+ end
48
+
49
+ let(:view_with_write_concern) do
50
+ described_class.new(collection)
51
+ end
52
+
53
+ let(:result) do
54
+ view_with_write_concern.drop_one('another_-1')
55
+ end
56
+
57
+ context 'when the server accepts writeConcern for the dropIndexes operation', if: collation_enabled? do
58
+
59
+ it 'applies the write concern' do
60
+ expect {
61
+ result
62
+ }.to raise_exception(Mongo::Error::OperationFailure)
63
+ end
64
+ end
65
+
66
+ context 'when the server does not accept writeConcern for the dropIndexes operation', unless: collation_enabled? do
67
+
68
+ it 'does not apply the write concern' do
69
+ expect(result).to be_successful
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'when there are multiple indexes with the same key pattern', if: collation_enabled? do
75
+
76
+ before do
77
+ view.create_one({ random: 1 }, unique: true)
78
+ view.create_one({ random: 1 },
79
+ name: 'random_1_with_collation',
80
+ unique: true,
81
+ collation: { locale: 'en_US', strength: 2 })
82
+ end
83
+
84
+ context 'when a name is supplied' do
85
+
86
+ let!(:result) do
87
+ view.drop_one('random_1_with_collation')
88
+ end
89
+
90
+ let(:index_names) do
91
+ view.collect { |model| model['name'] }
92
+ end
93
+
94
+ it 'returns ok' do
95
+ expect(result).to be_successful
96
+ end
97
+
98
+ it 'drops the correct index' do
99
+ expect(index_names).not_to include('random_1_with_collation')
100
+ expect(index_names).to include('random_1')
101
+ end
102
+ end
103
+ end
38
104
  end
39
105
 
40
106
  describe '#drop_all' do
@@ -56,6 +122,41 @@ describe Mongo::Index::View do
56
122
  it 'drops the index' do
57
123
  expect(result).to be_successful
58
124
  end
125
+
126
+ context 'when the collection has a write concern' do
127
+
128
+ let(:collection) do
129
+ authorized_collection.with(write: { w: WRITE_CONCERN[:w] + 1})
130
+ end
131
+
132
+ let(:view_with_write_concern) do
133
+ described_class.new(collection)
134
+ end
135
+
136
+ let(:result) do
137
+ view_with_write_concern.drop_all
138
+ end
139
+
140
+ after do
141
+ view.drop_all
142
+ end
143
+
144
+ context 'when the server accepts writeConcern for the dropIndexes operation', if: collation_enabled? do
145
+
146
+ it 'applies the write concern' do
147
+ expect {
148
+ result
149
+ }.to raise_exception(Mongo::Error::OperationFailure)
150
+ end
151
+ end
152
+
153
+ context 'when the server does not accept writeConcern for the dropIndexes operation', unless: collation_enabled? do
154
+
155
+ it 'does not apply the write concern' do
156
+ expect(result).to be_successful
157
+ end
158
+ end
159
+ end
59
160
  end
60
161
  end
61
162
 
@@ -65,39 +166,227 @@ describe Mongo::Index::View do
65
166
 
66
167
  context 'when passing multi-args' do
67
168
 
68
- let(:result) do
69
- view.create_many(
70
- { key: { random: 1 }, unique: true },
71
- { key: { testing: -1 }, unique: true }
72
- )
169
+ context 'when the index creation is successful' do
170
+
171
+ let!(:result) do
172
+ view.create_many(
173
+ { key: { random: 1 }, unique: true },
174
+ { key: { testing: -1 }, unique: true }
175
+ )
176
+ end
177
+
178
+ after do
179
+ view.drop_one('random_1')
180
+ view.drop_one('testing_-1')
181
+ end
182
+
183
+ it 'returns ok' do
184
+ expect(result).to be_successful
185
+ end
73
186
  end
74
187
 
75
- after do
76
- view.drop_one('random_1')
77
- view.drop_one('testing_-1')
188
+ context 'when collation is specified', if: collation_enabled? do
189
+
190
+ let(:result) do
191
+ view.create_many(
192
+ { key: { random: 1 },
193
+ unique: true,
194
+ collation: { locale: 'en_US', strength: 2 } }
195
+ )
196
+ end
197
+
198
+ after do
199
+ begin; view.drop_one('random_1'); rescue; end
200
+ end
201
+
202
+ let(:index_info) do
203
+ view.get('random_1')
204
+ end
205
+
206
+ context 'when the server supports collations', if: collation_enabled? do
207
+
208
+ it 'returns ok' do
209
+ expect(result).to be_successful
210
+ end
211
+
212
+ it 'applies the collation to the new index' do
213
+ result
214
+ expect(index_info['collation']).not_to be_nil
215
+ expect(index_info['collation']['locale']).to eq('en_US')
216
+ expect(index_info['collation']['strength']).to eq(2)
217
+ end
218
+ end
219
+
220
+ context 'when the server does not support collations', unless: collation_enabled? do
221
+
222
+ it 'raises an exception' do
223
+ expect {
224
+ result
225
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
226
+ end
227
+ end
78
228
  end
79
229
 
80
- it 'returns ok' do
81
- expect(result).to be_successful
230
+ context 'when the collection has a write concern' do
231
+
232
+ after do
233
+ begin; view.drop_one('random_1'); rescue; end
234
+ begin; view.drop_one('testing_-1'); rescue; end
235
+ end
236
+
237
+ let(:collection) do
238
+ authorized_collection.with(write: { w: WRITE_CONCERN[:w] + 1})
239
+ end
240
+
241
+ let(:view_with_write_concern) do
242
+ described_class.new(collection)
243
+ end
244
+
245
+ let(:result) do
246
+ view_with_write_concern.create_many(
247
+ { key: { random: 1 }, unique: true },
248
+ { key: { testing: -1 }, unique: true }
249
+ )
250
+ end
251
+
252
+ context 'when the server accepts writeConcern for the createIndexes operation', if: collation_enabled? do
253
+
254
+ it 'applies the write concern' do
255
+ expect {
256
+ result
257
+ }.to raise_exception(Mongo::Error::OperationFailure)
258
+ end
259
+ end
260
+
261
+ context 'when the server does not accept writeConcern for the createIndexes operation', unless: collation_enabled? do
262
+
263
+ context 'when the server supports the createIndexes command', if: write_command_enabled? do
264
+
265
+ it 'does not apply the write concern' do
266
+ expect(result).to be_successful
267
+ end
268
+ end
269
+
270
+ context 'when the driver inserts into the system.indexes collection', unless: write_command_enabled? do
271
+
272
+ it 'does not apply the write concern' do
273
+ expect(result).to be_successful
274
+ end
275
+ end
276
+ end
82
277
  end
83
278
  end
84
279
 
85
280
  context 'when passing an array' do
86
281
 
87
- let(:result) do
88
- view.create_many([
89
- { key: { random: 1 }, unique: true },
90
- { key: { testing: -1 }, unique: true }
91
- ])
282
+ context 'when the index creation is successful' do
283
+
284
+ let!(:result) do
285
+ view.create_many([
286
+ { key: { random: 1 }, unique: true },
287
+ { key: { testing: -1 }, unique: true }
288
+ ])
289
+ end
290
+
291
+ after do
292
+ view.drop_one('random_1')
293
+ view.drop_one('testing_-1')
294
+ end
295
+
296
+ it 'returns ok' do
297
+ expect(result).to be_successful
298
+ end
92
299
  end
93
300
 
94
- after do
95
- view.drop_one('random_1')
96
- view.drop_one('testing_-1')
301
+ context 'when collation is specified' do
302
+
303
+ let(:result) do
304
+ view.create_many([
305
+ { key: { random: 1 },
306
+ unique: true,
307
+ collation: { locale: 'en_US', strength: 2 }},
308
+ ])
309
+ end
310
+
311
+ let(:index_info) do
312
+ view.get('random_1')
313
+ end
314
+
315
+ after do
316
+ begin; view.drop_one('random_1'); rescue; end
317
+ end
318
+
319
+ context 'when the server supports collations', if: collation_enabled? do
320
+
321
+ it 'returns ok' do
322
+ expect(result).to be_successful
323
+ end
324
+
325
+ it 'applies the collation to the new index' do
326
+ result
327
+ expect(index_info['collation']).not_to be_nil
328
+ expect(index_info['collation']['locale']).to eq('en_US')
329
+ expect(index_info['collation']['strength']).to eq(2)
330
+ end
331
+ end
332
+
333
+ context 'when the server does not support collations', unless: collation_enabled? do
334
+
335
+ it 'raises an exception' do
336
+ expect {
337
+ result
338
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
339
+ end
340
+ end
97
341
  end
98
342
 
99
- it 'returns ok' do
100
- expect(result).to be_successful
343
+ context 'when the collection has a write concern' do
344
+
345
+ after do
346
+ begin; view.drop_one('random_1'); rescue; end
347
+ begin; view.drop_one('testing_-1'); rescue; end
348
+ end
349
+
350
+ let(:collection) do
351
+ authorized_collection.with(write: { w: WRITE_CONCERN[:w] + 1})
352
+ end
353
+
354
+ let(:view_with_write_concern) do
355
+ described_class.new(collection)
356
+ end
357
+
358
+ let(:result) do
359
+ view_with_write_concern.create_many([
360
+ { key: { random: 1 }, unique: true },
361
+ { key: { testing: -1 }, unique: true }
362
+ ])
363
+ end
364
+
365
+ context 'when the server accepts writeConcern for the createIndexes operation', if: collation_enabled? do
366
+
367
+ it 'applies the write concern' do
368
+ expect {
369
+ result
370
+ }.to raise_exception(Mongo::Error::OperationFailure)
371
+ end
372
+ end
373
+
374
+ context 'when the server does not accept writeConcern for the createIndexes operation', unless: collation_enabled? do
375
+
376
+ context 'when the server accepts the createIndexes command', if: write_command_enabled? do
377
+
378
+ it 'does not apply the write concern' do
379
+ expect(result).to be_successful
380
+ end
381
+ end
382
+
383
+ context 'when the driver inserts into the system.indexes collection', unless: write_command_enabled? do
384
+
385
+ it 'does not apply the write concern' do
386
+ expect(result).to be_successful
387
+ end
388
+ end
389
+ end
101
390
  end
102
391
  end
103
392
 
@@ -148,22 +437,44 @@ describe Mongo::Index::View do
148
437
  expect(result).to be_successful
149
438
  end
150
439
 
151
- context 'when the index is created on an subdocument field' do
440
+ context 'when the collection has a write concern' do
152
441
 
153
- let(:spec) do
154
- { 'sub_document.random' => 1 }
442
+ let(:collection) do
443
+ authorized_collection.with(write: { w: WRITE_CONCERN[:w] + 1})
444
+ end
445
+
446
+ let(:view_with_write_concern) do
447
+ described_class.new(collection)
155
448
  end
156
449
 
157
450
  let(:result) do
158
- view.create_one(spec, unique: true)
451
+ view_with_write_concern.create_one(spec, unique: true)
159
452
  end
160
453
 
161
- after do
162
- begin; view.drop_one('sub_document.random_1'); rescue; end
454
+ context 'when the server accepts writeConcern for the createIndexes operation', if: collation_enabled? do
455
+
456
+ it 'applies the write concern' do
457
+ expect {
458
+ result
459
+ }.to raise_exception(Mongo::Error::OperationFailure)
460
+ end
163
461
  end
164
462
 
165
- it 'returns ok' do
166
- expect(result).to be_successful
463
+ context 'when the server does not accept writeConcern for the createIndexes operation', unless: collation_enabled? do
464
+
465
+ context 'when the server supports the createIndexes command', if: write_command_enabled? do
466
+
467
+ it 'does not apply the write concern' do
468
+ expect(result).to be_successful
469
+ end
470
+ end
471
+
472
+ context 'when the driver inserts into the system.indexes collection', unless: write_command_enabled? do
473
+
474
+ it 'does not apply the write concern' do
475
+ expect(result).to be_successful
476
+ end
477
+ end
167
478
  end
168
479
  end
169
480
  end
@@ -254,7 +565,6 @@ describe Mongo::Index::View do
254
565
  it 'passes partialFilterExpression correctly' do
255
566
  expect(indexes[:partialFilterExpression]).to eq(expression)
256
567
  end
257
-
258
568
  end
259
569
  end
260
570
 
@@ -364,7 +674,7 @@ describe Mongo::Index::View do
364
674
  end
365
675
 
366
676
  let(:models) do
367
- view.send(:normalize_models, [ options ])
677
+ view.send(:normalize_models, [ options ], authorized_primary)
368
678
  end
369
679
 
370
680
  let(:expected) do
@@ -397,7 +707,26 @@ describe Mongo::Index::View do
397
707
  end
398
708
 
399
709
  let(:models) do
400
- view.send(:normalize_models, [ extended_options ])
710
+ view.send(:normalize_models, [ extended_options ], authorized_primary)
711
+ end
712
+
713
+ it 'maps the ruby options to the server options' do
714
+ expect(models).to eq([ extended_expected ])
715
+ end
716
+ end
717
+
718
+ context 'when the server supports collations', if: collation_enabled? do
719
+
720
+ let(:extended_options) do
721
+ options.merge(:collation => { locale: 'en_US' } )
722
+ end
723
+
724
+ let(:models) do
725
+ view.send(:normalize_models, [ extended_options ], authorized_primary)
726
+ end
727
+
728
+ let(:extended_expected) do
729
+ expected.tap { |exp| exp[:collation] = { locale: 'en_US' } }
401
730
  end
402
731
 
403
732
  it 'maps the ruby options to the server options' do