mongoid 7.6.1 → 8.0.1

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 (314) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -0
  3. data/README.md +3 -3
  4. data/Rakefile +21 -85
  5. data/lib/config/locales/en.yml +46 -30
  6. data/lib/mongoid/association/accessors.rb +32 -3
  7. data/lib/mongoid/association/bindable.rb +48 -0
  8. data/lib/mongoid/association/builders.rb +4 -2
  9. data/lib/mongoid/association/eager_loadable.rb +29 -7
  10. data/lib/mongoid/association/embedded/batchable.rb +28 -5
  11. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  12. data/lib/mongoid/association/embedded/embedded_in.rb +2 -1
  13. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  14. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  15. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +40 -18
  16. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  17. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +21 -2
  18. data/lib/mongoid/association/macros.rb +2 -1
  19. data/lib/mongoid/association/many.rb +5 -0
  20. data/lib/mongoid/association/nested/many.rb +2 -1
  21. data/lib/mongoid/association/proxy.rb +12 -0
  22. data/lib/mongoid/association/referenced/auto_save.rb +3 -2
  23. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  24. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  25. data/lib/mongoid/association/referenced/belongs_to.rb +1 -1
  26. data/lib/mongoid/association/referenced/counter_cache.rb +8 -8
  27. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +64 -11
  28. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +4 -1
  29. data/lib/mongoid/association/referenced/has_many/enumerable.rb +10 -18
  30. data/lib/mongoid/association/referenced/has_many/proxy.rb +12 -9
  31. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  32. data/lib/mongoid/association/referenced/has_one/proxy.rb +8 -11
  33. data/lib/mongoid/association/referenced/syncable.rb +2 -2
  34. data/lib/mongoid/association/relatable.rb +38 -4
  35. data/lib/mongoid/attributes/processing.rb +9 -2
  36. data/lib/mongoid/attributes.rb +30 -27
  37. data/lib/mongoid/cacheable.rb +2 -2
  38. data/lib/mongoid/changeable.rb +37 -2
  39. data/lib/mongoid/clients/factory.rb +0 -4
  40. data/lib/mongoid/clients/options.rb +4 -0
  41. data/lib/mongoid/clients/sessions.rb +2 -14
  42. data/lib/mongoid/config.rb +15 -11
  43. data/lib/mongoid/contextual/aggregable/memory.rb +23 -15
  44. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  45. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  46. data/lib/mongoid/contextual/memory.rb +55 -28
  47. data/lib/mongoid/contextual/mongo.rb +173 -287
  48. data/lib/mongoid/contextual/none.rb +33 -15
  49. data/lib/mongoid/copyable.rb +32 -8
  50. data/lib/mongoid/criteria/includable.rb +24 -20
  51. data/lib/mongoid/criteria/marshalable.rb +10 -2
  52. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -15
  53. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  54. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  55. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  56. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  57. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -16
  58. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  59. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  60. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  61. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +1 -1
  62. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
  63. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  64. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  65. data/lib/mongoid/criteria/queryable/optional.rb +3 -9
  66. data/lib/mongoid/criteria/queryable/options.rb +1 -1
  67. data/lib/mongoid/criteria/queryable/selectable.rb +2 -24
  68. data/lib/mongoid/criteria/queryable/selector.rb +90 -5
  69. data/lib/mongoid/criteria/queryable/smash.rb +39 -6
  70. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  71. data/lib/mongoid/criteria/queryable.rb +11 -6
  72. data/lib/mongoid/criteria.rb +1 -28
  73. data/lib/mongoid/deprecable.rb +36 -0
  74. data/lib/mongoid/deprecation.rb +25 -0
  75. data/lib/mongoid/document.rb +88 -33
  76. data/lib/mongoid/equality.rb +4 -4
  77. data/lib/mongoid/errors/document_not_found.rb +6 -2
  78. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  79. data/lib/mongoid/errors/invalid_field.rb +5 -1
  80. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  81. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  82. data/lib/mongoid/errors.rb +2 -2
  83. data/lib/mongoid/extensions/array.rb +8 -6
  84. data/lib/mongoid/extensions/big_decimal.rb +29 -10
  85. data/lib/mongoid/extensions/binary.rb +42 -0
  86. data/lib/mongoid/extensions/boolean.rb +8 -2
  87. data/lib/mongoid/extensions/date.rb +26 -20
  88. data/lib/mongoid/extensions/date_time.rb +1 -1
  89. data/lib/mongoid/extensions/float.rb +4 -5
  90. data/lib/mongoid/extensions/hash.rb +13 -32
  91. data/lib/mongoid/extensions/integer.rb +4 -5
  92. data/lib/mongoid/extensions/object.rb +2 -0
  93. data/lib/mongoid/extensions/range.rb +41 -10
  94. data/lib/mongoid/extensions/regexp.rb +11 -4
  95. data/lib/mongoid/extensions/set.rb +11 -4
  96. data/lib/mongoid/extensions/string.rb +2 -13
  97. data/lib/mongoid/extensions/symbol.rb +3 -14
  98. data/lib/mongoid/extensions/time.rb +27 -16
  99. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  100. data/lib/mongoid/extensions.rb +1 -0
  101. data/lib/mongoid/factory.rb +42 -7
  102. data/lib/mongoid/fields/foreign_key.rb +7 -0
  103. data/lib/mongoid/fields/validators/macro.rb +3 -9
  104. data/lib/mongoid/fields.rb +49 -7
  105. data/lib/mongoid/findable.rb +21 -16
  106. data/lib/mongoid/indexable/specification.rb +1 -1
  107. data/lib/mongoid/indexable/validators/options.rb +4 -1
  108. data/lib/mongoid/interceptable.rb +69 -9
  109. data/lib/mongoid/persistable/creatable.rb +14 -5
  110. data/lib/mongoid/persistable/updatable.rb +12 -5
  111. data/lib/mongoid/persistence_context.rb +8 -42
  112. data/lib/mongoid/query_cache.rb +6 -258
  113. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  114. data/lib/mongoid/reloadable.rb +7 -3
  115. data/lib/mongoid/scopable.rb +9 -11
  116. data/lib/mongoid/selectable.rb +1 -2
  117. data/lib/mongoid/shardable.rb +11 -35
  118. data/lib/mongoid/stateful.rb +27 -1
  119. data/lib/mongoid/timestamps/created.rb +1 -1
  120. data/lib/mongoid/timestamps/updated.rb +1 -1
  121. data/lib/mongoid/touchable.rb +2 -3
  122. data/lib/mongoid/traversable.rb +1 -0
  123. data/lib/mongoid/validatable/uniqueness.rb +2 -1
  124. data/lib/mongoid/version.rb +1 -5
  125. data/lib/mongoid/warnings.rb +3 -4
  126. data/lib/mongoid.rb +1 -0
  127. data/spec/config/mongoid.yml +16 -0
  128. data/spec/integration/app_spec.rb +8 -12
  129. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  130. data/spec/integration/associations/embedded_spec.rb +15 -0
  131. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  132. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  133. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  134. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  135. data/spec/integration/associations/has_one_spec.rb +97 -1
  136. data/spec/integration/associations/scope_option_spec.rb +1 -1
  137. data/spec/integration/callbacks_models.rb +95 -1
  138. data/spec/integration/callbacks_spec.rb +226 -4
  139. data/spec/integration/criteria/range_spec.rb +95 -1
  140. data/spec/integration/discriminator_key_spec.rb +115 -76
  141. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  142. data/spec/integration/i18n_fallbacks_spec.rb +1 -15
  143. data/spec/integration/matcher_examples_spec.rb +20 -13
  144. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  145. data/spec/integration/matcher_operator_spec.rb +3 -5
  146. data/spec/integration/persistence/range_field_spec.rb +350 -0
  147. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  148. data/spec/mongoid/association/depending_spec.rb +9 -9
  149. data/spec/mongoid/association/eager_spec.rb +2 -1
  150. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  151. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  152. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  153. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  154. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +198 -8
  155. data/spec/mongoid/association/embedded/embeds_many_models.rb +36 -0
  156. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  157. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  158. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  159. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  160. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  161. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  162. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  163. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  164. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  165. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  166. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +38 -5
  167. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  168. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  169. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  170. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  171. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +62 -13
  172. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  173. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  174. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  175. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  176. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  177. data/spec/mongoid/association/syncable_spec.rb +14 -0
  178. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  179. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  180. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  181. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  182. data/spec/mongoid/attributes_spec.rb +480 -27
  183. data/spec/mongoid/cacheable_spec.rb +3 -3
  184. data/spec/mongoid/changeable_spec.rb +130 -13
  185. data/spec/mongoid/clients/factory_spec.rb +22 -60
  186. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  187. data/spec/mongoid/clients_spec.rb +2 -2
  188. data/spec/mongoid/config_spec.rb +52 -15
  189. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  190. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  191. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  192. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  193. data/spec/mongoid/contextual/memory_spec.rb +521 -14
  194. data/spec/mongoid/contextual/mongo_spec.rb +566 -426
  195. data/spec/mongoid/contextual/none_spec.rb +11 -19
  196. data/spec/mongoid/copyable_spec.rb +451 -2
  197. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  198. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  199. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  200. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  201. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  202. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  203. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +1 -2
  204. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  205. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  206. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +1 -2
  207. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  208. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  209. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  210. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  211. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  212. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  213. data/spec/mongoid/criteria/queryable/selectable_spec.rb +77 -85
  214. data/spec/mongoid/criteria/queryable/selector_spec.rb +16 -77
  215. data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
  216. data/spec/mongoid/criteria_spec.rb +469 -1201
  217. data/spec/mongoid/document_fields_spec.rb +173 -24
  218. data/spec/mongoid/document_spec.rb +32 -41
  219. data/spec/mongoid/equality_spec.rb +12 -12
  220. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  221. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  222. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  223. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  224. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  225. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  226. data/spec/mongoid/extensions/array_spec.rb +16 -2
  227. data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
  228. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  229. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  230. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  231. data/spec/mongoid/extensions/date_spec.rb +71 -1
  232. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  233. data/spec/mongoid/extensions/float_spec.rb +48 -76
  234. data/spec/mongoid/extensions/hash_spec.rb +30 -236
  235. data/spec/mongoid/extensions/integer_spec.rb +45 -66
  236. data/spec/mongoid/extensions/range_spec.rb +255 -54
  237. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  238. data/spec/mongoid/extensions/set_spec.rb +106 -0
  239. data/spec/mongoid/extensions/string_spec.rb +53 -25
  240. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  241. data/spec/mongoid/extensions/time_spec.rb +634 -66
  242. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  243. data/spec/mongoid/factory_spec.rb +61 -1
  244. data/spec/mongoid/fields_spec.rb +321 -50
  245. data/spec/mongoid/findable_spec.rb +64 -29
  246. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  247. data/spec/mongoid/indexable_spec.rb +16 -19
  248. data/spec/mongoid/interceptable_spec.rb +584 -5
  249. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  250. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  251. data/spec/mongoid/mongoizable_spec.rb +285 -0
  252. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  253. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  254. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  255. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  256. data/spec/mongoid/persistence_context_spec.rb +24 -0
  257. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  258. data/spec/mongoid/query_cache_spec.rb +1 -156
  259. data/spec/mongoid/reloadable_spec.rb +35 -2
  260. data/spec/mongoid/scopable_spec.rb +36 -34
  261. data/spec/mongoid/serializable_spec.rb +14 -7
  262. data/spec/mongoid/shardable_models.rb +0 -14
  263. data/spec/mongoid/shardable_spec.rb +61 -153
  264. data/spec/mongoid/stateful_spec.rb +28 -0
  265. data/spec/mongoid/timestamps_spec.rb +390 -0
  266. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  267. data/spec/mongoid/touchable_spec.rb +116 -0
  268. data/spec/mongoid/touchable_spec_models.rb +12 -8
  269. data/spec/mongoid/traversable_spec.rb +4 -11
  270. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  271. data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
  272. data/spec/mongoid/warnings_spec.rb +35 -0
  273. data/spec/mongoid_spec.rb +1 -7
  274. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  275. data/spec/rails/mongoid_spec.rb +4 -16
  276. data/spec/shared/lib/mrss/docker_runner.rb +1 -8
  277. data/spec/shared/lib/mrss/event_subscriber.rb +5 -15
  278. data/spec/shared/lib/mrss/lite_constraints.rb +2 -10
  279. data/spec/shared/lib/mrss/server_version_registry.rb +24 -17
  280. data/spec/shared/lib/mrss/spec_organizer.rb +3 -32
  281. data/spec/shared/lib/mrss/utils.rb +6 -28
  282. data/spec/shared/share/Dockerfile.erb +107 -33
  283. data/spec/shared/shlib/distro.sh +0 -10
  284. data/spec/shared/shlib/server.sh +33 -64
  285. data/spec/shared/shlib/set_env.sh +71 -12
  286. data/spec/support/constraints.rb +24 -0
  287. data/spec/support/expectations.rb +17 -20
  288. data/spec/support/macros.rb +30 -0
  289. data/spec/support/models/augmentation.rb +12 -0
  290. data/spec/support/models/band.rb +3 -0
  291. data/spec/support/models/catalog.rb +24 -0
  292. data/spec/support/models/circus.rb +3 -0
  293. data/spec/support/models/fanatic.rb +8 -0
  294. data/spec/support/models/implant.rb +9 -0
  295. data/spec/support/models/label.rb +2 -0
  296. data/spec/support/models/passport.rb +9 -0
  297. data/spec/support/models/person.rb +1 -0
  298. data/spec/support/models/player.rb +2 -0
  299. data/spec/support/models/powerup.rb +12 -0
  300. data/spec/support/models/registry.rb +1 -0
  301. data/spec/support/models/school.rb +14 -0
  302. data/spec/support/models/shield.rb +18 -0
  303. data/spec/support/models/student.rb +14 -0
  304. data/spec/support/models/weapon.rb +12 -0
  305. data.tar.gz.sig +0 -0
  306. metadata +695 -641
  307. metadata.gz.sig +0 -0
  308. data/lib/mongoid/errors/eager_load.rb +0 -23
  309. data/lib/mongoid/errors/invalid_value.rb +0 -17
  310. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
  311. data/spec/shared/CANDIDATE.md +0 -28
  312. data/spec/shared/lib/mrss/release/candidate.rb +0 -281
  313. data/spec/shared/lib/mrss/release/product_data.rb +0 -144
  314. data/spec/shared/lib/tasks/candidate.rake +0 -64
