mongoid 7.1.7 → 7.1.11

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 (81) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/Rakefile +31 -0
  5. data/lib/config/locales/en.yml +13 -0
  6. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +1 -1
  7. data/lib/mongoid/association/proxy.rb +1 -1
  8. data/lib/mongoid/association/referenced/has_many/enumerable.rb +1 -1
  9. data/lib/mongoid/association/referenced/has_many/proxy.rb +1 -1
  10. data/lib/mongoid/attributes.rb +8 -1
  11. data/lib/mongoid/config/environment.rb +9 -1
  12. data/lib/mongoid/contextual/atomic.rb +7 -2
  13. data/lib/mongoid/contextual/none.rb +3 -0
  14. data/lib/mongoid/criteria/queryable/selectable.rb +2 -2
  15. data/lib/mongoid/criteria/queryable/storable.rb +4 -4
  16. data/lib/mongoid/criteria.rb +1 -1
  17. data/lib/mongoid/document.rb +3 -2
  18. data/lib/mongoid/errors/empty_config_file.rb +26 -0
  19. data/lib/mongoid/errors/invalid_config_file.rb +26 -0
  20. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  21. data/lib/mongoid/errors.rb +2 -0
  22. data/lib/mongoid/interceptable.rb +1 -1
  23. data/lib/mongoid/persistence_context.rb +3 -1
  24. data/lib/mongoid/reloadable.rb +5 -0
  25. data/lib/mongoid/tasks/database.rb +1 -1
  26. data/lib/mongoid/validatable/associated.rb +1 -1
  27. data/lib/mongoid/validatable/presence.rb +3 -3
  28. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  29. data/lib/mongoid/version.rb +1 -1
  30. data/lib/mongoid.rb +1 -0
  31. data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
  32. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  33. data/spec/app/models/address.rb +4 -0
  34. data/spec/app/models/mop.rb +26 -0
  35. data/spec/app/models/person.rb +9 -0
  36. data/spec/integration/app_spec.rb +144 -87
  37. data/spec/integration/contextual/empty_spec.rb +142 -0
  38. data/spec/integration/document_spec.rb +21 -0
  39. data/spec/lite_spec_helper.rb +5 -5
  40. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +17 -4
  41. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +17 -0
  42. data/spec/mongoid/attributes_spec.rb +241 -0
  43. data/spec/mongoid/clients/factory_spec.rb +11 -0
  44. data/spec/mongoid/clients/options_spec.rb +11 -3
  45. data/spec/mongoid/config/environment_spec.rb +86 -8
  46. data/spec/mongoid/contextual/atomic_spec.rb +81 -29
  47. data/spec/mongoid/contextual/geo_near_spec.rb +1 -1
  48. data/spec/mongoid/criteria_spec.rb +4 -0
  49. data/spec/mongoid/document_query_spec.rb +51 -0
  50. data/spec/mongoid/document_spec.rb +21 -1
  51. data/spec/mongoid/errors/invalid_config_file_spec.rb +32 -0
  52. data/spec/mongoid/errors/mongoid_error_spec.rb +20 -8
  53. data/spec/mongoid/factory_spec.rb +2 -2
  54. data/spec/mongoid/persistable/savable_spec.rb +4 -4
  55. data/spec/mongoid/persistable/settable_spec.rb +30 -0
  56. data/spec/mongoid/persistable/updatable_spec.rb +2 -0
  57. data/spec/mongoid/persistable_spec.rb +2 -2
  58. data/spec/shared/bin/get-mongodb-download-url +17 -0
  59. data/spec/shared/bin/s3-copy +45 -0
  60. data/spec/shared/bin/s3-upload +69 -0
  61. data/spec/shared/lib/mrss/cluster_config.rb +19 -4
  62. data/spec/shared/lib/mrss/constraints.rb +67 -12
  63. data/spec/shared/lib/mrss/docker_runner.rb +10 -1
  64. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  65. data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
  66. data/spec/shared/lib/mrss/server_version_registry.rb +84 -33
  67. data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
  68. data/spec/shared/lib/mrss/utils.rb +15 -0
  69. data/spec/shared/share/Dockerfile.erb +126 -32
  70. data/spec/shared/share/haproxy-1.conf +16 -0
  71. data/spec/shared/share/haproxy-2.conf +17 -0
  72. data/spec/shared/shlib/server.sh +123 -26
  73. data/spec/shared/shlib/set_env.sh +4 -1
  74. data/spec/spec_helper.rb +3 -1
  75. data/spec/support/constraints.rb +0 -226
  76. data/spec/support/spec_config.rb +8 -0
  77. data.tar.gz.sig +0 -0
  78. metadata +555 -503
  79. metadata.gz.sig +0 -0
  80. data/spec/support/child_process_helper.rb +0 -76
  81. data/spec/support/lite_constraints.rb +0 -22
