mongo 2.0.6 → 2.1.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 (317) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +5 -2
  3. data/lib/mongo/address/ipv4.rb +6 -1
  4. data/lib/mongo/address/unix.rb +2 -2
  5. data/lib/mongo/address.rb +18 -10
  6. data/lib/mongo/auth/cr/conversation.rb +1 -1
  7. data/lib/mongo/auth/ldap/conversation.rb +7 -3
  8. data/lib/mongo/auth/scram/conversation.rb +9 -3
  9. data/lib/mongo/auth/user/view.rb +23 -2
  10. data/lib/mongo/auth/x509/conversation.rb +1 -1
  11. data/lib/mongo/bulk_write/combineable.rb +51 -0
  12. data/lib/mongo/bulk_write/ordered_combiner.rb +55 -0
  13. data/lib/mongo/bulk_write/result.rb +191 -0
  14. data/lib/mongo/bulk_write/result_combiner.rb +117 -0
  15. data/lib/mongo/bulk_write/transformable.rb +132 -0
  16. data/lib/mongo/bulk_write/unordered_combiner.rb +52 -0
  17. data/lib/mongo/bulk_write/validatable.rb +62 -0
  18. data/lib/mongo/bulk_write.rb +159 -23
  19. data/lib/mongo/client.rb +52 -16
  20. data/lib/mongo/cluster/topology/replica_set.rb +27 -9
  21. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  22. data/lib/mongo/cluster/topology/unknown.rb +5 -2
  23. data/lib/mongo/cluster.rb +42 -7
  24. data/lib/mongo/collection/view/aggregation.rb +48 -9
  25. data/lib/mongo/collection/view/immutable.rb +6 -6
  26. data/lib/mongo/collection/view/iterable.rb +18 -4
  27. data/lib/mongo/collection/view/map_reduce.rb +58 -17
  28. data/lib/mongo/collection/view/readable.rb +173 -42
  29. data/lib/mongo/collection/view/writable.rb +37 -23
  30. data/lib/mongo/collection/view.rb +2 -2
  31. data/lib/mongo/collection.rb +370 -33
  32. data/lib/mongo/cursor.rb +15 -3
  33. data/lib/mongo/database/view.rb +5 -4
  34. data/lib/mongo/database.rb +14 -4
  35. data/lib/mongo/dbref.rb +113 -0
  36. data/lib/mongo/error/closed_stream.rb +34 -0
  37. data/lib/mongo/error/extra_file_chunk.rb +34 -0
  38. data/lib/mongo/error/{invalid_uri_option.rb → file_not_found.rb} +11 -12
  39. data/lib/mongo/error/invalid_file.rb +2 -2
  40. data/lib/mongo/error/invalid_file_revision.rb +37 -0
  41. data/lib/mongo/error/invalid_uri.rb +5 -4
  42. data/lib/mongo/error/missing_file_chunk.rb +38 -0
  43. data/lib/mongo/error/operation_failure.rb +1 -1
  44. data/lib/mongo/error/parser.rb +1 -1
  45. data/lib/mongo/error/unchangeable_collection_option.rb +38 -0
  46. data/lib/mongo/error/unexpected_chunk_length.rb +39 -0
  47. data/lib/mongo/error.rb +13 -2
  48. data/lib/mongo/event/description_changed.rb +1 -1
  49. data/lib/mongo/grid/file/chunk.rb +6 -6
  50. data/lib/mongo/grid/file/{metadata.rb → info.rb} +41 -39
  51. data/lib/mongo/grid/file.rb +13 -10
  52. data/lib/mongo/grid/fs_bucket.rb +448 -0
  53. data/lib/mongo/grid/stream/read.rb +208 -0
  54. data/lib/mongo/grid/stream/write.rb +187 -0
  55. data/lib/mongo/grid/stream.rb +64 -0
  56. data/lib/mongo/grid.rb +2 -1
  57. data/lib/mongo/index/view.rb +3 -3
  58. data/lib/mongo/index.rb +5 -0
  59. data/lib/mongo/loggable.rb +34 -57
  60. data/lib/mongo/logger.rb +16 -78
  61. data/lib/mongo/monitoring/command_log_subscriber.rb +112 -0
  62. data/lib/mongo/monitoring/event/command_failed.rb +96 -0
  63. data/lib/mongo/monitoring/event/command_started.rb +89 -0
  64. data/lib/mongo/monitoring/event/command_succeeded.rb +118 -0
  65. data/lib/mongo/monitoring/event/secure.rb +58 -0
  66. data/lib/mongo/monitoring/event.rb +18 -0
  67. data/lib/mongo/monitoring/publishable.rb +106 -0
  68. data/lib/mongo/monitoring.rb +195 -0
  69. data/lib/mongo/operation/{aggregate.rb → commands/aggregate.rb} +3 -41
  70. data/lib/mongo/operation/commands/collections_info/result.rb +39 -0
  71. data/lib/mongo/operation/commands/collections_info.rb +68 -0
  72. data/lib/mongo/operation/{command.rb → commands/command.rb} +2 -18
  73. data/lib/mongo/operation/commands/indexes.rb +70 -0
  74. data/lib/mongo/operation/commands/list_collections/result.rb +112 -0
  75. data/lib/mongo/operation/commands/list_collections.rb +54 -0
  76. data/lib/mongo/operation/commands/list_indexes/result.rb +116 -0
  77. data/lib/mongo/operation/commands/list_indexes.rb +56 -0
  78. data/lib/mongo/operation/{map_reduce → commands/map_reduce}/result.rb +1 -1
  79. data/lib/mongo/operation/{map_reduce.rb → commands/map_reduce.rb} +3 -41
  80. data/lib/mongo/operation/commands/parallel_scan/result.rb +72 -0
  81. data/lib/mongo/operation/commands/parallel_scan.rb +56 -0
  82. data/lib/mongo/operation/commands/user_query.rb +69 -0
  83. data/lib/mongo/{bulk_write/ordered_bulk_write.rb → operation/commands/users_info/result.rb} +18 -30
  84. data/lib/mongo/operation/commands/users_info.rb +53 -0
  85. data/lib/mongo/operation/commands.rb +24 -0
  86. data/lib/mongo/operation/executable.rb +4 -68
  87. data/lib/mongo/operation/kill_cursors.rb +3 -3
  88. data/lib/mongo/operation/read/get_more.rb +2 -22
  89. data/lib/mongo/{bulk_write/unordered_bulk_write.rb → operation/read/query/result.rb} +20 -26
  90. data/lib/mongo/operation/read/query.rb +4 -21
  91. data/lib/mongo/operation/read.rb +0 -4
  92. data/lib/mongo/operation/{read_preferrable.rb → read_preference.rb} +3 -2
  93. data/lib/mongo/operation/result.rb +13 -1
  94. data/lib/mongo/operation/specifiable.rb +42 -0
  95. data/lib/mongo/operation/write/bulk/bulkable.rb +82 -0
  96. data/lib/mongo/operation/write/bulk/delete/result.rb +74 -0
  97. data/lib/mongo/operation/write/bulk/delete.rb +71 -0
  98. data/lib/mongo/operation/write/bulk/insert/result.rb +129 -0
  99. data/lib/mongo/operation/write/bulk/insert.rb +96 -0
  100. data/lib/mongo/operation/write/bulk/legacy_mergable.rb +87 -0
  101. data/lib/mongo/operation/write/bulk/mergable.rb +71 -0
  102. data/lib/mongo/operation/write/bulk/update/result.rb +174 -0
  103. data/lib/mongo/operation/write/bulk/update.rb +81 -0
  104. data/lib/mongo/operation/write/bulk.rb +6 -3
  105. data/lib/mongo/operation/write/command/create_index.rb +0 -1
  106. data/lib/mongo/operation/write/command/create_user.rb +0 -1
  107. data/lib/mongo/operation/write/command/delete.rb +0 -1
  108. data/lib/mongo/operation/write/command/drop_index.rb +0 -1
  109. data/lib/mongo/operation/write/command/insert.rb +0 -1
  110. data/lib/mongo/operation/write/command/remove_user.rb +0 -1
  111. data/lib/mongo/operation/write/command/update.rb +0 -1
  112. data/lib/mongo/operation/write/command/update_user.rb +0 -1
  113. data/lib/mongo/operation/write/command/writable.rb +13 -18
  114. data/lib/mongo/operation/write/create_index.rb +4 -27
  115. data/lib/mongo/operation/write/create_user.rb +4 -30
  116. data/lib/mongo/operation/write/delete.rb +6 -29
  117. data/lib/mongo/operation/write/drop_index.rb +3 -3
  118. data/lib/mongo/operation/write/gle.rb +48 -0
  119. data/lib/mongo/operation/write/idable.rb +5 -0
  120. data/lib/mongo/operation/write/insert.rb +2 -24
  121. data/lib/mongo/operation/write/remove_user.rb +4 -27
  122. data/lib/mongo/operation/write/update.rb +13 -36
  123. data/lib/mongo/operation/write/update_user.rb +4 -30
  124. data/lib/mongo/operation/write/write_command_enabled.rb +53 -0
  125. data/lib/mongo/operation/write.rb +2 -0
  126. data/lib/mongo/operation.rb +32 -4
  127. data/lib/mongo/options/mapper.rb +4 -2
  128. data/lib/mongo/options/redacted.rb +156 -0
  129. data/lib/mongo/options.rb +1 -0
  130. data/lib/mongo/protocol/delete.rb +75 -15
  131. data/lib/mongo/protocol/get_more.rb +65 -13
  132. data/lib/mongo/protocol/insert.rb +85 -13
  133. data/lib/mongo/protocol/kill_cursors.rb +59 -14
  134. data/lib/mongo/protocol/message.rb +12 -12
  135. data/lib/mongo/protocol/query.rb +163 -37
  136. data/lib/mongo/protocol/reply.rb +103 -0
  137. data/lib/mongo/protocol/serializers.rb +1 -1
  138. data/lib/mongo/protocol/update.rb +82 -14
  139. data/lib/mongo/retryable.rb +83 -0
  140. data/lib/mongo/server/connectable.rb +21 -25
  141. data/lib/mongo/server/connection.rb +75 -4
  142. data/lib/mongo/server/connection_pool/queue.rb +15 -0
  143. data/lib/mongo/server/connection_pool.rb +12 -0
  144. data/lib/mongo/server/description/features.rb +2 -1
  145. data/lib/mongo/server/description.rb +52 -1
  146. data/lib/mongo/server/monitor/connection.rb +26 -2
  147. data/lib/mongo/server/monitor.rb +19 -3
  148. data/lib/mongo/server.rb +39 -5
  149. data/lib/mongo/server_selector/selectable.rb +40 -31
  150. data/lib/mongo/server_selector.rb +19 -10
  151. data/lib/mongo/socket/ssl.rb +28 -16
  152. data/lib/mongo/socket/tcp.rb +3 -3
  153. data/lib/mongo/socket/unix.rb +5 -8
  154. data/lib/mongo/socket.rb +11 -4
  155. data/lib/mongo/uri.rb +248 -137
  156. data/lib/mongo/version.rb +1 -1
  157. data/lib/mongo.rb +5 -3
  158. data/spec/mongo/address/unix_spec.rb +1 -1
  159. data/spec/mongo/address_spec.rb +25 -0
  160. data/spec/mongo/auth/cr_spec.rb +9 -1
  161. data/spec/mongo/auth/ldap/conversation_spec.rb +43 -0
  162. data/spec/mongo/auth/ldap_spec.rb +9 -1
  163. data/spec/mongo/auth/scram_spec.rb +9 -1
  164. data/spec/mongo/auth/user/view_spec.rb +26 -1
  165. data/spec/mongo/auth/x509_spec.rb +9 -1
  166. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +271 -0
  167. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +239 -0
  168. data/spec/mongo/bulk_write_spec.rb +428 -0
  169. data/spec/mongo/client_spec.rb +167 -17
  170. data/spec/mongo/cluster/topology/replica_set_spec.rb +18 -9
  171. data/spec/mongo/cluster/topology/sharded_spec.rb +11 -3
  172. data/spec/mongo/cluster/topology/single_spec.rb +12 -4
  173. data/spec/mongo/cluster_spec.rb +55 -10
  174. data/spec/mongo/collection/view/aggregation_spec.rb +188 -1
  175. data/spec/mongo/collection/view/explainable_spec.rb +1 -1
  176. data/spec/mongo/collection/view/immutable_spec.rb +103 -0
  177. data/spec/mongo/collection/view/map_reduce_spec.rb +99 -4
  178. data/spec/mongo/collection/view/readable_spec.rb +238 -6
  179. data/spec/mongo/collection/view/writable_spec.rb +4 -4
  180. data/spec/mongo/collection/view_spec.rb +459 -71
  181. data/spec/mongo/collection_spec.rb +1291 -9
  182. data/spec/mongo/command_monitoring_spec.rb +51 -0
  183. data/spec/mongo/connection_string_spec.rb +115 -0
  184. data/spec/mongo/crud_spec.rb +2 -2
  185. data/spec/mongo/cursor_spec.rb +3 -3
  186. data/spec/mongo/database_spec.rb +47 -11
  187. data/spec/mongo/dbref_spec.rb +149 -0
  188. data/spec/mongo/grid/file/chunk_spec.rb +5 -5
  189. data/spec/mongo/grid/file/{metadata_spec.rb → info_spec.rb} +29 -17
  190. data/spec/mongo/grid/file_spec.rb +8 -8
  191. data/spec/mongo/grid/fs_bucket_spec.rb +1020 -0
  192. data/spec/mongo/grid/stream/read_spec.rb +275 -0
  193. data/spec/mongo/grid/stream/write_spec.rb +440 -0
  194. data/spec/mongo/grid/stream_spec.rb +48 -0
  195. data/spec/mongo/gridfs_spec.rb +50 -0
  196. data/spec/mongo/logger_spec.rb +0 -40
  197. data/spec/mongo/monitoring/command_log_subscriber_spec.rb +76 -0
  198. data/spec/mongo/monitoring/event/command_started_spec.rb +26 -0
  199. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +26 -0
  200. data/spec/mongo/monitoring/event/secure_spec.rb +57 -0
  201. data/spec/mongo/monitoring_spec.rb +168 -0
  202. data/spec/mongo/operation/commands/aggregate_spec.rb +69 -0
  203. data/spec/mongo/operation/{read → commands}/collections_info_spec.rb +1 -1
  204. data/spec/mongo/operation/{command_spec.rb → commands/command_spec.rb} +0 -18
  205. data/spec/mongo/operation/{read → commands}/indexes_spec.rb +1 -1
  206. data/spec/mongo/operation/{map_reduce_spec.rb → commands/map_reduce_spec.rb} +1 -19
  207. data/spec/mongo/operation/kill_cursors_spec.rb +1 -17
  208. data/spec/mongo/operation/read/get_more_spec.rb +0 -16
  209. data/spec/mongo/operation/read/query_spec.rb +19 -16
  210. data/spec/mongo/operation/{read_preferrable_spec.rb → read_preference_spec.rb} +11 -11
  211. data/spec/mongo/operation/write/bulk/{bulk_delete_spec.rb → delete_spec.rb} +18 -29
  212. data/spec/mongo/operation/write/bulk/{bulk_insert_spec.rb → insert_spec.rb} +3 -14
  213. data/spec/mongo/operation/write/bulk/{bulk_update_spec.rb → update_spec.rb} +8 -19
  214. data/spec/mongo/operation/write/command/delete_spec.rb +0 -16
  215. data/spec/mongo/operation/write/command/insert_spec.rb +0 -16
  216. data/spec/mongo/operation/write/command/update_spec.rb +0 -16
  217. data/spec/mongo/operation/write/delete_spec.rb +4 -4
  218. data/spec/mongo/operation/write/insert_spec.rb +2 -13
  219. data/spec/mongo/operation/write/update_spec.rb +7 -7
  220. data/spec/mongo/options/redacted_spec.rb +350 -0
  221. data/spec/mongo/protocol/kill_cursors_spec.rb +5 -3
  222. data/spec/mongo/protocol/query_spec.rb +15 -30
  223. data/spec/mongo/retryable_spec.rb +147 -0
  224. data/spec/mongo/server/connection_pool/queue_spec.rb +16 -0
  225. data/spec/mongo/server/connection_pool_spec.rb +50 -6
  226. data/spec/mongo/server/connection_spec.rb +49 -4
  227. data/spec/mongo/server/description_spec.rb +49 -3
  228. data/spec/mongo/server/monitor_spec.rb +51 -0
  229. data/spec/mongo/server_discovery_and_monitoring_spec.rb +32 -59
  230. data/spec/mongo/server_selection_rtt_spec.rb +37 -57
  231. data/spec/mongo/server_selection_spec.rb +19 -9
  232. data/spec/mongo/server_selector/nearest_spec.rb +35 -27
  233. data/spec/mongo/server_selector/primary_preferred_spec.rb +32 -30
  234. data/spec/mongo/server_selector/primary_spec.rb +21 -14
  235. data/spec/mongo/server_selector/secondary_preferred_spec.rb +28 -26
  236. data/spec/mongo/server_selector/secondary_spec.rb +24 -22
  237. data/spec/mongo/server_selector_spec.rb +87 -24
  238. data/spec/mongo/server_spec.rb +94 -8
  239. data/spec/mongo/socket/ssl_spec.rb +123 -13
  240. data/spec/mongo/socket/unix_spec.rb +52 -0
  241. data/spec/mongo/uri_spec.rb +295 -67
  242. data/spec/spec_helper.rb +40 -24
  243. data/spec/support/authorization.rb +23 -9
  244. data/spec/support/certificates/client.pem +4 -4
  245. data/spec/support/command_monitoring/bulkWrite.yml +73 -0
  246. data/spec/support/command_monitoring/command.yml +42 -0
  247. data/spec/support/command_monitoring/deleteMany.yml +55 -0
  248. data/spec/support/command_monitoring/deleteOne.yml +55 -0
  249. data/spec/support/command_monitoring/find.yml +219 -0
  250. data/spec/support/command_monitoring/insertMany.yml +81 -0
  251. data/spec/support/command_monitoring/insertOne.yml +51 -0
  252. data/spec/support/command_monitoring/updateMany.yml +67 -0
  253. data/spec/support/command_monitoring/updateOne.yml +95 -0
  254. data/spec/support/command_monitoring.rb +365 -0
  255. data/spec/support/connection_string.rb +228 -0
  256. data/spec/support/connection_string_tests/invalid-uris.yml +193 -0
  257. data/spec/support/connection_string_tests/valid-auth.yml +256 -0
  258. data/spec/support/connection_string_tests/valid-host_identifiers.yml +121 -0
  259. data/spec/support/connection_string_tests/valid-options.yml +30 -0
  260. data/spec/support/connection_string_tests/valid-unix_socket-absolute.yml +197 -0
  261. data/spec/support/connection_string_tests/valid-unix_socket-relative.yml +213 -0
  262. data/spec/support/connection_string_tests/valid-warnings.yml +55 -0
  263. data/spec/support/crud/read.rb +22 -19
  264. data/spec/support/crud/write.rb +58 -27
  265. data/spec/support/crud.rb +10 -2
  266. data/spec/support/gridfs.rb +637 -0
  267. data/spec/support/gridfs_tests/delete.yml +157 -0
  268. data/spec/support/gridfs_tests/download.yml +210 -0
  269. data/spec/support/gridfs_tests/download_by_name.yml +113 -0
  270. data/spec/support/gridfs_tests/upload.yml +158 -0
  271. data/spec/support/matchers.rb +1 -1
  272. data/spec/support/sdam/rs/equal_electionids.yml +44 -0
  273. data/spec/support/sdam/rs/new_primary_new_electionid.yml +95 -0
  274. data/spec/support/sdam/rs/null_election_id.yml +144 -0
  275. data/spec/support/sdam/rs/primary_disconnect_electionid.yml +124 -0
  276. data/spec/support/sdam/rs/primary_mismatched_me.yml +37 -0
  277. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +75 -0
  278. data/spec/support/sdam/rs/secondary_mismatched_me.yml +37 -0
  279. data/spec/support/sdam/sharded/mongos_disconnect.yml +104 -0
  280. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
  281. data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
  282. data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
  283. data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
  284. data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
  285. data/spec/support/sdam/single/not_ok_response.yml +0 -1
  286. data/spec/support/server_discovery_and_monitoring.rb +22 -3
  287. data/spec/support/server_selection.rb +3 -1
  288. data/spec/support/shared/bulk_write.rb +218 -22
  289. data/spec/support/shared/server_selector.rb +80 -14
  290. data.tar.gz.sig +0 -0
  291. metadata +188 -59
  292. metadata.gz.sig +0 -0
  293. data/lib/mongo/bulk_write/bulk_writable.rb +0 -196
  294. data/lib/mongo/bulk_write/deletable.rb +0 -56
  295. data/lib/mongo/bulk_write/insertable.rb +0 -48
  296. data/lib/mongo/bulk_write/replacable.rb +0 -57
  297. data/lib/mongo/bulk_write/updatable.rb +0 -68
  298. data/lib/mongo/grid/fs.rb +0 -149
  299. data/lib/mongo/operation/list_collections/result.rb +0 -114
  300. data/lib/mongo/operation/list_indexes/result.rb +0 -118
  301. data/lib/mongo/operation/read/collections_info.rb +0 -68
  302. data/lib/mongo/operation/read/indexes.rb +0 -69
  303. data/lib/mongo/operation/read/list_collections.rb +0 -76
  304. data/lib/mongo/operation/read/list_indexes.rb +0 -78
  305. data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +0 -75
  306. data/lib/mongo/operation/write/bulk/bulk_delete.rb +0 -145
  307. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +0 -130
  308. data/lib/mongo/operation/write/bulk/bulk_insert.rb +0 -132
  309. data/lib/mongo/operation/write/bulk/bulk_mergable.rb +0 -67
  310. data/lib/mongo/operation/write/bulk/bulk_update/result.rb +0 -162
  311. data/lib/mongo/operation/write/bulk/bulk_update.rb +0 -154
  312. data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +0 -83
  313. data/spec/mongo/bulk/bulk_write_spec.rb +0 -262
  314. data/spec/mongo/grid/fs_spec.rb +0 -160
  315. data/spec/mongo/loggable_spec.rb +0 -63
  316. data/spec/mongo/operation/aggregate_spec.rb +0 -127
  317. /data/lib/mongo/operation/{aggregate → commands/aggregate}/result.rb +0 -0