@@ -290,6 +290,26 @@ describe Mongoid::Extensions::Hash do
290
290
  it "returns the hash" do
291
291
  expect(Hash.demongoize(hash)).to eq(hash)
292
292
  end
293
+
294
+ context "when object is nil" do
295
+ let(:demongoized) do
296
+ Hash.demongoize(nil)
297
+ end
298
+
299
+ it "returns nil" do
300
+ expect(demongoized).to be_nil
301
+ end
302
+ end
303
+
304
+ context "when the object is uncastable" do
305
+ let(:demongoized) do
306
+ Hash.demongoize(1)
307
+ end
308
+
309
+ it "returns the object" do
310
+ expect(demongoized).to eq(1)
311
+ end
312
+ end
293
313
  end
294
314
 
295
315
  describe ".mongoize" do
@@ -326,6 +346,16 @@ describe Mongoid::Extensions::Hash do
326
346
  expect(mongoized).to be_nil
327
347
  end
328
348
  end
349
+
350
+ context "when the object is uncastable" do
351
+ let(:mongoized) do
352
+ Hash.mongoize(1)
353
+ end
354
+
355
+ it "returns nil" do
356
+ expect(mongoized).to be_nil
357
+ end
358
+ end
329
359
  end
330
360
 
331
361
  describe "#mongoize" do