@@ -753,12 +753,25 @@ describe Mongoid::Contextual::Atomic do
753
753
  context.set(name: "Recoil")
754
754
  end
755
755
 
756
- it "sets existing fields" do
757
- expect(depeche_mode.reload.name).to eq("Recoil")
756
+ shared_examples 'writes as expected' do
757
+ it "sets existing fields" do
758
+ expect(depeche_mode.reload.name).to eq("Recoil")
759
+ end
760
+
761
+ it "sets non existent fields" do
762
+ expect(smiths.reload.name).to eq("Recoil")
763
+ end
758
764
  end
759
765
 
760
- it "sets non existent fields" do
761
- expect(smiths.reload.name).to eq("Recoil")
766
+ include_examples 'writes as expected'
767
+
768
+ context 'when fields being set have been projected out' do
769
+
770
+ let(:criteria) do
771
+ Band.only(:genres)
772
+ end
773
+
774
+ include_examples 'writes as expected'
762
775
  end
763
776
  end
764
777
 
@@ -788,27 +801,28 @@ describe Mongoid::Contextual::Atomic do
788
801
  context.unset(:name)
789
802
  end
790
803
 
791
- it "unsets the first existing field" do
792
- expect(depeche_mode.reload.name).to be_nil
793
- end
794
-
795
- it "unsets the last existing field" do
796
- expect(new_order.reload.name).to be_nil
804
+ it "unsets the fields from all documents" do
805
+ depeche_mode.reload
806
+ new_order.reload
807
+ expect(depeche_mode.name).to be_nil
808
+ expect(depeche_mode.years).to_not be_nil
809
+ expect(new_order.name).to be_nil
810
+ expect(new_order.years).to_not be_nil
797
811
  end
798
812
  end
799
813
 
800
814
  context "when the field is aliased" do
801
-
802
815
  before do
803
816
  context.unset(:years)
804
817
  end
805
818
 
806
- it "unsets the first existing field" do
807
- expect(depeche_mode.reload.years).to be_nil
808
- end
809
-
810
- it "unsets the last existing field" do
811
- expect(new_order.reload.years).to be_nil
819
+ it "unsets the fields from all documents" do
820
+ depeche_mode.reload
821
+ new_order.reload
822
+ expect(depeche_mode.name).to_not be_nil
823
+ expect(depeche_mode.years).to be_nil
824
+ expect(new_order.name).to_not be_nil
825
+ expect(new_order.years).to be_nil
812
826
  end
813
827
  end
814
828
  end
@@ -816,7 +830,8 @@ describe Mongoid::Contextual::Atomic do
816
830
  context "when unsetting multiple fields" do
817
831
 
818
832
  let!(:new_order) do
819
- Band.create(name: "New Order", genres: [ "electro", "dub" ], years: 10)
833
+ Band.create(name: "New Order", genres: %w[electro dub], years: 10,
834
+ likes: 200, rating: 4.3, origin: 'Space')
820
835
  end
821
836
 
822
837
  let(:criteria) do
@@ -833,12 +848,13 @@ describe Mongoid::Contextual::Atomic do
833
848
  context.unset(:name, :genres)
834
849
  end
835
850
 
836
- it "unsets name field" do
837
- expect(new_order.reload.name).to be_nil
838
- end
839
-
840
- it "unsets genres field" do
841
- expect(new_order.reload.genres).to be_nil
851
+ it "unsets the specified fields" do
852
+ new_order.reload
853
+ expect(new_order.name).to be_nil
854
+ expect(new_order.genres).to be_nil
855
+ expect(new_order.years).to_not be_nil
856
+ expect(new_order.likes).to_not be_nil
857
+ expect(new_order.rating).to_not be_nil
842
858
  end
843
859
  end
844
860
 
@@ -848,12 +864,46 @@ describe Mongoid::Contextual::Atomic do
848
864
  context.unset(:name, :years)
