mongoid 8.0.13 → 8.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 (225) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +3 -3
  5. data/Rakefile +17 -66
  6. data/lib/config/locales/en.yml +46 -40
  7. data/lib/mongoid/association/accessors.rb +3 -7
  8. data/lib/mongoid/association/builders.rb +1 -1
  9. data/lib/mongoid/association/depending.rb +4 -8
  10. data/lib/mongoid/association/eager_loadable.rb +0 -3
  11. data/lib/mongoid/association/embedded/batchable.rb +2 -2
  12. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  13. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
  14. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
  15. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +6 -6
  16. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
  17. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +2 -2
  18. data/lib/mongoid/association/macros.rb +0 -6
  19. data/lib/mongoid/association/nested/many.rb +3 -38
  20. data/lib/mongoid/association/nested/nested_buildable.rb +0 -14
  21. data/lib/mongoid/association/nested/one.rb +40 -2
  22. data/lib/mongoid/association/proxy.rb +1 -1
  23. data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
  24. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +1 -1
  25. data/lib/mongoid/association/referenced/has_many/enumerable.rb +6 -23
  26. data/lib/mongoid/association/referenced/has_many/proxy.rb +4 -103
  27. data/lib/mongoid/association/reflections.rb +2 -2
  28. data/lib/mongoid/atomic.rb +7 -16
  29. data/lib/mongoid/attributes/dynamic.rb +1 -1
  30. data/lib/mongoid/attributes/nested.rb +2 -2
  31. data/lib/mongoid/attributes/processing.rb +5 -29
  32. data/lib/mongoid/attributes/projector.rb +1 -1
  33. data/lib/mongoid/attributes/readonly.rb +1 -1
  34. data/lib/mongoid/attributes.rb +8 -2
  35. data/lib/mongoid/changeable.rb +107 -5
  36. data/lib/mongoid/clients/factory.rb +0 -4
  37. data/lib/mongoid/clients/storage_options.rb +2 -5
  38. data/lib/mongoid/clients/validators/storage.rb +1 -13
  39. data/lib/mongoid/collection_configurable.rb +58 -0
  40. data/lib/mongoid/composable.rb +2 -0
  41. data/lib/mongoid/config/defaults.rb +60 -0
  42. data/lib/mongoid/config/options.rb +0 -3
  43. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  44. data/lib/mongoid/config/validators.rb +1 -0
  45. data/lib/mongoid/config.rb +88 -89
  46. data/lib/mongoid/contextual/aggregable/memory.rb +2 -5
  47. data/lib/mongoid/contextual/atomic.rb +1 -1
  48. data/lib/mongoid/contextual/memory.rb +240 -51
  49. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  50. data/lib/mongoid/contextual/mongo.rb +370 -133
  51. data/lib/mongoid/contextual/none.rb +162 -7
  52. data/lib/mongoid/contextual.rb +12 -0
  53. data/lib/mongoid/criteria/findable.rb +2 -2
  54. data/lib/mongoid/criteria/includable.rb +4 -3
  55. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -15
  56. data/lib/mongoid/criteria/queryable/key.rb +1 -1
  57. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -13
  58. data/lib/mongoid/criteria/queryable/optional.rb +8 -8
  59. data/lib/mongoid/criteria/queryable/selectable.rb +43 -121
  60. data/lib/mongoid/criteria/queryable/selector.rb +1 -1
  61. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  62. data/lib/mongoid/criteria.rb +6 -5
  63. data/lib/mongoid/deprecable.rb +1 -2
  64. data/lib/mongoid/deprecation.rb +3 -3
  65. data/lib/mongoid/document.rb +1 -8
  66. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  67. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  68. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  69. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  70. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  71. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  72. data/lib/mongoid/errors.rb +4 -2
  73. data/lib/mongoid/extensions/hash.rb +3 -51
  74. data/lib/mongoid/extensions/object.rb +2 -2
  75. data/lib/mongoid/extensions/time.rb +2 -0
  76. data/lib/mongoid/fields/localized.rb +10 -0
  77. data/lib/mongoid/fields/standard.rb +10 -0
  78. data/lib/mongoid/fields.rb +59 -35
  79. data/lib/mongoid/findable.rb +27 -3
  80. data/lib/mongoid/interceptable.rb +6 -116
  81. data/lib/mongoid/matchable.rb +1 -6
  82. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  83. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +5 -3
  84. data/lib/mongoid/matcher/regex.rb +9 -8
  85. data/lib/mongoid/matcher/type.rb +1 -1
  86. data/lib/mongoid/matcher.rb +0 -1
  87. data/lib/mongoid/persistable/creatable.rb +1 -0
  88. data/lib/mongoid/persistable/deletable.rb +1 -1
  89. data/lib/mongoid/persistable/savable.rb +13 -1
  90. data/lib/mongoid/persistable/unsettable.rb +2 -2
  91. data/lib/mongoid/persistable/updatable.rb +51 -1
  92. data/lib/mongoid/persistable/upsertable.rb +20 -1
  93. data/lib/mongoid/persistable.rb +3 -0
  94. data/lib/mongoid/query_cache.rb +5 -1
  95. data/lib/mongoid/railties/database.rake +7 -2
  96. data/lib/mongoid/reloadable.rb +5 -3
  97. data/lib/mongoid/stateful.rb +22 -1
  98. data/lib/mongoid/tasks/database.rake +12 -0
  99. data/lib/mongoid/tasks/database.rb +20 -0
  100. data/lib/mongoid/threaded.rb +0 -3
  101. data/lib/mongoid/timestamps/created.rb +1 -8
  102. data/lib/mongoid/traversable.rb +0 -12
  103. data/lib/mongoid/utils.rb +22 -0
  104. data/lib/mongoid/validatable/associated.rb +17 -98
  105. data/lib/mongoid/validatable/macros.rb +5 -20
  106. data/lib/mongoid/validatable.rb +4 -10
  107. data/lib/mongoid/version.rb +1 -5
  108. data/lib/mongoid/warnings.rb +17 -2
  109. data/lib/mongoid.rb +16 -3
  110. data/spec/integration/app_spec.rb +2 -20
  111. data/spec/integration/associations/embeds_one_spec.rb +5 -25
  112. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +0 -55
  113. data/spec/integration/callbacks_spec.rb +99 -12
  114. data/spec/integration/discriminator_key_spec.rb +4 -5
  115. data/spec/integration/dots_and_dollars_spec.rb +2 -12
  116. data/spec/integration/i18n_fallbacks_spec.rb +3 -2
  117. data/spec/integration/matcher_operator_data/regex.yml +0 -21
  118. data/spec/mongoid/association/eager_spec.rb +2 -24
  119. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
  120. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +20 -25
  121. data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
  122. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +0 -4
  123. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  124. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
  125. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +42 -103
  126. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +9 -195
  127. data/spec/mongoid/association/syncable_spec.rb +1 -1
  128. data/spec/mongoid/attributes/nested_spec.rb +10 -204
  129. data/spec/mongoid/attributes_spec.rb +3 -33
  130. data/spec/mongoid/changeable_spec.rb +299 -24
  131. data/spec/mongoid/clients/factory_spec.rb +0 -30
  132. data/spec/mongoid/clients_spec.rb +122 -13
  133. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  134. data/spec/mongoid/config/defaults_spec.rb +160 -0
  135. data/spec/mongoid/config_spec.rb +154 -27
  136. data/spec/mongoid/contextual/aggregable/memory_spec.rb +0 -91
  137. data/spec/mongoid/contextual/memory_spec.rb +332 -253
  138. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  139. data/spec/mongoid/contextual/mongo_spec.rb +1009 -125
  140. data/spec/mongoid/contextual/none_spec.rb +49 -2
  141. data/spec/mongoid/copyable_spec.rb +2 -10
  142. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -10
  143. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  144. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -2
  145. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
  146. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +0 -235
  147. data/spec/mongoid/criteria/queryable/selector_spec.rb +3 -76
  148. data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
  149. data/spec/mongoid/criteria_projection_spec.rb +1 -4
  150. data/spec/mongoid/criteria_spec.rb +5 -11
  151. data/spec/mongoid/document_spec.rb +0 -27
  152. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  153. data/spec/mongoid/extensions/hash_spec.rb +3 -239
  154. data/spec/mongoid/extensions/time_spec.rb +8 -43
  155. data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
  156. data/spec/mongoid/fields/localized_spec.rb +46 -28
  157. data/spec/mongoid/fields_spec.rb +136 -77
  158. data/spec/mongoid/findable_spec.rb +391 -34
  159. data/spec/mongoid/indexable_spec.rb +16 -10
  160. data/spec/mongoid/interceptable_spec.rb +153 -442
  161. data/spec/mongoid/interceptable_spec_models.rb +111 -51
  162. data/spec/mongoid/persistable/deletable_spec.rb +26 -6
  163. data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
  164. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  165. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  166. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  167. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  168. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  169. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  170. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  171. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  172. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  173. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  174. data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
  175. data/spec/mongoid/persistence_context_spec.rb +7 -57
  176. data/spec/mongoid/query_cache_spec.rb +56 -61
  177. data/spec/mongoid/reloadable_spec.rb +24 -28
  178. data/spec/mongoid/scopable_spec.rb +70 -0
  179. data/spec/mongoid/serializable_spec.rb +23 -44
  180. data/spec/mongoid/stateful_spec.rb +122 -8
  181. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  182. data/spec/mongoid/tasks/database_spec.rb +127 -0
  183. data/spec/mongoid/timestamps/created_spec.rb +0 -23
  184. data/spec/mongoid/timestamps_spec.rb +9 -11
  185. data/spec/mongoid/touchable_spec.rb +277 -5
  186. data/spec/mongoid/touchable_spec_models.rb +3 -1
  187. data/spec/mongoid/traversable_spec.rb +9 -24
  188. data/spec/mongoid/validatable/associated_spec.rb +34 -27
  189. data/spec/mongoid/validatable/numericality_spec.rb +0 -16
  190. data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
  191. data/spec/mongoid_spec.rb +36 -10
  192. data/spec/shared/lib/mrss/docker_runner.rb +1 -1
  193. data/spec/shared/lib/mrss/server_version_registry.rb +1 -1
  194. data/spec/shared/lib/mrss/spec_organizer.rb +3 -32
  195. data/spec/shared/share/Dockerfile.erb +85 -15
  196. data/spec/shared/shlib/distro.sh +0 -10
  197. data/spec/shared/shlib/server.sh +27 -34
  198. data/spec/shared/shlib/set_env.sh +68 -9
  199. data/spec/spec_helper.rb +5 -0
  200. data/spec/support/expectations.rb +17 -20
  201. data/spec/support/immutable_ids.rb +118 -0
  202. data/spec/support/macros.rb +47 -15
  203. data/spec/support/models/artist.rb +0 -1
  204. data/spec/support/models/band.rb +1 -0
  205. data/spec/support/models/building.rb +2 -0
  206. data/spec/support/models/name.rb +0 -10
  207. data/spec/support/models/person.rb +0 -1
  208. data/spec/support/models/product.rb +1 -0
  209. data.tar.gz.sig +0 -0
  210. metadata +715 -671
  211. metadata.gz.sig +2 -0
  212. data/lib/mongoid/errors/in_memory_regexp_timeout.rb +0 -26
  213. data/lib/mongoid/field_readable.rb +0 -70
  214. data/lib/mongoid/matcher/regexp_budget.rb +0 -389
  215. data/lib/mongoid/validatable/numericality.rb +0 -19
  216. data/spec/integration/matcher_regexp_timeout_spec.rb +0 -215
  217. data/spec/integration/query_operator_guard_spec.rb +0 -89
  218. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -61
  219. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -61
  220. data/spec/mongoid/matcher/regexp_budget_spec.rb +0 -570
  221. data/spec/shared/CANDIDATE.md +0 -28
  222. data/spec/shared/lib/mrss/release/candidate.rb +0 -281
  223. data/spec/shared/lib/mrss/release/product_data.rb +0 -144
  224. data/spec/shared/lib/tasks/candidate.rake +0 -64
  225. data/spec/support/models/purse.rb +0 -9