@@ -467,240 +497,4 @@ describe Mongoid::Extensions::Hash do
467
497
 
468
498
  it_behaves_like 'unsatisfiable criteria method'
469
499
  end
470
-
471
- describe '#to_criteria' do
472
- subject(:criteria) { hash.to_criteria }
473
-
474
- context 'when klass is specified' do
475
- let(:hash) do
476
- { klass: Band, where: { name: 'Songs Ohia' } }
477
- end
478
-
479
- it 'returns a criteria' do
480
- expect(criteria).to be_a(Mongoid::Criteria)
481
- end
482
-
483
- it 'sets the klass' do
484
- expect(criteria.klass).to eq(Band)
485
- end
486
-
487
- it 'sets the selector' do
488
- expect(criteria.selector).to eq({ 'name' => 'Songs Ohia' })
489
- end
490
- end
491
-
492
- context 'when klass is missing' do
493
- let(:hash) do
494
- { where: { name: 'Songs Ohia' } }
495
- end
496
-
497
- it 'returns a criteria' do
498
- expect(criteria).to be_a(Mongoid::Criteria)
499
- end
500
-
501
- it 'has klass nil' do
502
- expect(criteria.klass).to be_nil
503
- end
504
-
505
- it 'sets the selector' do
506
- expect(criteria.selector).to eq({ 'name' => 'Songs Ohia' })
507
- end
508
- end
509
-
510
- context 'with allowed methods' do
511
- context 'when using multiple query methods' do
512
- let(:hash) do
513
- {
514
- klass: Band,
515
- where: { active: true },
516
- limit: 10,
517
- skip: 5,
518
- order_by: { name: 1 }
519
- }
520
- end
521
-
522
- it 'applies all methods successfully' do
523
- expect(criteria.selector).to eq({ 'active' => true })
524
- expect(criteria.options[:limit]).to eq(10)
525
- expect(criteria.options[:skip]).to eq(5)
526
- expect(criteria.options[:sort]).to eq({ 'name' => 1 })
527
- end
528
- end
529
-
530
- context 'when using query selector methods' do
531
- let(:hash) do
532
- {
533
- klass: Band,
534
- gt: { members: 2 },
535
- in: { genre: ['rock', 'metal'] }
536
- }
537
- end
538
-
539
- it 'applies selector methods' do
540
- expect(criteria.selector['members']).to eq({ '$gt' => 2 })
541
- expect(criteria.selector['genre']).to eq({ '$in' => ['rock', 'metal'] })
542
- end
543
- end
544
-
545
- context 'when using aggregation methods' do
546
- let(:hash) do
547
- {
548
- klass: Band,
549
- project: { name: 1, members: 1 }
550
- }
551
- end
552
-
553
- it 'applies aggregation methods' do
554
- expect { criteria }.not_to raise_error
555
- end
556
- end
557
- end
558
-
559
- context 'with disallowed methods' do
560
- context 'when attempting to call create' do
561
- let(:hash) do
562
- { klass: Band, create: { name: 'Malicious' } }
563
- end
564
-
565
- it 'raises ArgumentError' do
566
- expect { criteria }.to raise_error(ArgumentError, "Method 'create' is not allowed in to_criteria")
567
- end
568
- end
569
-
570
- context 'when attempting to call create!' do
571
- let(:hash) do
572
- { klass: Band, 'create!': { name: 'Malicious' } }
573
- end
574
-
575
- it 'raises ArgumentError' do
576
- expect { criteria }.to raise_error(ArgumentError, "Method 'create!' is not allowed in to_criteria")
577
- end
578
- end
579
-
580
- context 'when attempting to call build' do
581
- let(:hash) do
582
- { klass: Band, build: { name: 'Malicious' } }
583
- end
584
-
585
- it 'raises ArgumentError' do
586
- expect { criteria }.to raise_error(ArgumentError, "Method 'build' is not allowed in to_criteria")
587
- end
588
- end
589
-
590
- context 'when attempting to call find' do
591
- let(:hash) do
592
- { klass: Band, find: 'some_id' }
593
- end
594
-
595
- it 'raises ArgumentError' do
596
- expect { criteria }.to raise_error(ArgumentError, "Method 'find' is not allowed in to_criteria")
597
- end
598
- end
599
-
600
- context 'when attempting to call execute_or_raise' do
601
- let(:hash) do
602
- { klass: Band, execute_or_raise: ['id1', 'id2'] }
603
- end
604
-
605
- it 'raises ArgumentError' do
606
- expect { criteria }.to raise_error(ArgumentError, "Method 'execute_or_raise' is not allowed in to_criteria")
607
- end
608
- end
609
-
610
- context 'when attempting to call new' do
611
- let(:hash) do
612
- { klass: Band, new: { name: 'Test' } }
613
- end
614
-
615
- it 'raises ArgumentError' do
616
- expect { criteria }.to raise_error(ArgumentError, "Method 'new' is not allowed in to_criteria")
617
- end
618
- end
619
-
620
- context 'when allowed method is combined with disallowed method' do
621
- let(:hash) do
622
- {
623
- klass: Band,
624
- where: { active: true },
625
- create: { name: 'Malicious' }
626
- }
627
- end
628
-
629
- it 'raises ArgumentError before executing any methods' do
630
- expect { criteria }.to raise_error(ArgumentError, "Method 'create' is not allowed in to_criteria")
631
- end
632
- end
633
- end
634
-
635
- context 'security validation' do
636
- # This test ensures that ALL public methods not in the allowlist are blocked
637
- it 'blocks all dangerous public methods' do
638
- dangerous_methods = %i[
639
- build create create! new
640
- find find_or_create_by find_or_create_by! find_or_initialize_by
641
- first_or_create first_or_create! first_or_initialize
642
- execute_or_raise multiple_from_db for_ids
643
- documents= inclusions= scoping_options=
644
- initialize freeze as_json
645
- ]
646
-
647
- dangerous_methods.each do |method|
648
- hash = { klass: Band, method => 'arg' }
649
- expect { hash.to_criteria }.to raise_error(
650
- ArgumentError,
651
- "Method '#{method}' is not allowed in to_criteria"
652
- ), "Expected method '#{method}' to be blocked but it was allowed"
653
- end
654
- end
655
-
656
- it 'blocks dangerous inherited methods from Object' do
657
- # Critical security test: block send, instance_eval, etc.
658
- inherited_dangerous = %i[
659
- send __send__ instance_eval instance_exec
660
- instance_variable_set method
661
- ]
662
-
663
- inherited_dangerous.each do |method|
664
- hash = { klass: Band, method => 'arg' }
665
- expect { hash.to_criteria }.to raise_error(
666
- ArgumentError,
667
- "Method '#{method}' is not allowed in to_criteria"
668
- ), "Expected inherited method '#{method}' to be blocked"
669
- end
670
- end
671
-
672
- it 'blocks Enumerable execution methods' do
673
- # to_criteria should build queries, not execute them
674
- enumerable_methods = %i[each map select count sum]
675
-
676
- enumerable_methods.each do |method|
677
- hash = { klass: Band, method => 'arg' }
678
- expect { hash.to_criteria }.to raise_error(
679
- ArgumentError,
680
- "Method '#{method}' is not allowed in to_criteria"
681
- ), "Expected Enumerable method '#{method}' to be blocked"
682
- end
683
- end
684
-
685
- it 'allows all whitelisted methods' do
686
- # Sample of allowed methods from each category
687
- allowed_sample = {
688
- where: { name: 'Test' }, # Query selector
689
- limit: 10, # Query option
690
- skip: 5, # Query option
691
- gt: { age: 18 }, # Query selector
692
- in: { status: ['active'] }, # Query selector
693
- ascending: :name, # Sorting
694
- includes: :notes, # Eager loading
695
- merge: { klass: Band }, # Merge
696
- }
697
-
698
- allowed_sample.each do |method, args|
699
- hash = { klass: Band, method => args }
700
- expect { hash.to_criteria }.not_to raise_error,
701
- "Expected method '#{method}' to be allowed but it was blocked"
702
- end
703
- end
704
- end
705
- end
706
500
  end