@@ -2,6 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  describe Mongo::Collection do
4
4
 
5
+ after do
6
+ authorized_collection.delete_many
7
+ end
8
+
9
+ let(:collection_invalid_write_concern) do
10
+ authorized_collection.client.with(write: { w: (WRITE_CONCERN[:w] + 1) })[authorized_collection.name]
11
+ end
12
+
5
13
  describe '#==' do
6
14
 
7
15
  let(:database) do
@@ -82,6 +90,172 @@ describe Mongo::Collection do
82
90
  end
83
91
  end
84
92
 
93
+ describe '#with' do
94
+
95
+ let(:client) do
96
+ Mongo::Client.new(ADDRESSES)
97
+ end
98
+
99
+ let(:database) do
100
+ Mongo::Database.new(client, :test)
101
+ end
102
+
103
+ let(:collection) do
104
+ database.collection(:users)
105
+ end
106
+
107
+ let(:new_collection) do
108
+ collection.with(new_options)
109
+ end
110
+
111
+ context 'when new read options are provided' do
112
+
113
+ let(:new_options) do
114
+ { read: { mode: :secondary } }
115
+ end
116
+
117
+ it 'returns a new collection' do
118
+ expect(new_collection).not_to be(collection)
119
+ end
120
+
121
+ it 'sets the new read options on the new collection' do
122
+ expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
123
+ end
124
+
125
+ context 'when the client has a server selection timeout setting' do
126
+
127
+ let(:client) do
128
+ Mongo::Client.new(ADDRESSES, server_selection_timeout: 2)
129
+ end
130
+
131
+ let(:server_selection_timeout) do
132
+ new_collection.read_preference.server_selection_timeout
133
+ end
134
+
135
+ it 'keeps the server_selection_timeout setting from client' do
136
+ expect(server_selection_timeout).to eq(client.options[:server_selection_timeout])
137
+ end
138
+ end
139
+
140
+ context 'when the client has a read preference set' do
141
+
142
+ let(:client) do
143
+ Mongo::Client.new(ADDRESSES, read: { mode: :primary_preferred })
144
+ end
145
+
146
+ it 'sets the new read options on the new collection' do
147
+ expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
148
+ end
149
+ end
150
+
151
+ context 'when the client has a read preference and server selection timeout set' do
152
+
153
+ let(:client) do
154
+ Mongo::Client.new(ADDRESSES, read: { mode: :primary_preferred }, server_selection_timeout: 2)
155
+ end
156
+
157
+ let(:server_selection_timeout) do
158
+ new_collection.read_preference.server_selection_timeout
159
+ end
160
+
161
+ it 'sets the new read options on the new collection' do
162
+ expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
163
+ end
164
+
165
+ it 'keeps the server_selection_timeout setting from client' do
166
+ expect(server_selection_timeout).to eq(client.options[:server_selection_timeout])
167
+ end
168
+ end
169
+ end
170
+
171
+ context 'when new write options are provided' do
172
+
173
+ let(:new_options) do
174
+ { write: { w: 5 } }
175
+ end
176
+
177
+ it 'returns a new collection' do
178
+ expect(new_collection).not_to be(collection)
179
+ end
180
+
181
+ it 'sets the new write options on the new collection' do
182
+ expect(new_collection.write_concern.options).to eq(Mongo::WriteConcern.get(new_options[:write]).options)
183
+ end
184
+
185
+ context 'when the client has a write concern set' do
186
+
187
+ let(:client) do
188
+ Mongo::Client.new(ADDRESSES, write: { w: 10 })
189
+ end
190
+
191
+ it 'sets the new write options on the new collection' do
192
+ expect(new_collection.write_concern.options).to eq(Mongo::WriteConcern.get(new_options[:write]).options)
193
+ end
194
+ end
195
+ end
196
+
197
+ context 'when new read and write options are provided' do
198
+
199
+ let(:new_options) do
200
+ {
201
+ read: { mode: :secondary },
202
+ write: { w: 4}
203
+ }
204
+ end
205
+
206
+ it 'returns a new collection' do
207
+ expect(new_collection).not_to be(collection)
208
+ end
209
+
210
+ it 'sets the new read options on the new collection' do
211
+ expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
212
+ end
213
+
214
+ it 'sets the new write options on the new collection' do
215
+ expect(new_collection.write_concern.options).to eq(Mongo::WriteConcern.get(new_options[:write]).options)
216
+ end
217
+
218
+ context 'when the client has a server selection timeout setting' do
219
+
220
+ let(:client) do
221
+ Mongo::Client.new(ADDRESSES, server_selection_timeout: 2)
222
+ end
223
+
224
+ let(:server_selection_timeout) do
225
+ new_collection.read_preference.server_selection_timeout
226
+ end
227
+
228
+ it 'keeps the server_selection_timeout setting from client' do
229
+ expect(server_selection_timeout).to eq(client.options[:server_selection_timeout])
230
+ end
231
+ end
232
+
233
+ context 'when the client has a read preference set' do
234
+
235
+ let(:client) do
236
+ Mongo::Client.new(ADDRESSES, read: { mode: :primary_preferred })
237
+ end
238
+
239
+ it 'sets the new read options on the new collection' do
240
+ expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
241
+ end
242
+ end
243
+ end
244
+
245
+ context 'when neither read nor write options are provided' do
246
+
247
+ let(:new_options) do
248
+ { some_option: 'invalid' }
249
+ end
250
+
251
+ it 'raises an error' do
252
+ expect {
253
+ new_collection
254
+ }.to raise_exception(Mongo::Error::UnchangeableCollectionOption)
255
+ end
256
+ end
257
+ end
258
+
85
259
  describe '#capped?' do