@@ -35,8 +35,6 @@ describe Mongoid::Criteria::Queryable::Selectable do
35
35
  it_behaves_like 'requires a non-nil argument'
36
36
 
37
37
  context "when provided a string" do
38
- # String criteria compile to $where, which requires the opt-in.
39
- config_override :allow_unsafe_query_operators, true
40
38
 
41
39
  let(:selection) do
42
40
  query.where("this.value = 10")
@@ -588,237 +586,4 @@ describe Mongoid::Criteria::Queryable::Selectable do
588
586
  end
589
587
  end
590
588
  end
591
-
592
- describe 'top-level operator injection guard' do
593
- context 'when allow_unsafe_query_operators is true' do
594
- config_override :allow_unsafe_query_operators, true
595
-
596
- context 'when passing $where' do
597
- it 'does not raise' do
598
- expect do
599
- query.where('$where' => 'this.name == "admin"')
600
- end.not_to raise_error
601
- end
602
- end
603
-
604
- context 'when passing a string criterion' do
605
- it 'does not raise' do
606
- expect do
607
- query.where('this.name == "admin"')
608
- end.not_to raise_error
609
- end
610
- end
611
-
612
- context 'when passing a string criterion to a negated query' do
613
- it 'does not raise' do
614
- expect do
615
- query.not.where('this.name == "admin"')
616
- end.not_to raise_error
617
- end
618
- end
619
-
620
- context 'when passing $function' do
621
- it 'does not raise' do
622
- expect do
623
- query.where('$function' => { body: 'function() { return true; }', args: [], lang: 'js' })
624
- end.not_to raise_error
625
- end
626
- end
627
- end
628
-
629
- context 'when allow_unsafe_query_operators is false' do
630
- config_override :allow_unsafe_query_operators, false
631
-
632
- context 'when passing $where' do
633
- it 'raises InvalidQuery' do
634
- expect do
635
- query.where('$where' => 'this.name == "admin"')
636
- end.to raise_error(Mongoid::Errors::InvalidQuery, /\$where/)
637
- end
638
- end
639
-
640
- context 'when passing $function' do
641
- it 'raises InvalidQuery' do
642
- expect do
643
- query.where('$function' => { body: 'function() { return true; }', args: [], lang: 'js' })
644
- end.to raise_error(Mongoid::Errors::InvalidQuery, /\$function/)
645
- end
646
- end
647
-
648
- context 'when the error mentions allow_unsafe_query_operators' do
649
- it 'includes the config opt-in in the message' do
650
- expect do
651
- query.where('$where' => 'true')
652
- end.to raise_error(Mongoid::Errors::InvalidQuery, /allow_unsafe_query_operators/)
653
- end
654
- end
655
-
656
- context 'when passing a string criterion' do
657
- it 'raises InvalidQuery' do
658
- expect do
659
- query.where('this.name == "admin"')
660
- end.to raise_error(Mongoid::Errors::InvalidQuery, /\$where/)
661
- end
662
-
663
- it 'includes the config opt-in in the message' do
664
- expect do
665
- query.where('this.name == "admin"')
666
- end.to raise_error(Mongoid::Errors::InvalidQuery, /allow_unsafe_query_operators/)
667
- end
668
- end
669
-
670
- context 'when passing a string criterion to a negated query' do
671
- it 'raises InvalidQuery' do
672
- expect do
673
- query.not.where('this.name == "admin"')
674
- end.to raise_error(Mongoid::Errors::InvalidQuery, /\$where/)
675
- end
676
- end
677
-
678
- %w[$and $or $nor $not $text $comment $expr $jsonSchema $alwaysFalse $alwaysTrue].each do |op|
679
- context "when passing #{op} (allowlisted)" do
680
- it 'does not raise' do
681
- value = case op
682
- when '$and', '$or', '$nor', '$not' then [ { 'x' => 1 } ]
683
- when '$text' then { '$search' => 'hi' }
684
- when '$expr' then { '$gt' => [ '$a', 1 ] }
685
- when '$jsonSchema' then { 'required' => [ 'x' ] }
686
- else true
687
- end
688
- expect { query.where(op => value) }.not_to raise_error
689
- end
690
- end
691
- end
692
- end
693
- end
694
-
695
- describe 'nested operator injection guard' do
696
- js = 'this.name == "admin"'
697
-
698
- function_expr = {
699
- '$function' => { 'body' => 'function() { return true; }', 'args' => [], 'lang' => 'js' }
700
- }.freeze
701
-
702
- accumulator_expr = {
703
- '$accumulator' => {
704
- 'init' => 'function() { return 0; }',
705
- 'accumulate' => 'function() { return 0; }',
706
- 'accumulateArgs' => [],
707
- 'merge' => 'function() { return 0; }',
708
- 'lang' => 'js'
709
- }
710
- }.freeze
711
-
712
- # Every path into the selector that does not route through #expr_query,
713
- # plus the nested forms that a top-level key check cannot see.
714
- unsafe_queries = {
715
- 'and with a $where key' => ->(query) { query.and('$where' => js) },
716
- 'or with a $where key' => ->(query) { query.or('$where' => js) },
717
- 'nor with a $where key' => ->(query) { query.nor('$where' => js) },
718
- 'not with a $where key' => ->(query) { query.not('$where' => js) },
719
- 'any_of with a $where key' => ->(query) { query.any_of('$where' => js) },
720
- # none_of is not available on this branch; it landed in 8.1 via MONGOID-5453.
721
- 'elem_match with a nested $where' => ->(query) { query.elem_match(a: { '$where' => js }) },
722
- 'where with $where inside $or' => ->(query) { query.where('$or' => [ { '$where' => js } ]) },
723
- 'where with $function inside $expr' => ->(query) { query.where('$expr' => function_expr) },
724
- 'where with $accumulator inside $expr' => ->(query) { query.where('$expr' => accumulator_expr) },
725
- 'where with $where three levels deep' => lambda { |query|
726
- query.where('$and' => [ { '$or' => [ { '$where' => js } ] } ])
727
- },
728
- 'where with a symbol $where key inside $or' => ->(query) { query.where('$or' => [ { :$where => js } ]) }
729
- }.freeze
730
-
731
- context 'when allow_unsafe_query_operators is false' do
732
- config_override :allow_unsafe_query_operators, false
733
-
734
- unsafe_queries.each do |description, builder|
735
- context "when querying with #{description}" do
736
- it 'raises InvalidQuery' do
737
- expect do
738
- builder.call(query)
739
- end.to raise_error(Mongoid::Errors::InvalidQuery, /\$where|\$function|\$accumulator/)
740
- end
741
- end
742
- end
743
-
744
- it 'includes the config opt-in in the message' do
745
- expect do
746
- query.or('$where' => js)
747
- end.to raise_error(Mongoid::Errors::InvalidQuery, /allow_unsafe_query_operators/)
748
- end
749
-
750
- context 'when the nested expression is safe' do
751
- it 'permits $or with field expressions' do
752
- expect do
753
- query.where('$or' => [ { 'a' => 1 }, { 'b' => { '$gt' => 2 } } ])
754
- end.not_to raise_error
755
- end
756
-
757
- it 'permits $expr with aggregation operators' do
758
- expect do
759
- query.where('$expr' => { '$gt' => [ '$a', '$b' ] })
760
- end.not_to raise_error
761
- end
762
-
763
- it 'permits a field whose name resembles a javascript operator' do
764
- expect do
765
- query.where('where' => js)
766
- end.not_to raise_error
767
- end
768
-
769
- it 'permits a value that resembles a javascript operator' do
770
- expect do
771
- query.where('name' => '$where')
772
- end.not_to raise_error
773
- end
774
- end
775
- end
776
-
777
- context 'when allow_unsafe_query_operators is true' do
778
- config_override :allow_unsafe_query_operators, true
779
-
780
- unsafe_queries.each do |description, builder|
781
- context "when querying with #{description}" do
782
- it 'does not raise' do
783
- expect { builder.call(query) }.not_to raise_error
784
- end
785
- end
786
- end
787
- end
788
- end
789
-
790
- describe 'operator guard on chained override methods' do
791
- # On this branch overwrite_chained_operators defaults to false, which
792
- # routes elem_match through the guarded and_with_operator funnel. Force
793
- # the override path so the guard in Mergeable#__override__ is exercised.
794
- config_override :overwrite_chained_operators, true
795
-
796
- let(:js) { 'this.name == "admin"' }
797
-
798
- context 'when allow_unsafe_query_operators is false' do
799
- config_override :allow_unsafe_query_operators, false
800
-
801
- it 'rejects a $where nested in elem_match' do
802
- expect do
803
- query.elem_match(a: { '$where' => js })
804
- end.to raise_error(Mongoid::Errors::InvalidQuery, /executes server-side JavaScript/)
805
- end
806
-
807
- it 'permits an ordinary elem_match value' do
808
- expect do
809
- query.elem_match(a: { name: 'x' })
810
- end.not_to raise_error
811
- end
812
- end
813
-
814
- context 'when allow_unsafe_query_operators is true' do
815
- config_override :allow_unsafe_query_operators, true
816
-
817
- it 'permits a $where nested in elem_match' do
818
- expect do
819
- query.elem_match(a: { '$where' => js })
820
- end.not_to raise_error
821
- end
822
- end
823
- end
824
589
  end