@@ -33,107 +33,86 @@ describe Mongoid::Extensions::Integer do
33
33
  end
34
34
  end
35
35
 
36
- describe ".demongoize" do
36
+ [ :mongoize, :demongoize ].each do |method|
37
37
 
38
- context "when the value is an integer" do
38
+ describe ".#{method}" do
39
39
 
40
- it "returns a integer" do
41
- expect(Integer.demongoize(number)).to eq(number)
42
- end
43
- end
40
+ context "when the value is a number" do
44
41
 
45
- context "when the value is nil" do
46
-
47
- it "returns nil" do
48
- expect(Integer.demongoize(nil)).to be_nil
49
- end
50
- end
42
+ context "when the value is an integer" do
51
43
 
52
- context "when the value is not an integer" do
44
+ context "when the value is small" do
53
45
 
54
- it "converts the value to an integer" do
55
- expect(Integer.demongoize("1.0")).to eq(1)
56
- end
57
- end
58
- end
59
-
60
- describe ".mongoize" do
61
-
62
- context "when the value is a number" do
63
-
64
- context "when the value is an integer" do
65
-
66
- context "when the value is small" do
67
-
68
- it "it returns the integer" do
69
- expect(Integer.mongoize(3)).to eq(3)
46
+ it "it returns the integer" do
47
+ expect(Integer.send(method, 3)).to eq(3)
48
+ end
70
49
  end