849
865
  end
850
866
 
851
- it "unsets the unaliased field" do
852
- expect(new_order.reload.name).to be_nil
867
+ it "unsets the specified fields" do
868
+ new_order.reload
869
+ expect(new_order.name).to be_nil
870
+ expect(new_order.genres).to_not be_nil
871
+ expect(new_order.years).to be_nil
872
+ expect(new_order.likes).to_not be_nil
873
+ expect(new_order.rating).to_not be_nil
874
+ end
875
+ end
876
+
877
+ context "when using Hash arguments" do
878
+
879
+ before do
880
+ context.unset({ years: true, likes: "" }, { rating: false, origin: nil })
881
+ end
882
+
883
+ it "unsets the specified fields" do
884
+ new_order.reload
885
+ expect(new_order.name).to_not be_nil
886
+ expect(new_order.genres).to_not be_nil
887
+ expect(new_order.years).to be_nil
888
+ expect(new_order.likes).to be_nil
889
+ expect(new_order.rating).to be_nil
890
+ expect(new_order.origin).to be_nil
891
+ end
892
+ end
893
+
894
+ context "when mixing argument types" do
895
+
896
+ before do
897
+ context.unset(:name, [:years], { likes: "" }, { rating: false })
853
898
  end
854
899
 
855
- it "unsets the aliased field" do
856
- expect(new_order.reload.years).to be_nil
900
+ it "unsets the specified fields" do
901
+ new_order.reload
902
+ expect(new_order.name).to be_nil
903
+ expect(new_order.genres).to_not be_nil
904
+ expect(new_order.years).to be_nil
905
+ expect(new_order.likes).to be_nil
906
+ expect(new_order.rating).to be_nil
857
907
  end
858
908
  end
859
909
  end
@@ -882,7 +932,9 @@ describe Mongoid::Contextual::Atomic do
882
932
  end
883
933
 
884
934
  it "unsets the unaliased field" do
885
- expect(depeche_mode.reload.name).to be_nil
935
+ depeche_mode.reload
936
+ expect(depeche_mode.name).to be_nil
937
+ expect(depeche_mode.years).to_not be_nil
886
938
  end
887
939
  end
888
940
  end
@@ -59,7 +59,7 @@ describe Mongoid::Contextual::GeoNear do
59
59
  end
60
60
 
61
61
  it "is nil except for 4.0 sharded when it is 0" do
62
- expect(geo_near.average_distance).to be expected_value
62
+ expect(geo_near.average_distance).to eq expected_value
63
63
  end
64
64
  end
65
65
  end
@@ -3645,10 +3645,14 @@ describe Mongoid::Criteria do
3645
3645
 
3646
3646
  before do
3647
3647
  expect(Person).to receive(:minor).and_call_original
3648
+ expect(Person).to receive(:older_than).and_call_original
3648
3649
  end
3649
3650
 
3650
3651
  it "calls the method on the class" do
3651
3652
  expect(criteria.minor).to be_empty
3653
+ expect do
3654
+ criteria.older_than(age: 25)
3655
+ end.not_to raise_error
3652
3656
  end
3653
3657
  end
3654
3658
 
@@ -36,4 +36,55 @@ describe Mongoid::Document do
36
36
  expect(_person.age).to be 42
37
37
  end
38
38
  end
39
+
40
+ context 'when projecting with #without' do
41
+ before do
42
+ duck = Pet.new(name: 'Duck')
43
+ Person.create!(username: 'Dev', title: 'CEO', pet: duck)
44
+ end
45
+
46
+ let(:person) { Person.where(username: 'Dev').without(:title).first }
47
+
48
+ it 'allows access to attribute of embedded document' do
49
+ expect(person.pet.name).to eq 'Duck'
50
+ end
51
+
52
+ context 'when exclusion starts with association name but is not the association' do
53
+
54
+ let(:person) { Person.where(username: 'Dev').without(:pet_).first }
55
+
56
+ it 'allows access to attribute of embedded document' do
57
+ expect(person.pet.name).to eq 'Duck'
58
+ end
59
+ end
60
+
61
+ context 'when exclusion starts with prefix of association name' do
62
+
63
+ let(:person) { Person.where(username: 'Dev').without(:pe).first }
64
+
65
+ it 'allows access to attribute of embedded document' do
66
+ expect(person.pet.name).to eq 'Duck'
67
+ end
68
+ end
69
+
70
+ context 'when another attribute of the association is excluded' do
71
+
72
+ let(:person) { Person.where(username: 'Dev').without('pet.weight').first }
73
+
74
+ it 'allows access to non-excluded attribute of embedded document' do
75
+ expect(person.pet.name).to eq 'Duck'
76
+ end
77
+ end
78
+
79
+ context 'when the excluded attribute of the association is retrieved' do
80
+
81
+ let(:person) { Person.where(username: 'Dev').without('pet.name').first }
82
+
83
+ it 'prohibits the retrieval' do
84
+ lambda do
85
+ person.pet.name
86
+ end.should raise_error(ActiveModel::MissingAttributeError)
87
+ end
88
+ end
89
+ end
39
90
  end