@@ -44,7 +44,7 @@ describe Mongoid::Criteria::Queryable::Selector do
44
44
  end
45
45
  end
46
46
 
47
- context "when selector contains a $nin string" do
47
+ context "when selector contains a $nin" do
48
48
 
49
49
  let(:initial) do
50
50
  { "$nin" => ["foo"] }
@@ -72,35 +72,7 @@ describe Mongoid::Criteria::Queryable::Selector do
72
72
  end
73
73
  end
74
74
 
75
- context "when selector contains a $nin symbol" do
76
-
77
- let(:initial) do
78
- { :$nin => ["foo"] }
79
- end
80
-
81
- before do
82
- selector["field"] = initial
83
- end
84
-
85
- context "when merging in a new $nin" do
86
-
87
- let(:other) do
88
- { "field" => { :$nin => ["bar"] } }
89
- end
90
-
91
- before do
92
- selector.merge!(other)
93
- end
94
-
95
- it "combines the two $nin queries into one" do
96
- expect(selector).to eq({
97
- "field" => { :$nin => ["foo", "bar"] }
98
- })
99
- end
100
- end
101
- end
102
-
103
- context "when selector contains a $in string" do
75
+ context "when selector contains a $in" do
104
76
 
105
77
  let(:initial) do
106
78
  { "$in" => [1, 2] }