71
- end
72
50
 
73
- context "when the value is large" do
51
+ context "when the value is large" do
74
52
 
75
- it "returns the integer" do
76
- expect(Integer.mongoize(1024**2).to_s).to eq("1048576")
53
+ it "returns the integer" do
54
+ expect(Integer.send(method, 1024**2).to_s).to eq("1048576")
55
+ end
77
56
  end
78
57
  end
79
- end
80
58
 
81
- context "when the value is a decimal" do
59
+ context "when the value is a decimal" do
82
60
 
83
- it "casts to integer" do
84
- expect(Integer.mongoize(2.5)).to eq(2)
61
+ it "casts to integer" do
62
+ expect(Integer.send(method, 2.5)).to eq(2)
63
+ end
85
64
  end
86
- end
87
65
 
88
- context "when the value is floating point zero" do
66
+ context "when the value is floating point zero" do
89
67
 
90
- it "returns the integer zero" do
91
- expect(Integer.mongoize(0.00000)).to eq(0)
68
+ it "returns the integer zero" do
69
+ expect(Integer.send(method, 0.00000)).to eq(0)
70
+ end
92
71
  end
93
- end
94
72
 
95
- context "when the value is a floating point integer" do
73
+ context "when the value is a floating point integer" do
96
74
 
97
- it "returns the integer number" do
98
- expect(Integer.mongoize(4.00000)).to eq(4)
75
+ it "returns the integer number" do
76
+ expect(Integer.send(method, 4.00000)).to eq(4)
77
+ end
99
78
  end