86
260
 
87
261
  let(:database) do
@@ -282,7 +456,7 @@ describe Mongo::Collection do
282
456
  end
283
457
 
284
458
  after do
285
- authorized_collection.find.delete_many
459
+ authorized_collection.delete_many
286
460
  end
287
461
 
288
462
  let(:view) do
@@ -295,35 +469,222 @@ describe Mongo::Collection do
295
469
  end
296
470
  end
297
471
  end
472
+
473
+ context 'when the user is not authorized' do
474
+
475
+ let(:view) do
476
+ unauthorized_collection.find
477
+ end
478
+
479
+ it 'iterates over the documents' do
480
+ expect {
481
+ view.each{ |document| document }
482
+ }.to raise_error(Mongo::Error::OperationFailure)
483
+ end
484
+ end
485
+
486
+ context 'when documents contain potential error message fields' do
487
+
488
+ [ Mongo::Error::ERRMSG, Mongo::Error::ERROR, Mongo::Operation::Result::OK ].each do |field|
489
+
490
+ context "when the document contains a '#{field}' field" do
491
+
492
+ let(:value) do
493
+ 'testing'
494
+ end
495
+
496
+ let(:view) do
497
+ authorized_collection.find
498
+ end
499
+
500
+ before do
501
+ authorized_collection.insert_one({ field => value })
502
+ end
503
+
504
+ after do
505
+ authorized_collection.delete_many
506
+ end
507
+
508
+ it 'iterates over the documents' do
509
+ view.each do |document|
510
+ expect(document[field]).to eq(value)
511
+ end
512
+ end
513
+ end
514
+ end
515
+ end
516
+
517
+ context 'when provided options' do
518
+
519
+ let(:view) do
520
+ authorized_collection.find({}, options)
521
+ end
522
+
523
+ context 'when provided :allow_partial_results' do
524
+
525
+ let(:options) do
526
+ { allow_partial_results: true }
527
+ end
528
+
529
+ it 'returns a view with :allow_partial_results set' do
530
+ expect(view.options[:allow_partial_results]).to be(options[:allow_partial_results])
531
+ end
532
+ end
533
+
534
+ context 'when provided :batch_size' do
535
+
536
+ let(:options) do
537
+ { batch_size: 100 }
538
+ end
539
+
540
+ it 'returns a view with :batch_size set' do
541
+ expect(view.options[:batch_size]).to eq(options[:batch_size])
542
+ end
543
+ end
544
+
545
+ context 'when provided :comment' do
546
+
547
+ let(:options) do
548
+ { comment: 'slow query' }
549
+ end
550
+
551
+ it 'returns a view with :comment set' do
552
+ expect(view.modifiers[:$comment]).to eq(options[:comment])
553
+ end
554
+ end
555
+
556
+ context 'when provided :cursor_type' do
557
+
558
+ let(:options) do
559
+ { cursor_type: :tailable }
560
+ end
561
+
562
+ it 'returns a view with :cursor_type set' do
563
+ expect(view.options[:cursor_type]).to eq(options[:cursor_type])
564
+ end
565
+ end
566
+
567
+ #limit
568
+
569
+ context 'when provided :max_time_ms' do
570
+
571
+ let(:options) do
572
+ { max_time_ms: 500 }
573
+ end
574
+
575
+ it 'returns a view with :max_time_ms set' do
576
+ expect(view.modifiers[:$maxTimeMS]).to eq(options[:max_time_ms])
577
+ end
578
+ end
579
+
580
+ context 'when provided :modifiers' do
581
+
582
+ let(:options) do
583
+ { modifiers: { :$orderby => Mongo::Index::ASCENDING } }
584
+ end
585
+
586
+ it 'returns a view with modifiers set' do
587
+ expect(view.modifiers).to eq(options[:modifiers])
588
+ end
589
+
590
+ it 'dups the modifiers hash' do
591
+ expect(view.modifiers).not_to be(options[:modifiers])
592
+ end
593
+ end
594
+
595
+ context 'when provided :no_cursor_timeout' do
596
+
597
+ let(:options) do
598
+ { no_cursor_timeout: true }
599
+ end
600
+
601
+ it 'returns a view with :no_cursor_timeout set' do
602
+ expect(view.options[:no_cursor_timeout]).to eq(options[:no_cursor_timeout])
603
+ end
604
+ end
605
+
606
+ context 'when provided :oplog_replay' do
607
+
608
+ let(:options) do
609
+ { oplog_replay: false }
610
+ end
611
+
612
+ it 'returns a view with :oplog_replay set' do
613
+ expect(view.options[:oplog_replay]).to eq(options[:oplog_replay])
614
+ end
615
+ end
616
+
617
+ context 'when provided :projection' do
618
+
619
+ let(:options) do
620
+ { projection: { 'x' => 1 } }
621
+ end
622
+
623
+ it 'returns a view with :projection set' do
624
+ expect(view.options[:projection]).to eq(options[:projection])
625
+ end
626
+ end
627
+
628
+ context 'when provided :skip' do
629
+
630
+ let(:options) do
631
+ { skip: 5 }
632
+ end
633
+
634
+ it 'returns a view with :skip set' do
635
+ expect(view.options[:skip]).to eq(options[:skip])
636
+ end
637
+ end
638
+
639
+ context 'when provided :sort' do
640
+
641
+ let(:options) do
642
+ { sort: { 'x' => Mongo::Index::ASCENDING } }
643
+ end
644
+
645
+ it 'returns a view with :sort set' do
646
+ expect(view.modifiers[:$orderby]).to eq(options[:sort])
647
+ end
648
+ end
649
+ end
298
650
  end