@@ -145,51 +117,6 @@ describe Mongoid::Criteria::Queryable::Selector do
145
117
  end
146
118
  end
147
119
 
148
- context "when selector contains a $in symbol" do
149
-
150
- let(:initial) do
151
- { :$in => [1, 2] }
152
- end
153
-
154
- before do
155
- selector["field"] = initial
156
- end
157
-
158
- context "when merging in a new $in with an intersecting value" do
159
-
160
- let(:other) do
161
- { "field" => { :$in => [1] } }
162
- end
163
-
164
- before do
165
- selector.merge!(other)
166
- end
167
-
168
- it "intersects the $in values" do
169
- expect(selector).to eq({
170
- "field" => { :$in => [1] }
171
- })
172
- end
173
- end
174
-
175
- context "when merging in a new $in with no intersecting values" do
176
-
177
- let(:other) do
178
- { "field" => { :$in => [3] } }
179
- end
180
-
181
- before do
182
- selector.merge!(other)
183
- end
184
-
185
- it "intersects the $in values" do
186
- expect(selector).to eq({
187
- "field" => { :$in => [] }
188
- })
189
- end
190
- end
191
- end
192
-
193
120
  context "when selector is not nested" do
194
121
 
195
122
  before do
@@ -681,6 +608,7 @@ describe Mongoid::Criteria::Queryable::Selector do
681
608
  end