100
- end
101
79
 
102
- context "when the value has leading zeros" do
80
+ context "when the value has leading zeros" do
103
81
 
104
- it "returns the stripped integer" do
105
- expect(Integer.mongoize("000011")).to eq(11)
82
+ it "returns the stripped integer" do
83
+ expect(Integer.send(method, "000011")).to eq(11)
84
+ end
106
85
  end
107
86
  end
108
- end
109
87
 
110
- context "when the string is not a number" do
88
+ context "when the string is not a number" do
111
89
 
112
- context "when the string is non numerical" do
90
+ context "when the string is non numerical" do
113
91
 
114
- it "returns 0" do
115
- expect(Integer.mongoize("foo")).to eq(0)
92
+ it "returns nil" do
93
+ expect(Integer.send(method, "foo")).to be_nil
94
+ end
116
95
  end
117
- end
118
96
 
119
- context "when the string is numerical" do
97
+ context "when the string is numerical" do
120
98
 
121
- it "returns the integer value for the string" do
122
- expect(Integer.mongoize("3")).to eq(3)
99
+ it "returns the integer value for the string" do
100
+ expect(Integer.send(method, "3")).to eq(3)
101
+ end
123
102
  end
124
- end
125
103
 
126
- context "when the string is empty" do
104
+ context "when the string is empty" do
127
105
 
128
- it "returns nil" do
129
- expect(Integer.mongoize("")).to be_nil
106
+ it "returns nil" do
107
+ expect(Integer.send(method, "")).to be_nil
108
+ end
130
109
  end
131
- end
132
110
 
133
- context "when the string is nil" do
111
+ context "when the string is nil" do
134
112
 
135
- it "returns nil" do
136
- expect(Integer.mongoize(nil)).to be_nil
113
+ it "returns nil" do
114
+ expect(Integer.send(method, nil)).to be_nil
115
+ end
137
116
  end
138
117
  end
139
118
  end