@@ -458,7 +458,7 @@ describe Mongoid::Document do
458
458
  end
459
459
  end
460
460
 
461
- context ':compact option' do
461
+ context 'deprecated :compact option' do
462
462
  # Since rails 6 differs in how it treats id fields,
463
463
  # run this test on one version of rails. Currently rails 6 is in beta,
464
464
  # when it is released this version should be changed to 6.
@@ -470,6 +470,26 @@ describe Mongoid::Document do
470
470
  expect(church.as_json.keys.sort).to eq(%w(_id location name))
471
471
  end
472
472
 
473
+ context 'deprecation' do
474
+ let(:church) do
475
+ Church.create!(name: 'St. Basil')
476
+ end
477
+
478
+ let(:message) do
479
+ '#as_json :compact option is deprecated. Please call #compact on the returned Hash object instead.'
480
+ end
481
+
482
+ it 'logs a deprecation warning when :compact is given' do
483
+ expect_any_instance_of(Logger).to receive(:warn).with(message)
484
+ church.as_json(compact: true)
485
+ end
486
+
487
+ it 'does not log a deprecation warning when :compact is not given' do
488
+ expect_any_instance_of(Logger).to_not receive(:warn).with(message)
489
+ church.as_json
490
+ end
491
+ end
492
+
473
493
  context 'there is a nil valued attribute' do
474
494
  let(:church) do
475
495
  Church.create!(name: 'St. Basil')
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Errors::InvalidConfigFile do
7
+
8
+ describe "#message" do
9
+
10
+ let(:error) do
11
+ described_class.new('/my/path')
12
+ end
13
+
14
+ it "contains the problem in the message" do
15
+ expect(error.message).to include(
16
+ "Invalid configuration file: /my/path."
17
+ )
18
+ end
19
+
20
+ it "contains the summary in the message" do
21
+ expect(error.message).to include(
22
+ "Your mongoid.yml configuration file does not contain the"
23
+ )
24
+ end
25
+
26
+ it "contains the resolution in the message" do
27
+ expect(error.message).to include(
28
+ "Ensure your configuration file contains the correct contents."
29
+ )
30
+ end
31
+ end
32
+ end
@@ -10,14 +10,26 @@ describe Mongoid::Errors::MongoidError do
10
10
  let(:options) { {} }
11
11
 
12
12
  before do
13
- {"message_title" => "message", "summary_title" => "summary", "resolution_title" => "resolution"}.each do |key, name|
14
- expect(::I18n).to receive(:translate).with("mongoid.errors.messages.#{key}", {}).and_return(name)
15
- end
16
-
17
- ["message", "summary", "resolution"].each do |name|
18
- expect(::I18n).to receive(:translate).
19
- with("mongoid.errors.messages.#{key}.#{name}", {}).
20
- and_return(name)
13
+ if RUBY_VERSION.start_with?('3.', '2.7')
14
+ {"message_title" => "message", "summary_title" => "summary", "resolution_title" => "resolution"}.each do |key, name|
15
+ expect(::I18n).to receive(:translate).with("mongoid.errors.messages.#{key}", **{}).and_return(name)
16
+ end
17
+
18
+ ["message", "summary", "resolution"].each do |name|
19
+ expect(::I18n).to receive(:translate).
20
+ with("mongoid.errors.messages.#{key}.#{name}", **{}).
21
+ and_return(name)
22
+ end
23
+ else
24
+ {"message_title" => "message", "summary_title" => "summary", "resolution_title" => "resolution"}.each do |key, name|
25
+ expect(::I18n).to receive(:translate).with("mongoid.errors.messages.#{key}", {}).and_return(name)
26
+ end
27
+
28
+ ["message", "summary", "resolution"].each do |name|
29
+ expect(::I18n).to receive(:translate).
30
+ with("mongoid.errors.messages.#{key}.#{name}", {}).
31
+ and_return(name)
32
+ end
21
33
  end