299
651
 
300
652
  describe '#insert_many' do
301
653
 
302
654
  after do
303
- authorized_collection.find.delete_many
655
+ authorized_collection.delete_many
304
656
  end
305
657
 
306
658
  let(:result) do
307
659
  authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }])
308
660
  end
309
661
 
310
- it 'inserts the documents into the collection', if: write_command_enabled? do
311
- expect(result.written_count).to eq(2)
312
- end
313
-
314
- it 'inserts the documents into the collection', unless: write_command_enabled? do
315
- expect(result.written_count).to eq(0)
662
+ it 'inserts the documents into the collection' do
663
+ expect(result.inserted_count).to eq(2)
316
664
  end
317
665
 
318
666
  it 'contains the ids in the result' do
319
667
  expect(result.inserted_ids.size).to eq(2)
320
668
  end
669
+
670
+ context 'when the inserts fail' do
671
+
672
+ let(:result) do
673
+ authorized_collection.insert_many([{ _id: 1 }, { _id: 1 }])
674
+ end
675
+
676
+ it 'raises an BulkWriteError' do
677
+ expect {
678
+ result
679
+ }.to raise_exception(Mongo::Error::BulkWriteError)
680
+ end
681
+ end
321
682
  end
322
683
 
323
684
  describe '#insert_one' do
