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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +3 -3
- data/README.md +3 -3
- data/Rakefile +17 -66
- data/lib/config/locales/en.yml +46 -40
- data/lib/mongoid/association/accessors.rb +3 -7
- data/lib/mongoid/association/builders.rb +1 -1
- data/lib/mongoid/association/depending.rb +4 -8
- data/lib/mongoid/association/eager_loadable.rb +0 -3
- data/lib/mongoid/association/embedded/batchable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +6 -6
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +2 -2
- data/lib/mongoid/association/macros.rb +0 -6
- data/lib/mongoid/association/nested/many.rb +3 -38
- data/lib/mongoid/association/nested/nested_buildable.rb +0 -14
- data/lib/mongoid/association/nested/one.rb +40 -2
- data/lib/mongoid/association/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +6 -23
- data/lib/mongoid/association/referenced/has_many/proxy.rb +4 -103
- data/lib/mongoid/association/reflections.rb +2 -2
- data/lib/mongoid/atomic.rb +7 -16
- data/lib/mongoid/attributes/dynamic.rb +1 -1
- data/lib/mongoid/attributes/nested.rb +2 -2
- data/lib/mongoid/attributes/processing.rb +5 -29
- data/lib/mongoid/attributes/projector.rb +1 -1
- data/lib/mongoid/attributes/readonly.rb +1 -1
- data/lib/mongoid/attributes.rb +8 -2
- data/lib/mongoid/changeable.rb +107 -5
- data/lib/mongoid/clients/factory.rb +0 -4
- data/lib/mongoid/clients/storage_options.rb +2 -5
- data/lib/mongoid/clients/validators/storage.rb +1 -13
- data/lib/mongoid/collection_configurable.rb +58 -0
- data/lib/mongoid/composable.rb +2 -0
- data/lib/mongoid/config/defaults.rb +60 -0
- data/lib/mongoid/config/options.rb +0 -3
- data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
- data/lib/mongoid/config/validators.rb +1 -0
- data/lib/mongoid/config.rb +88 -89
- data/lib/mongoid/contextual/aggregable/memory.rb +2 -5
- data/lib/mongoid/contextual/atomic.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +240 -51
- data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
- data/lib/mongoid/contextual/mongo.rb +370 -133
- data/lib/mongoid/contextual/none.rb +162 -7
- data/lib/mongoid/contextual.rb +12 -0
- data/lib/mongoid/criteria/findable.rb +2 -2
- data/lib/mongoid/criteria/includable.rb +4 -3
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -15
- data/lib/mongoid/criteria/queryable/key.rb +1 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +1 -13
- data/lib/mongoid/criteria/queryable/optional.rb +8 -8
- data/lib/mongoid/criteria/queryable/selectable.rb +43 -121
- data/lib/mongoid/criteria/queryable/selector.rb +1 -1
- data/lib/mongoid/criteria/queryable/storable.rb +1 -1
- data/lib/mongoid/criteria.rb +6 -5
- data/lib/mongoid/deprecable.rb +1 -2
- data/lib/mongoid/deprecation.rb +3 -3
- data/lib/mongoid/document.rb +1 -8
- data/lib/mongoid/errors/create_collection_failure.rb +33 -0
- data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
- data/lib/mongoid/errors/immutable_attribute.rb +26 -0
- data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
- data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
- data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
- data/lib/mongoid/errors.rb +4 -2
- data/lib/mongoid/extensions/hash.rb +3 -51
- data/lib/mongoid/extensions/object.rb +2 -2
- data/lib/mongoid/extensions/time.rb +2 -0
- data/lib/mongoid/fields/localized.rb +10 -0
- data/lib/mongoid/fields/standard.rb +10 -0
- data/lib/mongoid/fields.rb +59 -35
- data/lib/mongoid/findable.rb +27 -3
- data/lib/mongoid/interceptable.rb +6 -116
- data/lib/mongoid/matchable.rb +1 -6
- data/lib/mongoid/matcher/eq_impl.rb +1 -1
- data/lib/mongoid/matcher/eq_impl_with_regexp.rb +5 -3
- data/lib/mongoid/matcher/regex.rb +9 -8
- data/lib/mongoid/matcher/type.rb +1 -1
- data/lib/mongoid/matcher.rb +0 -1
- data/lib/mongoid/persistable/creatable.rb +1 -0
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/savable.rb +13 -1
- data/lib/mongoid/persistable/unsettable.rb +2 -2
- data/lib/mongoid/persistable/updatable.rb +51 -1
- data/lib/mongoid/persistable/upsertable.rb +20 -1
- data/lib/mongoid/persistable.rb +3 -0
- data/lib/mongoid/query_cache.rb +5 -1
- data/lib/mongoid/railties/database.rake +7 -2
- data/lib/mongoid/reloadable.rb +5 -3
- data/lib/mongoid/stateful.rb +22 -1
- data/lib/mongoid/tasks/database.rake +12 -0
- data/lib/mongoid/tasks/database.rb +20 -0
- data/lib/mongoid/threaded.rb +0 -3
- data/lib/mongoid/timestamps/created.rb +1 -8
- data/lib/mongoid/traversable.rb +0 -12
- data/lib/mongoid/utils.rb +22 -0
- data/lib/mongoid/validatable/associated.rb +17 -98
- data/lib/mongoid/validatable/macros.rb +5 -20
- data/lib/mongoid/validatable.rb +4 -10
- data/lib/mongoid/version.rb +1 -5
- data/lib/mongoid/warnings.rb +17 -2
- data/lib/mongoid.rb +16 -3
- data/spec/integration/app_spec.rb +2 -20
- data/spec/integration/associations/embeds_one_spec.rb +5 -25
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +0 -55
- data/spec/integration/callbacks_spec.rb +99 -12
- data/spec/integration/discriminator_key_spec.rb +4 -5
- data/spec/integration/dots_and_dollars_spec.rb +2 -12
- data/spec/integration/i18n_fallbacks_spec.rb +3 -2
- data/spec/integration/matcher_operator_data/regex.yml +0 -21
- data/spec/mongoid/association/eager_spec.rb +2 -24
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +20 -25
- data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +0 -4
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +42 -103
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +9 -195
- data/spec/mongoid/association/syncable_spec.rb +1 -1
- data/spec/mongoid/attributes/nested_spec.rb +10 -204
- data/spec/mongoid/attributes_spec.rb +3 -33
- data/spec/mongoid/changeable_spec.rb +299 -24
- data/spec/mongoid/clients/factory_spec.rb +0 -30
- data/spec/mongoid/clients_spec.rb +122 -13
- data/spec/mongoid/collection_configurable_spec.rb +158 -0
- data/spec/mongoid/config/defaults_spec.rb +160 -0
- data/spec/mongoid/config_spec.rb +154 -27
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +0 -91
- data/spec/mongoid/contextual/memory_spec.rb +332 -253
- data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
- data/spec/mongoid/contextual/mongo_spec.rb +1009 -125
- data/spec/mongoid/contextual/none_spec.rb +49 -2
- data/spec/mongoid/copyable_spec.rb +2 -10
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -10
- data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -2
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +0 -235
- data/spec/mongoid/criteria/queryable/selector_spec.rb +3 -76
- data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
- data/spec/mongoid/criteria_projection_spec.rb +1 -4
- data/spec/mongoid/criteria_spec.rb +5 -11
- data/spec/mongoid/document_spec.rb +0 -27
- data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
- data/spec/mongoid/extensions/hash_spec.rb +3 -239
- data/spec/mongoid/extensions/time_spec.rb +8 -43
- data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
- data/spec/mongoid/fields/localized_spec.rb +46 -28
- data/spec/mongoid/fields_spec.rb +136 -77
- data/spec/mongoid/findable_spec.rb +391 -34
- data/spec/mongoid/indexable_spec.rb +16 -10
- data/spec/mongoid/interceptable_spec.rb +153 -442
- data/spec/mongoid/interceptable_spec_models.rb +111 -51
- data/spec/mongoid/persistable/deletable_spec.rb +26 -6
- data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
- data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
- data/spec/mongoid/persistable/logical_spec.rb +37 -0
- data/spec/mongoid/persistable/poppable_spec.rb +36 -0
- data/spec/mongoid/persistable/pullable_spec.rb +72 -0
- data/spec/mongoid/persistable/pushable_spec.rb +72 -0
- data/spec/mongoid/persistable/renamable_spec.rb +36 -0
- data/spec/mongoid/persistable/savable_spec.rb +96 -0
- data/spec/mongoid/persistable/settable_spec.rb +37 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
- data/spec/mongoid/persistable/updatable_spec.rb +20 -28
- data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
- data/spec/mongoid/persistence_context_spec.rb +7 -57
- data/spec/mongoid/query_cache_spec.rb +56 -61
- data/spec/mongoid/reloadable_spec.rb +24 -28
- data/spec/mongoid/scopable_spec.rb +70 -0
- data/spec/mongoid/serializable_spec.rb +23 -44
- data/spec/mongoid/stateful_spec.rb +122 -8
- data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
- data/spec/mongoid/tasks/database_spec.rb +127 -0
- data/spec/mongoid/timestamps/created_spec.rb +0 -23
- data/spec/mongoid/timestamps_spec.rb +9 -11
- data/spec/mongoid/touchable_spec.rb +277 -5
- data/spec/mongoid/touchable_spec_models.rb +3 -1
- data/spec/mongoid/traversable_spec.rb +9 -24
- data/spec/mongoid/validatable/associated_spec.rb +34 -27
- data/spec/mongoid/validatable/numericality_spec.rb +0 -16
- data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
- data/spec/mongoid_spec.rb +36 -10
- data/spec/shared/lib/mrss/docker_runner.rb +1 -1
- data/spec/shared/lib/mrss/server_version_registry.rb +1 -1
- data/spec/shared/lib/mrss/spec_organizer.rb +3 -32
- data/spec/shared/share/Dockerfile.erb +85 -15
- data/spec/shared/shlib/distro.sh +0 -10
- data/spec/shared/shlib/server.sh +27 -34
- data/spec/shared/shlib/set_env.sh +68 -9
- data/spec/spec_helper.rb +5 -0
- data/spec/support/expectations.rb +17 -20
- data/spec/support/immutable_ids.rb +118 -0
- data/spec/support/macros.rb +47 -15
- data/spec/support/models/artist.rb +0 -1
- data/spec/support/models/band.rb +1 -0
- data/spec/support/models/building.rb +2 -0
- data/spec/support/models/name.rb +0 -10
- data/spec/support/models/person.rb +0 -1
- data/spec/support/models/product.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +715 -671
- metadata.gz.sig +2 -0
- data/lib/mongoid/errors/in_memory_regexp_timeout.rb +0 -26
- data/lib/mongoid/field_readable.rb +0 -70
- data/lib/mongoid/matcher/regexp_budget.rb +0 -389
- data/lib/mongoid/validatable/numericality.rb +0 -19
- data/spec/integration/matcher_regexp_timeout_spec.rb +0 -215
- data/spec/integration/query_operator_guard_spec.rb +0 -89
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -61
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -61
- data/spec/mongoid/matcher/regexp_budget_spec.rb +0 -570
- data/spec/shared/CANDIDATE.md +0 -28
- data/spec/shared/lib/mrss/release/candidate.rb +0 -281
- data/spec/shared/lib/mrss/release/product_data.rb +0 -144
- data/spec/shared/lib/tasks/candidate.rake +0 -64
- 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
|
|
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 $
|
|
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
|
-
|
|
2059
|
+
require_fallbacks
|
|
2063
2060
|
|
|
2064
|
-
|
|
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
|
|
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
|
|
21
|
+
"Documents that are marked readonly cannot be persisted"
|
|
22
22
|
)
|
|
23
23
|
end
|
|
24
24
|
|