22
34
 
23
35
  error.compose_message(key, options)
@@ -109,11 +109,11 @@ describe Mongoid::Factory do
109
109
  context "when the attributes are nil" do
110
110
 
111
111
  let(:document) do
112
- described_class.from_db(Address, nil)
112
+ described_class.from_db(Animal, nil)
113
113
  end
114
114
 
115
115
  it "generates based on the provided class" do
116
- expect(document).to be_a(Address)
116
+ expect(document).to be_a(Animal)
117
117
  end
118
118
 
119
119
  it "sets the attributes to empty" do
@@ -169,8 +169,8 @@ describe Mongoid::Persistable::Savable do
169
169
  Person.create(title: "Blah")
170
170
  end
171
171
 
172
- let!(:address) do
173
- person.addresses.build(street: "Bond St")
172
+ let!(:symptom) do
173
+ person.symptoms.build(name: "Headache")
174
174
  end
175
175
 
176
176
  let!(:name) do
@@ -193,7 +193,7 @@ describe Mongoid::Persistable::Savable do
193
193
  "name.first_name" => "Ryan"
194
194
  },
195
195
  "$push"=> {
196
- "addresses" => { '$each' => [ { "_id" => address.id, "street" => "Bond St" } ] }
196
+ "symptoms" => { '$each' => [ { "_id" => symptom.id, "name" => "Headache" } ] }
197
197
  }
198
198
  })
199
199
  end
@@ -205,7 +205,7 @@ describe Mongoid::Persistable::Savable do
205
205
  end
206
206
 
207
207
  it "saves embedded many relations" do
208
- expect(person.addresses.first.street).to eq("Bond St")
208
+ expect(person.symptoms.first.name).to eq("Headache")
209
209
  end
210
210
 
211
211
  it "saves embedded one relations" do
@@ -512,4 +512,34 @@ describe Mongoid::Persistable::Settable do
512
512
  end
513
513
  end
514
514
  end
515
+
516
+ context "when the field being set was projected out" do
517
+ let(:full_agent) do
518
+ Agent.create!(title: "Double-Oh Eight")
519
+ end
520
+
521
+ let(:agent) do
522
+ Agent.where(_id: full_agent.id).only(:dob).first
523
+ end
524
+
525
+ context 'field exists in database' do
526
+ it "raises MissingAttributeError" do
527
+ lambda do
528
+ agent.set(title: '008')
529
+ end.should raise_error(ActiveModel::MissingAttributeError)
530
+
531
+ expect(agent.reload.title).to eq 'Double-Oh Eight'
532
+ end
533
+ end
534
+
535
+ context 'field does not exist in database' do
536
+ it "raises MissingAttributeError" do
537
+ lambda do
538
+ agent.set(number: '008')
539
+ end.should raise_error(ActiveModel::MissingAttributeError)
540
+
541
+ expect(agent.reload.read_attribute(:number)).to be nil
542
+ end
543
+ end
544
+ end
515
545
  end
@@ -458,6 +458,7 @@ describe Mongoid::Persistable::Updatable do
458
458
  describe "##{method}" do
459
459
 
460
460
  context "when saving with a hash field with invalid keys" do
461
+ max_server_version '4.9'
461
462
 
462
463
  let(:person) do
463
464
  Person.create
@@ -494,6 +495,7 @@ describe Mongoid::Persistable::Updatable do
494
495
  end
495
496
 
496
497
  context "when the document has been destroyed" do
498
+ max_server_version '4.9'
497
499
 
498
500
  let(:person) do
499
501
  Person.create
@@ -178,8 +178,8 @@ describe Mongoid::Persistable do
178
178
 
179
179
  before do
180
180
  class Band
181
- def my_updates(*args)
182
- atomically(*args) do |d|
181
+ def my_updates(**args)
182
+ atomically(**args) do |d|
183
183
  d.set(name: "Placebo")
184
184
  d.unset(:origin)
185
185
  end