682
609
 
683
610
  context "when the serializer is localized" do
611
+ with_default_i18n_configs
684
612
 
685
613
  before(:all) do
686
614
  class Field
@@ -696,7 +624,6 @@ describe Mongoid::Criteria::Queryable::Selector do
696
624
 
697
625
  after(:all) do
698
626
  Object.send(:remove_const, :Field)
699
- ::I18n.locale = :en
700
627
  end
701
628
 
702
629
  let(:selector) do
@@ -210,79 +210,7 @@ describe Mongoid::Criteria::Queryable::Storable do
210
210
  }
211
211
  end
212
212
  end
213
-
214
- context 'when value is a hash combine values with different operator keys' do
215
- let(:base) do
216
- query.add_field_expression('foo', {'$in' => ['bar']})
217
- end
218
-
219
- let(:modified) do
220
- base.add_field_expression('foo', {'$nin' => ['zoom']})
221
- end
222
-
223
- it 'combines the conditions using $and' do
224
- modified.selector.should == {
225
- 'foo' => {
226
- '$in' => ['bar'],
227
- '$nin' => ['zoom']
228
- }
229
- }
230
- end
231
- end
232
-
233
- context 'when value is a hash with symbol operator key combine values with different operator keys' do
234
- let(:base) do
235
- query.add_field_expression('foo', {:$in => ['bar']})
236
- end
237
-
238
- let(:modified) do
239
- base.add_field_expression('foo', {:$nin => ['zoom']})
240
- end
241
-
242
- it 'combines the conditions using $and' do
243
- modified.selector.should == {
244
- 'foo' => {
245
- :$in => ['bar'],
246
- :$nin => ['zoom']
247
- }
248
- }
249
- end
250
- end
251
-
252
- context 'when value is a hash add values with same operator keys using $and' do
253
- let(:base) do
254
- query.add_field_expression('foo', {'$in' => ['bar']})
255
- end
256
-
257
- let(:modified) do
258
- base.add_field_expression('foo', {'$in' => ['zoom']})
259
- end
260
-
261
- it 'adds the new condition using $and' do
262
- modified.selector.should == {
263
- 'foo' => {'$in' => ['bar']},
264
- '$and' => ['foo' => {'$in' => ['zoom']}]
265
- }
266
- end
267
- end
268
-
269
- context 'when value is a hash with symbol operator key add values with same operator keys using $and' do
270
- let(:base) do
271
- query.add_field_expression('foo', {:$in => ['bar']})
272
- end
273
-
274
- let(:modified) do
275
- base.add_field_expression('foo', {:$in => ['zoom']})
276
- end
277
-
278
- it 'adds the new condition using $and' do
279
- modified.selector.should == {
280
- 'foo' => {:$in => ['bar']},
281
- '$and' => ['foo' => {:$in => ['zoom']}]
282
- }
283
- end
284
213
  end