324
685
 
325
686
  after do
326
- authorized_collection.find.delete_many
687
+ authorized_collection.delete_many
327
688
  end
328
689
 
329
690
  let(:result) do
@@ -341,6 +702,20 @@ describe Mongo::Collection do
341
702
  it 'contains the id in the result' do
342
703
  expect(result.inserted_id).to_not be_nil
343
704
  end
705
+
706
+ context 'when the insert fails' do
707
+
708
+ let(:result) do
709
+ authorized_collection.insert_one(_id: 1)
710
+ authorized_collection.insert_one(_id: 1)
711
+ end
712
+
713
+ it 'raises an OperationFailure' do
714
+ expect {
715
+ result
716
+ }.to raise_exception(Mongo::Error::OperationFailure)
717
+ end
718
+ end
344
719
  end
345
720
 
346
721
  describe '#inspect' do
@@ -387,4 +762,911 @@ describe Mongo::Collection do
387
762
  end
388
763
  end
389
764
  end
765
+
766
+ describe '#aggregate' do
767
+
768
+ it 'returns an Aggregation object' do
769
+ expect(authorized_collection.aggregate([])).to be_a(Mongo::Collection::View::Aggregation)
770
+ end
771
+
772
+ context 'when options are provided' do
773
+
774
+ let(:options) do
775
+ { :allow_disk_use => true }
776
+ end
777
+
778
+ it 'sets the options on the Aggregation object' do
779
+ expect(authorized_collection.aggregate([], options).options).to eq(options)
780
+ end
781
+ end
782
+ end
783
+
784
+ describe '#count' do
785
+
786
+ let(:documents) do
787
+ (1..10).map{ |i| { field: "test#{i}" }}
788
+ end
789
+
790
+ before do
791
+ authorized_collection.insert_many(documents)
792
+ end
793
+
794
+ after do
795
+ authorized_collection.delete_many
796
+ end
797
+
798
+ it 'returns an integer count' do
799
+ expect(authorized_collection.count).to eq(10)
800
+ end
801
+
802
+ context 'when options are provided' do
803
+
804
+ it 'passes the options to the count' do
805
+ expect(authorized_collection.count({}, limit: 5)).to eq(5)
806
+ end
807
+ end
808
+ end
809
+
810
+ describe '#distinct' do
811
+
812
+ let(:documents) do
813
+ (1..3).map{ |i| { field: "test#{i}" }}
814
+ end
815
+
816
+ before do
817
+ authorized_collection.insert_many(documents)
818
+ end
819
+
820
+ after do
821
+ authorized_collection.delete_many
822
+ end
823
+
824
+ it 'returns the distinct values' do
825
+ expect(authorized_collection.distinct(:field)).to eq([ 'test1', 'test2', 'test3' ])
826
+ end
827
+
828
+ context 'when a selector is provided' do
829
+
830
+ it 'returns the distinct values' do
831
+ expect(authorized_collection.distinct(:field, field: 'test1')).to eq([ 'test1' ])
832
+ end
833
+ end
834
+
835
+ context 'when options are provided' do
836
+
837
+ it 'passes the options to the distinct command' do
838
+ expect(authorized_collection.distinct(:field, {}, max_time_ms: 100)).to eq([ 'test1', 'test2', 'test3' ])
839
+ end
840
+ end
841
+ end
842
+
843
+ describe '#delete_one' do
844
+
845
+ context 'when a selector was provided' do
846
+
847
+ let(:selector) do
848
+ { field: 'test1' }
849
+ end
850
+
851
+ before do
852
+ authorized_collection.insert_many([
853
+ { field: 'test1' },
854
+ { field: 'test1' },
855
+ { field: 'test1' }
856
+ ])
857
+ end
858
+
859
+ after do
860
+ authorized_collection.delete_many
861
+ end
862
+
863
+ let(:response) do
864
+ authorized_collection.delete_one(selector)
865
+ end
866
+
867
+ it 'deletes the first matching document in the collection' do
868
+ expect(response.deleted_count).to eq(1)
869
+ end
870
+ end
871
+
872
+ context 'when no selector was provided' do
873
+
874
+ before do
875
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test2' }])
876
+ end
877
+
878
+ let(:response) do
879
+ authorized_collection.delete_one
880
+ end
881
+
882
+ it 'deletes the first document in the collection' do
883
+ expect(response.deleted_count).to eq(1)
884
+ end
885
+ end
886
+
887
+ context 'when the delete fails', if: standalone? do
888
+
889
+ let(:result) do
890
+ collection_invalid_write_concern.delete_one
891
+ end
892
+
893
+ it 'raises an OperationFailure' do
894
+ expect {
895
+ result
896
+ }.to raise_exception(Mongo::Error::OperationFailure)
897
+ end
898
+ end
899
+ end
900
+
901
+ describe '#delete_many' do
902
+
903
+ before do
904
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test2' }])
905
+ end
906
+
907
+ after do
908
+ authorized_collection.delete_many
909
+ end
910
+
911
+ context 'when a selector was provided' do
912
+
913
+ let(:selector) do
914
+ { field: 'test1' }
915
+ end
916
+
917
+ it 'deletes the matching documents in the collection' do
918
+ expect(authorized_collection.delete_many(selector).deleted_count).to eq(1)
919
+ end
920
+ end
921
+
922
+ context 'when no selector was provided' do
923
+
924
+ it 'deletes all the documents in the collection' do
925
+ expect(authorized_collection.delete_many.deleted_count).to eq(2)
926
+ end
927
+ end
928
+
929
+ context 'when the deletes fail', if: standalone? do
930
+
931
+ let(:result) do
932
+ collection_invalid_write_concern.delete_many
933
+ end
934
+
935
+ it 'raises an OperationFailure' do
936
+ expect {
937
+ result
938
+ }.to raise_exception(Mongo::Error::OperationFailure)
939
+ end
940
+ end
941
+ end
942
+
943
+ describe '#parallel_scan', unless: sharded? do
944
+
945
+ let(:documents) do
946
+ (1..200).map do |i|
947
+ { name: "testing-scan-#{i}" }
948
+ end
949
+ end
950
+
951
+ before do
952
+ authorized_collection.insert_many(documents)
953
+ end
954
+
955
+ let(:cursors) do
956
+ authorized_collection.parallel_scan(2)
957
+ end
958
+
959
+ it 'returns an array of cursors', if: write_command_enabled? do
960
+ cursors.each do |cursor|
961
+ expect(cursor.class).to be(Mongo::Cursor)
962
+ end
963
+ end
964
+
965
+ it 'returns the correct number of documents', if: write_command_enabled? do
966
+ expect(
967
+ cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
968
+ ).to eq(200)
969
+ end
970
+
971
+ it 'raises an error', unless: write_command_enabled? do
972
+ expect {
973
+ cursors
974
+ }.to raise_error(Mongo::Error::OperationFailure)
975
+ end
976
+ end
977
+
978
+ describe '#replace_one' do
979
+
980
+ let(:selector) do
981
+ { field: 'test1' }
982
+ end
983
+
984
+ context 'when a selector was provided' do
985
+
986
+ before do
987
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test1' }])
988
+ end
989
+
990
+ after do
991
+ authorized_collection.delete_many
992
+ end
993
+
994
+ let!(:response) do
995
+ authorized_collection.replace_one(selector, { field: 'testing' })
996
+ end
997
+
998
+ let(:updated) do
999
+ authorized_collection.find(field: 'testing').first
1000
+ end
1001
+
1002
+ it 'updates the first matching document in the collection' do
1003
+ expect(response.modified_count).to eq(1)
1004
+ end
1005
+
1006
+ it 'updates the documents in the collection' do
1007
+ expect(updated[:field]).to eq('testing')
1008
+ end
1009
+ end
1010
+
1011
+ context 'when upsert is false' do
1012
+
1013
+ let!(:response) do
1014
+ authorized_collection.replace_one(selector, { field: 'test1' }, upsert: false)
1015
+ end
1016
+
1017
+ let(:updated) do
1018
+ authorized_collection.find(field: 'test1').to_a
1019
+ end
1020
+
1021
+ it 'reports that no documents were written' do
1022
+ expect(response.modified_count).to eq(0)
1023
+ end
1024
+
1025
+ it 'does not insert the document' do
1026
+ expect(updated).to be_empty
1027
+ end
1028
+ end
1029
+
1030
+ context 'when upsert is true' do
1031
+
1032
+ let!(:response) do
1033
+ authorized_collection.replace_one(selector, { field: 'test1' }, upsert: true)
1034
+ end
1035
+
1036
+ let(:updated) do
1037
+ authorized_collection.find(field: 'test1').first
1038
+ end
1039
+
1040
+ after do
1041
+ authorized_collection.delete_many
1042
+ end
1043
+
1044
+ it 'reports that a document was written' do
1045
+ expect(response.written_count).to eq(1)
1046
+ end
1047
+
1048
+ it 'inserts the document' do
1049
+ expect(updated[:field]).to eq('test1')
1050
+ end
1051
+ end
1052
+
1053
+ context 'when upsert is not specified' do
1054
+
1055
+ let!(:response) do
1056
+ authorized_collection.replace_one(selector, { field: 'test1' })
1057
+ end
1058
+
1059
+ let(:updated) do
1060
+ authorized_collection.find(field: 'test1').to_a
1061
+ end
1062
+
1063
+ it 'reports that no documents were written' do
1064
+ expect(response.modified_count).to eq(0)
1065
+ end
1066
+
1067
+ it 'does not insert the document' do
1068
+ expect(updated).to be_empty
1069
+ end
1070
+ end
1071
+
1072
+ context 'when the replace fails' do
1073
+
1074
+ let(:result) do
1075
+ authorized_collection.replace_one(selector, { '$s' => 'test1' })
1076
+ end
1077
+
1078
+ it 'raises an OperationFailure' do
1079
+ expect {
1080
+ result
1081
+ }.to raise_exception(Mongo::Error::OperationFailure)
1082
+ end
1083
+ end
1084
+ end
1085
+
1086
+ describe '#update_many' do
1087
+
1088
+ let(:selector) do
1089
+ { field: 'test' }
1090
+ end
1091
+
1092
+ after do
1093
+ authorized_collection.delete_many
1094
+ end
1095
+
1096
+ context 'when a selector was provided' do
1097
+
1098
+ before do
1099
+ authorized_collection.insert_many([{ field: 'test' }, { field: 'test' }])
1100
+ end
1101
+
1102
+ let!(:response) do
1103
+ authorized_collection.update_many(selector, '$set'=> { field: 'testing' })
1104
+ end
1105
+
1106
+ let(:updated) do
1107
+ authorized_collection.find(field: 'testing').to_a.last
1108
+ end
1109
+
1110
+ it 'returns the number updated' do
1111
+ expect(response.modified_count).to eq(2)
1112
+ end
1113
+
1114
+ it 'updates the documents in the collection' do
1115
+ expect(updated[:field]).to eq('testing')
1116
+ end
1117
+ end
1118
+
1119
+ context 'when upsert is false' do
1120
+
1121
+ let(:response) do
1122
+ authorized_collection.update_many(selector, { '$set'=> { field: 'testing' } },
1123
+ upsert: false)
1124
+ end
1125
+
1126
+ let(:updated) do
1127
+ authorized_collection.find.to_a
1128
+ end
1129
+
1130
+ it 'reports that no documents were updated' do
1131
+ expect(response.modified_count).to eq(0)
1132
+ end
1133
+
1134
+ it 'updates no documents in the collection' do
1135
+ expect(updated).to be_empty
1136
+ end
1137
+ end
1138
+
1139
+ context 'when upsert is true' do
1140
+
1141
+ let!(:response) do
1142
+ authorized_collection.update_many(selector, { '$set'=> { field: 'testing' } },
1143
+ upsert: true)
1144
+ end
1145
+
1146
+ let(:updated) do
1147
+ authorized_collection.find.to_a.last
1148
+ end
1149
+
1150
+ it 'reports that a document was written' do
1151
+ expect(response.written_count).to eq(1)
1152
+ end
1153
+
1154
+ it 'inserts a document into the collection' do
1155
+ expect(updated[:field]).to eq('testing')
1156
+ end
1157
+ end
1158
+
1159
+ context 'when upsert is not specified' do
1160
+
1161
+ let(:response) do
1162
+ authorized_collection.update_many(selector, { '$set'=> { field: 'testing' } })
1163
+ end
1164
+
1165
+ let(:updated) do
1166
+ authorized_collection.find.to_a
1167
+ end
1168
+
1169
+ it 'reports that no documents were updated' do
1170
+ expect(response.modified_count).to eq(0)
1171
+ end
1172
+
1173
+ it 'updates no documents in the collection' do
1174
+ expect(updated).to be_empty
1175
+ end
1176
+ end
1177
+
1178
+ context 'when the updates fail' do
1179
+
1180
+ let(:result) do
1181
+ authorized_collection.update_many(selector, { '$s'=> { field: 'testing' } })
1182
+ end
1183
+
1184
+ it 'raises an OperationFailure' do
1185
+ expect {
1186
+ result
1187
+ }.to raise_exception(Mongo::Error::OperationFailure)
1188
+ end
1189
+ end
1190
+ end
1191
+
1192
+ describe '#update_one' do
1193
+
1194
+ let(:selector) do
1195
+ { field: 'test1' }
1196
+ end
1197
+
1198
+ context 'when a selector was provided' do
1199
+
1200
+ before do
1201
+ authorized_collection.insert_many([{ field: 'test1' }, { field: 'test1' }])
1202
+ end
1203
+
1204
+ let!(:response) do
1205
+ authorized_collection.update_one(selector, '$set'=> { field: 'testing' })
1206
+ end
1207
+
1208
+ let(:updated) do
1209
+ authorized_collection.find(field: 'testing').first
1210
+ end
1211
+
1212
+ it 'updates the first matching document in the collection' do
1213
+ expect(response.modified_count).to eq(1)
1214
+ end
1215
+
1216
+ it 'updates the documents in the collection' do
1217
+ expect(updated[:field]).to eq('testing')
1218
+ end
1219
+ end
1220
+
1221
+ context 'when upsert is false' do
1222
+
1223
+ let(:response) do
1224
+ authorized_collection.update_one(selector, { '$set'=> { field: 'testing' } },
1225
+ upsert: false)
1226
+ end
1227
+
1228
+ let(:updated) do
1229
+ authorized_collection.find.to_a
1230
+ end
1231
+
1232
+ it 'reports that no documents were updated' do
1233
+ expect(response.modified_count).to eq(0)
1234
+ end
1235
+
1236
+ it 'updates no documents in the collection' do
1237
+ expect(updated).to be_empty
1238
+ end
1239
+ end
1240
+
1241
+ context 'when upsert is true' do
1242
+
1243
+ let!(:response) do
1244
+ authorized_collection.update_one(selector, { '$set'=> { field: 'testing' } },
1245
+ upsert: true)
1246
+ end
1247
+
1248
+ let(:updated) do
1249
+ authorized_collection.find.first
1250
+ end
1251
+
1252
+ it 'reports that a document was written' do
1253
+ expect(response.written_count).to eq(1)
1254
+ end
1255
+
1256
+ it 'inserts a document into the collection' do
1257
+ expect(updated[:field]).to eq('testing')
1258
+ end
1259
+ end
1260
+
1261
+ context 'when upsert is not specified' do
1262
+
1263
+ let(:response) do
1264
+ authorized_collection.update_one(selector, { '$set'=> { field: 'testing' } })
1265
+ end
1266
+
1267
+ let(:updated) do
1268
+ authorized_collection.find.to_a
1269
+ end
1270
+
1271
+ it 'reports that no documents were updated' do
1272
+ expect(response.modified_count).to eq(0)
1273
+ end
1274
+
1275
+ it 'updates no documents in the collection' do
1276
+ expect(updated).to be_empty
1277
+ end
1278
+ end
1279
+
1280
+ context 'when the update fails' do
1281
+
1282
+ let(:result) do
1283
+ authorized_collection.update_one(selector, { '$s'=> { field: 'testing' } })
1284
+ end
1285
+
1286
+ it 'raises an OperationFailure' do
1287
+ expect {
1288
+ result
1289
+ }.to raise_exception(Mongo::Error::OperationFailure)
1290
+ end
1291
+ end
1292
+ end
1293
+
1294
+ describe '#find_one_and_delete' do
1295
+
1296
+ before do
1297
+ authorized_collection.insert_many([{ field: 'test1' }])
1298
+ end
1299
+
1300
+ let(:selector) do
1301
+ { field: 'test1' }
1302
+ end
1303
+
1304
+ context 'when a matching document is found' do
1305
+
1306
+ context 'when no options are provided' do
1307
+
1308
+ let!(:document) do
1309
+ authorized_collection.find_one_and_delete(selector)
1310
+ end
1311
+
1312
+ it 'deletes the document from the database' do
1313
+ expect(authorized_collection.find.to_a).to be_empty
1314
+ end
1315
+
1316
+ it 'returns the document' do
1317
+ expect(document['field']).to eq('test1')
1318
+ end
1319
+ end
1320
+
1321
+ context 'when a projection is provided' do
1322
+
1323
+ let!(:document) do
1324
+ authorized_collection.find_one_and_delete(selector, projection: { _id: 1 })
1325
+ end
1326
+
1327
+ it 'deletes the document from the database' do
1328
+ expect(authorized_collection.find.to_a).to be_empty
1329
+ end
1330
+
1331
+ it 'returns the document with limited fields' do
1332
+ expect(document['field']).to be_nil
1333
+ expect(document['_id']).to_not be_nil
1334
+ end
1335
+ end
1336
+
1337
+ context 'when a sort is provided' do
1338
+
1339
+ let!(:document) do
1340
+ authorized_collection.find_one_and_delete(selector, sort: { field: 1 })
1341
+ end
1342
+
1343
+ it 'deletes the document from the database' do
1344
+ expect(authorized_collection.find.to_a).to be_empty
1345
+ end
1346
+
1347
+ it 'returns the document with limited fields' do
1348
+ expect(document['field']).to eq('test1')
1349
+ end
1350
+ end
1351
+
1352
+ context 'when max_time_ms is provided', if: write_command_enabled? do
1353
+
1354
+ it 'includes the max_time_ms value in the command' do
1355
+ expect {
1356
+ authorized_collection.find_one_and_delete(selector, max_time_ms: 0.1)
1357
+ }.to raise_error(Mongo::Error::OperationFailure)
1358
+ end
1359
+ end
1360
+ end
1361
+
1362
+ context 'when no matching document is found' do
1363
+
1364
+ let(:selector) do
1365
+ { field: 'test5' }
1366
+ end
1367
+
1368
+ let!(:document) do
1369
+ authorized_collection.find_one_and_delete(selector)
1370
+ end
1371
+
1372
+ it 'returns nil' do
1373
+ expect(document).to be_nil
1374
+ end
1375
+ end
1376
+
1377
+ context 'when the operation fails', if: write_command_enabled? do
1378
+
1379
+ let(:result) do
1380
+ authorized_collection.find_one_and_delete(selector, max_time_ms: 0.1)
1381
+ end
1382
+
1383
+ it 'raises an OperationFailure' do
1384
+ expect {
1385
+ result
1386
+ }.to raise_exception(Mongo::Error::OperationFailure)
1387
+ end
1388
+ end
1389
+ end
1390
+
1391
+ describe '#find_one_and_update' do
1392
+
1393
+ let(:selector) do
1394
+ { field: 'test1' }
1395
+ end
1396
+
1397
+ before do
1398
+ authorized_collection.insert_many([{ field: 'test1' }])
1399
+ end
1400
+
1401
+ context 'when a matching document is found' do
1402
+
1403
+ context 'when no options are provided' do
1404
+
1405
+ let(:document) do
1406
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }})
1407
+ end
1408
+
1409
+ it 'returns the original document' do
1410
+ expect(document['field']).to eq('test1')
1411
+ end
1412
+ end
1413
+
1414
+ context 'when no options are provided' do
1415
+
1416
+ let(:document) do
1417
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }})
1418
+ end
1419
+
1420
+ it 'returns the original document' do
1421
+ expect(document['field']).to eq('test1')
1422
+ end
1423
+ end
1424
+
1425
+ context 'when return_document options are provided' do
1426
+
1427
+ context 'when return_document is :after' do
1428
+
1429
+ let(:document) do
1430
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, :return_document => :after)
1431
+ end
1432
+
1433
+ it 'returns the new document' do
1434
+ expect(document['field']).to eq('testing')
1435
+ end
1436
+ end
1437
+
1438
+ context 'when return_document is :before' do
1439
+
1440
+ let(:document) do
1441
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, :return_document => :before)
1442
+ end
1443
+
1444
+ it 'returns the original document' do
1445
+ expect(document['field']).to eq('test1')
1446
+ end
1447
+ end
1448
+ end
1449
+
1450
+ context 'when a projection is provided' do
1451
+
1452
+ let(:document) do
1453
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, projection: { _id: 1 })
1454
+ end
1455
+
1456
+ it 'returns the document with limited fields' do
1457
+ expect(document['field']).to be_nil
1458
+ expect(document['_id']).to_not be_nil
1459
+ end
1460
+ end
1461
+
1462
+ context 'when a sort is provided' do
1463
+
1464
+ let(:document) do
1465
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, sort: { field: 1 })
1466
+ end
1467
+
1468
+ it 'returns the original document' do
1469
+ expect(document['field']).to eq('test1')
1470
+ end
1471
+ end
1472
+ end
1473
+
1474
+ context 'when max_time_ms is provided' do
1475
+
1476
+ it 'includes the max_time_ms value in the command', if: write_command_enabled? do
1477
+ expect {
1478
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, max_time_ms: 0.1)
1479
+ }.to raise_error(Mongo::Error::OperationFailure)
1480
+ end
1481
+ end
1482
+
1483
+ context 'when no matching document is found' do
1484
+
1485
+ let(:selector) do
1486
+ { field: 'test5' }
1487
+ end
1488
+
1489
+ let(:document) do
1490
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }})
1491
+ end
1492
+
1493
+ it 'returns nil' do
1494
+ expect(document).to be_nil
1495
+ end
1496
+ end
1497
+
1498
+ context 'when no matching document is found' do
1499
+
1500
+ context 'when no upsert options are provided' do
1501
+
1502
+ let(:selector) do
1503
+ { field: 'test5' }
1504
+ end
1505
+
1506
+ let(:document) do
1507
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }})
1508
+ end
1509
+
1510
+ it 'returns nil' do
1511
+ expect(document).to be_nil
1512
+ end
1513
+ end
1514
+
1515
+ context 'when upsert options are provided' do
1516
+
1517
+ let(:selector) do
1518
+ { field: 'test5' }
1519
+ end
1520
+
1521
+ let(:document) do
1522
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, :upsert => true, :return_document => :after)
1523
+ end
1524
+
1525
+ it 'returns the new document' do
1526
+ expect(document['field']).to eq('testing')
1527
+ end
1528
+ end
1529
+ end
1530
+
1531
+ context 'when the operation fails', if: write_command_enabled? do
1532
+
1533
+ let(:result) do
1534
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, max_time_ms: 0.1)
1535
+ end
1536
+
1537
+ it 'raises an OperationFailure' do
1538
+ expect {
1539
+ result
1540
+ }.to raise_exception(Mongo::Error::OperationFailure)
1541
+ end
1542
+ end
1543
+ end
1544
+
1545
+ describe '#find_one_and_replace' do
1546
+
1547
+ before do
1548
+ authorized_collection.insert_many([{ field: 'test1', other: 'sth' }])
1549
+ end
1550
+
1551
+ let(:selector) do
1552
+ { field: 'test1' }
1553
+ end
1554
+
1555
+ context 'when a matching document is found' do
1556
+
1557
+ context 'when no options are provided' do
1558
+
1559
+ let(:document) do
1560
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' })
1561
+ end
1562
+
1563
+ it 'returns the original document' do
1564
+ expect(document['field']).to eq('test1')
1565
+ end
1566
+ end
1567
+
1568
+ context 'when return_document options are provided' do
1569
+
1570
+ context 'when return_document is :after' do
1571
+
1572
+ let(:document) do
1573
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, :return_document => :after)
1574
+ end
1575
+
1576
+ it 'returns the new document' do
1577
+ expect(document['field']).to eq('testing')
1578
+ end
1579
+ end
1580
+
1581
+ context 'when return_document is :before' do
1582
+
1583
+ let(:document) do
1584
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, :return_document => :before)
1585
+ end
1586
+
1587
+ it 'returns the original document' do
1588
+ expect(document['field']).to eq('test1')
1589
+ end
1590
+ end
1591
+ end
1592
+
1593
+ context 'when a projection is provided' do
1594
+
1595
+ let(:document) do
1596
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, projection: { _id: 1 })
1597
+ end
1598
+
1599
+ it 'returns the document with limited fields' do
1600
+ expect(document['field']).to be_nil
1601
+ expect(document['_id']).to_not be_nil
1602
+ end
1603
+ end
1604
+
1605
+ context 'when a sort is provided' do
1606
+
1607
+ let(:document) do
1608
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, :sort => { field: 1 })
1609
+ end
1610
+
1611
+ it 'returns the original document' do
1612
+ expect(document['field']).to eq('test1')
1613
+ end
1614
+ end
1615
+ end
1616
+
1617
+ context 'when no matching document is found' do
1618
+
1619
+ context 'when no upsert options are provided' do
1620
+
1621
+ let(:selector) do
1622
+ { field: 'test5' }
1623
+ end
1624
+
1625
+ let(:document) do
1626
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' })
1627
+ end
1628
+
1629
+ it 'returns nil' do
1630
+ expect(document).to be_nil
1631
+ end
1632
+ end
1633
+
1634
+ context 'when upsert options are provided' do
1635
+
1636
+ let(:selector) do
1637
+ { field: 'test5' }
1638
+ end
1639
+
1640
+ let(:document) do
1641
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, :upsert => true, :return_document => :after)
1642
+ end
1643
+
1644
+ it 'returns the new document' do
1645
+ expect(document['field']).to eq('testing')
1646
+ end
1647
+ end
1648
+ end
1649
+
1650
+ context 'when max_time_ms is provided', if: write_command_enabled? do
1651
+
1652
+ it 'includes the max_time_ms value in the command' do
1653
+ expect {
1654
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, max_time_ms: 0.1)
1655
+ }.to raise_error(Mongo::Error::OperationFailure)
1656
+ end
1657
+ end
1658
+
1659
+ context 'when the operation fails', if: write_command_enabled? do
1660
+
1661
+ let(:result) do
1662
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, max_time_ms: 0.1)
1663
+ end
1664
+
1665
+ it 'raises an OperationFailure' do
1666
+ expect {
1667
+ result
1668
+ }.to raise_exception(Mongo::Error::OperationFailure)
1669
+ end
1670
+ end
1671
+ end
390
1672
  end