mongo 2.3.1 → 2.4.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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