285
- end
286
214
 
287
215
  describe '#add_operator_expression' do
288
216
  let(:query_method) { :add_operator_expression }
@@ -154,6 +154,7 @@ describe Mongoid::Criteria do
154
154
  end
155
155
 
156
156
  context 'when the field is localized' do
157
+ with_default_i18n_configs
157
158
 
158
159
  before do
159
160
  I18n.locale = :en
@@ -163,10 +164,6 @@ describe Mongoid::Criteria do
163
164
  d.save!
164
165
  end
165
166
 
166
- after do
167
- I18n.locale = :en
168
- end
169
-
170
167
  context 'when entire field is included' do
171
168
 
172
169
  let(:dictionary) do
@@ -1953,6 +1953,7 @@ describe Mongoid::Criteria do
1953
1953
  end
1954
1954
 
1955
1955
  context 'when plucking a localized field' do
1956
+ with_default_i18n_configs
1956
1957
 
1957
1958
  before do
1958
1959
  I18n.locale = :en
@@ -1962,10 +1963,6 @@ describe Mongoid::Criteria do
1962
1963
  d.save!
1963
1964
  end
1964
1965
 
1965
- after do
1966
- I18n.locale = :en
1967
- end
1968
-
1969
1966
  context 'when plucking the entire field' do
1970
1967
  let(:plucked) do
1971
1968
  Dictionary.all.pluck(:description)
@@ -2059,13 +2056,10 @@ describe Mongoid::Criteria do
2059
2056
  end
2060
2057
 
2061
2058
  context 'when fallbacks are enabled with a locale list' do
2062
- with_i18n_fallbacks
2059
+ require_fallbacks
2063
2060
 
2064
- around(:all) do |example|
2065
- prev_fallbacks = I18n.fallbacks.dup
2061
+ before do
2066
2062
  I18n.fallbacks[:he] = [ :en ]
2067
- example.run
2068
- I18n.fallbacks = prev_fallbacks
2069
2063
  end
2070
2064
 
2071
2065
  let(:plucked) do
@@ -2093,6 +2087,8 @@ describe Mongoid::Criteria do
2093
2087
  end
2094
2088
 
2095
2089
  context "when the localized field is embedded" do
2090
+ with_default_i18n_configs
2091
+
2096
2092
  before do
2097
2093
  p = Passport.new
2098
2094
  I18n.locale = :en
@@ -2663,8 +2659,6 @@ describe Mongoid::Criteria do
2663
2659
  end
2664
2660
 
2665
2661
  context "when the criteria is not embedded" do
2666
- # String criteria compile to $where, which requires the opt-in.
2667
- config_override :allow_unsafe_query_operators, true
2668
2662
 
2669
2663
  let(:criteria) do
2670
2664
  Band.where("this.name == 'Depeche Mode'")
@@ -591,33 +591,6 @@ describe Mongoid::Document do
591
591
  expect(person.as_document["addresses"].first).to have_key(:locations)
592
592
  end
593
593
 
594
- context 'when modifying the returned object' do
595
- let(:record) do
596
- RootCategory.create(categories: [{ name: 'tests' }]).reload
597
- end
598
-
599
- shared_examples_for 'an object with protected internal state' do
600
- it 'does not expose internal state' do
601
- before_change = record.as_document.dup
602
- record.categories.first.name = 'things'
603
- after_change = record.as_document
604
- expect(before_change['categories'].first['name']).not_to eq('things')
605
- end
606
- end
607
-
608
- context 'when legacy_attributes is true' do
609
- config_override :legacy_attributes, true
610
-
611
- it_behaves_like 'an object with protected internal state'
612
- end
613
-
614
- context 'when legacy_attributes is false' do
615
- config_override :legacy_attributes, false
616
-
617
- it_behaves_like 'an object with protected internal state'
618
- end
619
- end
620
-
621
594
  context "with relation define store_as option in embeded_many" do
622
595
 
623
596
  let!(:phone) do
@@ -12,13 +12,13 @@ describe Mongoid::Errors::ReadonlyDocument do
12
12
 
13
13
  it "contains the problem in the message" do
14
14
  expect(error.message).to include(
15
- "Attempted to persist the readonly document 'Band'."
15
+ "Attempted to persist a readonly document of class 'Band'."
16
16
  )
17
17
  end
18
18
 
19
19
  it "contains the summary in the message" do
20
20
  expect(error.message).to include(
21
- "Documents loaded from the database using #only"
21
+ "Documents that are marked readonly cannot be persisted"
22
22
  )
23
23
  end
24
24