mongoid 8.0.2 → 8.0.4

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 (52) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +17 -15
  4. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +4 -0
  5. data/lib/mongoid/association/referenced/has_many/proxy.rb +4 -0
  6. data/lib/mongoid/cacheable.rb +2 -2
  7. data/lib/mongoid/criteria/queryable/extensions/array.rb +1 -1
  8. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -1
  9. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +0 -8
  10. data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -11
  11. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +0 -10
  12. data/lib/mongoid/criteria/translator.rb +45 -0
  13. data/lib/mongoid/criteria.rb +1 -0
  14. data/lib/mongoid/document.rb +50 -13
  15. data/lib/mongoid/extensions/big_decimal.rb +4 -0
  16. data/lib/mongoid/extensions/float.rb +6 -2
  17. data/lib/mongoid/extensions/integer.rb +6 -2
  18. data/lib/mongoid/factory.rb +21 -8
  19. data/lib/mongoid/fields/localized.rb +7 -2
  20. data/lib/mongoid/matcher.rb +21 -6
  21. data/lib/mongoid/persistence_context.rb +41 -5
  22. data/lib/mongoid/scopable.rb +9 -7
  23. data/lib/mongoid/shardable.rb +35 -11
  24. data/lib/mongoid/threaded.rb +33 -3
  25. data/lib/mongoid/traversable.rb +1 -1
  26. data/lib/mongoid/version.rb +1 -1
  27. data/spec/integration/i18n_fallbacks_spec.rb +1 -17
  28. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +37 -32
  29. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +143 -197
  30. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +102 -114
  31. data/spec/mongoid/attributes_spec.rb +2 -2
  32. data/spec/mongoid/cacheable_spec.rb +3 -3
  33. data/spec/mongoid/clients_spec.rb +25 -0
  34. data/spec/mongoid/contextual/memory_spec.rb +4 -5
  35. data/spec/mongoid/contextual/mongo_spec.rb +2 -4
  36. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +0 -59
  37. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  38. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -0
  39. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  40. data/spec/mongoid/criteria_projection_spec.rb +0 -1
  41. data/spec/mongoid/criteria_spec.rb +1 -1
  42. data/spec/mongoid/extensions/big_decimal_spec.rb +15 -0
  43. data/spec/mongoid/extensions/float_spec.rb +10 -3
  44. data/spec/mongoid/extensions/integer_spec.rb +10 -3
  45. data/spec/mongoid/fields/localized_spec.rb +37 -12
  46. data/spec/mongoid/shardable_models.rb +14 -0
  47. data/spec/mongoid/shardable_spec.rb +153 -61
  48. data/spec/mongoid/validatable/uniqueness_spec.rb +0 -1
  49. data/spec/support/macros.rb +16 -0
  50. data.tar.gz.sig +0 -0
  51. metadata +651 -643
  52. metadata.gz.sig +0 -0
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Mongoid::Criteria::Translator do
6
+ describe "#to_direction" do
7
+ context "when the value is a string" do
8
+ context "when ascending" do
9
+ it "returns 1" do
10
+ expect(described_class.to_direction("ascending")).to eq(1)
11
+ end
12
+ end
13
+
14
+ context "when asc" do
15
+ it "returns 1" do
16
+ expect(described_class.to_direction("asc")).to eq(1)
17
+ end
18
+ end
19
+
20
+ context "when ASCENDING" do
21
+ it "returns 1" do
22
+ expect(described_class.to_direction("ASCENDING")).to eq(1)
23
+ end
24
+ end
25
+
26
+ context "when ASC" do
27
+ it "returns 1" do
28
+ expect(described_class.to_direction("ASC")).to eq(1)
29
+ end
30
+ end
31
+
32
+ context "when descending" do
33
+ it "returns -1" do
34
+ expect(described_class.to_direction("descending")).to eq(-1)
35
+ end
36
+ end
37
+
38
+ context "when desc" do
39
+ it "returns -1" do
40
+ expect(described_class.to_direction("desc")).to eq(-1)
41
+ end
42
+ end
43
+
44
+ context "when DESCENDING" do
45
+ it "returns -1" do
46
+ expect(described_class.to_direction("DESCENDING")).to eq(-1)
47
+ end
48
+ end
49
+
50
+ context "when DESC" do
51
+ it "returns -1" do
52
+ expect(described_class.to_direction("DESC")).to eq(-1)
53
+ end
54
+ end
55
+ end
56
+
57
+ context "when the value is a symbol" do
58
+ context "when ascending" do
59
+ it "returns 1" do
60
+ expect(described_class.to_direction(:ascending)).to eq(1)
61
+ end
62
+ end
63
+
64
+ context "when asc" do
65
+ it "returns 1" do
66
+ expect(described_class.to_direction(:asc)).to eq(1)
67
+ end
68
+ end
69
+
70
+ context "when ASCENDING" do
71
+ it "returns 1" do
72
+ expect(described_class.to_direction(:ASCENDING)).to eq(1)
73
+ end
74
+ end
75
+
76
+ context "when ASC" do
77
+ it "returns 1" do
78
+ expect(described_class.to_direction(:ASC)).to eq(1)
79
+ end
80
+ end
81
+
82
+ context "when descending" do
83
+ it "returns -1" do
84
+ expect(described_class.to_direction(:descending)).to eq(-1)
85
+ end
86
+ end
87
+
88
+ context "when desc" do
89
+ it "returns -1" do
90
+ expect(described_class.to_direction(:desc)).to eq(-1)
91
+ end
92
+ end
93
+
94
+ context "when DESCENDING" do
95
+ it "returns -1" do
96
+ expect(described_class.to_direction(:DESCENDING)).to eq(-1)
97
+ end
98
+ end
99
+
100
+ context "when DESC" do
101
+ it "returns -1" do
102
+ expect(described_class.to_direction(:DESC)).to eq(-1)
103
+ end
104
+ end
105
+ end
106
+
107
+ context "when the value is numeric" do
108
+ it "should pass the value through unchanged" do
109
+ expect(described_class.to_direction(1)).to eq(1)
110
+ expect(described_class.to_direction(-1)).to eq(-1)
111
+ expect(described_class.to_direction(Math::PI)).to eq(Math::PI)
112
+ end
113
+ end
114
+
115
+ context "when the value is a hash" do
116
+ it "should pass the value through unchanged" do
117
+ expect(described_class.to_direction({})).to eq({})
118
+ expect(described_class.to_direction(scope: { "$meta" => "textScore" }))
119
+ .to eq(scope: { "$meta" => "textScore" })
120
+ expect(described_class.to_direction(a: 1, b: 2)).to eq(a: 1, b: 2)
121
+ end
122
+ end
123
+
124
+ context "when the value is an unrecognized type" do
125
+ it "should raise ArgumentError" do
126
+ expect { described_class.to_direction([]) }.to raise_error(ArgumentError)
127
+ expect { described_class.to_direction(/a/) }.to raise_error(ArgumentError)
128
+ expect { described_class.to_direction(Object.new) }.to raise_error(ArgumentError)
129
+ end
130
+ end
131
+ end
132
+ end
@@ -171,7 +171,6 @@ describe Mongoid::Criteria do
171
171
 
172
172
  let(:dictionary) do
173
173
  Dictionary.only(:description).first
174
-
175
174
  end
176
175
 
177
176
  it 'loads all translations' do
@@ -2059,7 +2059,7 @@ describe Mongoid::Criteria do
2059
2059
  end
2060
2060
 
2061
2061
  context 'when fallbacks are enabled with a locale list' do
2062
- require_fallbacks
2062
+ with_i18n_fallbacks
2063
2063
 
2064
2064
  around(:all) do |example|
2065
2065
  prev_fallbacks = I18n.fallbacks.dup
@@ -273,6 +273,21 @@ describe Mongoid::Extensions::BigDecimal do
273
273
  end
274
274
  end
275
275
 
276
+ context "when the value is castable" do
277
+
278
+ let(:value) do
279
+ 2.hours
280
+ end
281
+
282
+ before do
283
+ expect(value).to be_a(ActiveSupport::Duration)
284
+ end
285
+
286
+ it "returns nil" do
287
+ expect(mongoized).to eq(7200)
288
+ end
289
+ end
290
+
276
291
  context "when the value is nil" do
277
292
 
278
293
  let(:value) do
@@ -100,10 +100,10 @@ describe Mongoid::Extensions::Float do
100
100
  end
101
101
  end
102
102
 
103
- context "when the string is numerical" do
103
+ context "when the string starts with a number" do
104
104
 
105
- it "returns the float value for the string" do
106
- expect(Float.send(method, "3")).to eq(3)
105
+ it "returns nil" do
106
+ expect(Float.send(method, "42bogus")).to be_nil
107
107
  end
108
108
  end
109
109
 
@@ -120,6 +120,13 @@ describe Mongoid::Extensions::Float do
120
120
  expect(Float.send(method, nil)).to be_nil
121
121
  end
122
122
  end
123
+
124
+ context "when giving an object that is castable to an Float" do
125
+
126
+ it "returns the integer value" do
127
+ expect(Float.send(method, 2.hours)).to eq(7200)
128
+ end
129
+ end
123
130
  end
124
131
  end
125
132
  end
@@ -94,10 +94,10 @@ describe Mongoid::Extensions::Integer do
94
94
  end
95
95
  end
96
96
 
97
- context "when the string is numerical" do
97
+ context "when the string starts with a number" do
98
98
 
99
- it "returns the integer value for the string" do
100
- expect(Integer.send(method, "3")).to eq(3)
99
+ it "returns nil" do
100
+ expect(Integer.send(method, "42bogus")).to be_nil
101
101
  end
102
102
  end
103
103
 
@@ -114,6 +114,13 @@ describe Mongoid::Extensions::Integer do
114
114
  expect(Integer.send(method, nil)).to be_nil
115
115
  end
116
116
  end
117
+
118
+ context "when giving an object that is castable to an Integer" do
119
+
120
+ it "returns the integer value" do
121
+ expect(Integer.send(method, 2.hours)).to eq(7200)
122
+ end
123
+ end
117
124
  end
118
125
  end
119
126
  end
@@ -102,6 +102,29 @@ describe Mongoid::Fields::Localized do
102
102
  end
103
103
  end
104
104
 
105
+ context "when key is a symbol" do
106
+
107
+ let(:value) do
108
+ field.demongoize({ :de => "This is a test" })
109
+ end
110
+
111
+ it "returns the string from the set locale" do
112
+ expect(value).to eq("This is a test")
113
+ end
114
+ end
115
+
116
+
117
+ context "passing a bogus value" do
118
+
119
+ let(:value) do
120
+ field.demongoize("bogus")
121
+ end
122
+
123
+ it "returns nil" do
124
+ expect(value).to be_nil
125
+ end
126
+ end
127
+
105
128
  context "when the value does not exist" do
106
129
 
107
130
  context "when not using fallbacks" do
@@ -117,10 +140,7 @@ describe Mongoid::Fields::Localized do
117
140
 
118
141
  context "when using fallbacks" do
119
142
 
120
- before(:all) do
121
- require "i18n/backend/fallbacks"
122
- I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
123
- end
143
+ with_i18n_fallbacks
124
144
 
125
145
  context "when fallbacks are defined" do
126
146
 
@@ -139,6 +159,17 @@ describe Mongoid::Fields::Localized do
139
159
  end
140
160
  end
141
161
 
162
+ context "when the fallback translation exists and is a symbol" do
163
+
164
+ let(:value) do
165
+ field.demongoize({ :es => "testing" })
166
+ end
167
+
168
+ it "returns the fallback translation" do
169
+ expect(value).to eq("testing")
170
+ end
171
+ end
172
+
142
173
  context "when another fallback translation exists" do
143
174
 
144
175
  let(:value) do
@@ -275,10 +306,7 @@ describe Mongoid::Fields::Localized do
275
306
 
276
307
  context "when using fallbacks" do
277
308
 
278
- before(:all) do
279
- require "i18n/backend/fallbacks"
280
- I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
281
- end
309
+ with_i18n_fallbacks
282
310
 
283
311
  context "when fallbacks are defined" do
284
312
 
@@ -476,10 +504,7 @@ describe Mongoid::Fields::Localized do
476
504
 
477
505
  context "when fallbacks are defined" do
478
506
 
479
- before(:all) do
480
- require "i18n/backend/fallbacks"
481
- I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
482
- end
507
+ with_i18n_fallbacks
483
508
 
484
509
  context "when the lookup does not need to use fallbacks" do
485
510
 
@@ -59,3 +59,17 @@ end
59
59
  class SmNotSharded
60
60
  include Mongoid::Document
61
61
  end
62
+
63
+ class SmReviewAuthor
64
+ include Mongoid::Document
65
+ embedded_in :review, class_name: "SmReview", touch: false
66
+ field :name, type: String
67
+ end
68
+
69
+ class SmReview
70
+ include Mongoid::Document
71
+
72
+ embeds_one :author, class_name: "SmReviewAuthor"
73
+
74
+ shard_key "author.name" => 1
75
+ end
@@ -27,11 +27,11 @@ describe Mongoid::Shardable do
27
27
  context 'when full syntax is used' do
28
28
  context 'with symbol value' do
29
29
  it 'sets shard key fields to symbol value' do
30
- SmProducer.shard_key_fields.should == %i(age gender)
30
+ expect(SmProducer.shard_key_fields).to be == %i(age gender)
31
31
  end
32
32
 
33
33
  it 'sets shard config' do
34
- SmProducer.shard_config.should == {
34
+ expect(SmProducer.shard_config).to be == {
35
35
  key: {age: 1, gender: 'hashed'},
36
36
  options: {
37
37
  unique: true,
@@ -41,37 +41,37 @@ describe Mongoid::Shardable do
41
41
  end
42
42
 
43
43
  it 'keeps hashed as string' do
44
- SmProducer.shard_config[:key][:gender].should == 'hashed'
44
+ expect(SmProducer.shard_config[:key][:gender]).to be == 'hashed'
45
45
  end
46
46
  end
47
47
 
48
48
  context 'with string value' do
49
49
  it 'sets shard key fields to symbol value' do
50
- SmActor.shard_key_fields.should == %i(age gender hello)
50
+ expect(SmActor.shard_key_fields).to be == %i(age gender hello)
51
51
  end
52
52
 
53
53
  it 'sets shard config' do
54
- SmActor.shard_config.should == {
54
+ expect(SmActor.shard_config).to be == {
55
55
  key: {age: 1, gender: 'hashed', hello: 'hashed'},
56
56
  options: {},
57
57
  }
58
58
  end
59
59
 
60
60
  it 'sets hashed to string' do
61
- SmActor.shard_config[:key][:gender].should == 'hashed'
61
+ expect(SmActor.shard_config[:key][:gender]).to be == 'hashed'
62
62
  end
63
63
  end
64
64
 
65
65
  context 'when passed association name' do
66
66
  it 'uses foreign key as shard key in shard config' do
67
- SmDriver.shard_config.should == {
67
+ expect(SmDriver.shard_config).to be == {
68
68
  key: {age: 1, agency_id: 'hashed'},
69
69
  options: {},
70
70
  }
71
71
  end
72
72
 
73
73
  it 'uses foreign key as shard key in shard key fields' do
74
- SmDriver.shard_key_fields.should == %i(age agency_id)
74
+ expect(SmDriver.shard_key_fields).to be == %i(age agency_id)
75
75
  end
76
76
  end
77
77
  end
@@ -79,26 +79,26 @@ describe Mongoid::Shardable do
79
79
  context 'when shorthand syntax is used' do
80
80
  context 'with symbol value' do
81
81
  it 'sets shard key fields to symbol value' do
82
- SmMovie.shard_key_fields.should == %i(year)
82
+ expect(SmMovie.shard_key_fields).to be == %i(year)
83
83
  end
84
84
  end
85
85
 
86
86
  context 'with string value' do
87
87
  it 'sets shard key fields to symbol value' do
88
- SmTrailer.shard_key_fields.should == %i(year)
88
+ expect(SmTrailer.shard_key_fields).to be == %i(year)
89
89
  end
90
90
  end
91
91
 
92
92
  context 'when passed association name' do
93
93
  it 'uses foreign key as shard key in shard config' do
94
- SmDirector.shard_config.should == {
94
+ expect(SmDirector.shard_config).to be == {
95
95
  key: {agency_id: 1},
96
96
  options: {},
97
97
  }
98
98
  end
99
99
 
100
100
  it 'uses foreign key as shard key in shard key fields' do
101
- SmDirector.shard_key_fields.should == %i(agency_id)
101
+ expect(SmDirector.shard_key_fields).to be == %i(agency_id)
102
102
  end
103
103
  end
104
104
  end
@@ -106,41 +106,80 @@ describe Mongoid::Shardable do
106
106
 
107
107
  describe '#shard_key_selector' do
108
108
  subject { instance.shard_key_selector }
109
- let(:klass) { Band }
110
- let(:value) { 'a-brand-name' }
109
+
110
+ context 'when key is an immediate attribute' do
111
+ let(:klass) { Band }
112
+ let(:value) { 'a-brand-name' }
111
113
 
112
- before { klass.shard_key(:name) }
114
+ before { klass.shard_key(:name) }
113
115
 
114
- context 'when record is new' do
115
- let(:instance) { klass.new(name: value) }
116
+ context 'when record is new' do
117
+ let(:instance) { klass.new(name: value) }
116
118
 
117
- it { is_expected.to eq({ 'name' => value }) }
119
+ it { is_expected.to eq({ 'name' => value }) }
118
120
 
119
- context 'changing shard key value' do
120
- let(:new_value) { 'a-new-value' }
121
+ context 'changing shard key value' do
122
+ let(:new_value) { 'a-new-value' }
121
123
 
122
- before do
123
- instance.name = new_value
124
+ before do
125
+ instance.name = new_value
126
+ end
127
+
128
+ it { is_expected.to eq({ 'name' => new_value }) }
124
129
  end
130
+ end
131
+
132
+ context 'when record is persisted' do
133
+ let(:instance) { klass.create!(name: value) }
125
134
 
126
- it { is_expected.to eq({ 'name' => new_value }) }
135
+ it { is_expected.to eq({ 'name' => value }) }
136
+
137
+ context 'changing shard key value' do
138
+ let(:new_value) { 'a-new-value' }
139
+
140
+ before do
141
+ instance.name = new_value
142
+ end
143
+
144
+ it { is_expected.to eq({ 'name' => new_value }) }
145
+ end
127
146
  end
128
147
  end
129
148
 
130
- context 'when record is persisted' do
131
- let(:instance) { klass.create!(name: value) }
149
+ context 'when key is an embedded attribute' do
150
+ let(:klass) { SmReview }
151
+ let(:value) { 'Arthur Conan Doyle' }
152
+ let(:key) { 'author.name' }
132
153
 
133
- it { is_expected.to eq({ 'name' => value }) }
154
+ context 'when record is new' do
155
+ let(:instance) { klass.new(author: { name: value }) }
134
156
 
135
- context 'changing shard key value' do
136
- let(:new_value) { 'a-new-value' }
157
+ it { is_expected.to eq({ key => value }) }
137
158
 
138
- before do
139
- instance.name = new_value
159
+ context 'changing shard key value' do
160
+ let(:new_value) { 'Jules Verne' }
161
+
162
+ before do
163
+ instance.author.name = new_value
164
+ end
165
+
166
+ it { is_expected.to eq({ key => new_value }) }
140
167
  end
168
+ end
169
+
170
+ context 'when record is persisted' do
171
+ let(:instance) { klass.create!(author: { name: value }) }
172
+
173
+ it { is_expected.to eq({ key => value }) }
174
+
175
+ context 'changing shard key value' do
176
+ let(:new_value) { 'Jules Verne' }
141
177
 
142
- it 'uses the newly set shard key value' do
143
- subject.should == { 'name' => new_value }
178
+ before do
179
+ instance.author.name = new_value
180
+ end
181
+
182
+ it { is_expected.to eq({ 'author.name' => new_value }) }
144
183
  end
145
184
  end
146
185
  end
@@ -148,56 +187,109 @@ describe Mongoid::Shardable do
148
187
 
149
188
  describe '#shard_key_selector_in_db' do
150
189
  subject { instance.shard_key_selector_in_db }
151
- let(:klass) { Band }
152
- let(:value) { 'a-brand-name' }
153
190
 
154
- before { klass.shard_key(:name) }
191
+ context 'when key is an immediate attribute' do
192
+ let(:klass) { Band }
193
+ let(:value) { 'a-brand-name' }
155
194
 
156
- context 'when record is new' do
157
- let(:instance) { klass.new(name: value) }
195
+ before { klass.shard_key(:name) }
158
196
 
159
- it { is_expected.to eq({ 'name' => value }) }
197
+ context 'when record is new' do
198
+ let(:instance) { klass.new(name: value) }
160
199
 
161
- context 'changing shard key value' do
162
- let(:new_value) { 'a-new-value' }
200
+ it { is_expected.to eq({ 'name' => value }) }
163
201
 
164
- before do
165
- instance.name = new_value
166
- end
202
+ context 'changing shard key value' do
203
+ let(:new_value) { 'a-new-value' }
204
+
205
+ before do
206
+ instance.name = new_value
207
+ end
167
208
 
168
- it 'uses the existing shard key value' do
169
- subject.should == { 'name' => new_value }
209
+ it { is_expected.to eq({ 'name' => new_value }) }
170
210
  end
171
211
  end
172
- end
173
212
 
174
- context 'when record is persisted' do
175
- let(:instance) { klass.create!(name: value) }
213
+ context 'when record is persisted' do
214
+ let(:instance) { klass.create!(name: value) }
215
+
216
+ it { is_expected.to eq({ 'name' => value }) }
217
+
218
+ context 'changing shard key value' do
219
+ let(:new_value) { 'a-new-value' }
176
220
 
177
- it { is_expected.to eq({ 'name' => value }) }
221
+ before do
222
+ instance.name = new_value
223
+ end
178
224
 
179
- context 'changing shard key value' do
180
- let(:new_value) { 'a-new-value' }
225
+ it { is_expected.to eq({ 'name' => value }) }
226
+ end
227
+ end
228
+
229
+ context "when record is not found" do
230
+ let!(:instance) { klass.create!(name: value) }
181
231
 
182
232
  before do
183
- instance.name = new_value
233
+ instance.destroy
184
234
  end
185
235
 
186
- it { is_expected.to eq({ 'name' => value }) }
236
+ it "raises a DocumentNotFound error with the shard key in the description on reload" do
237
+ expect do
238
+ instance.reload
239
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Band with id #{instance.id.to_s} and shard key name: a-brand-name./)
240
+ end
187
241
  end
188
242
  end
189
243
 
190
- context "when record is not found" do
191
- let!(:instance) { klass.create!(name: value) }
244
+ context 'when key is an embedded attribute' do
245
+ let(:klass) { SmReview }
246
+ let(:value) { 'Arthur Conan Doyle' }
247
+ let(:key) { 'author.name' }
248
+
249
+ context 'when record is new' do
250
+ let(:instance) { klass.new(author: { name: value }) }
251
+
252
+ it { is_expected.to eq({ key => value }) }
192
253
 
193
- before do
194
- instance.destroy
254
+ context 'changing shard key value' do
255
+ let(:new_value) { 'Jules Verne' }
256
+
257
+ before do
258
+ instance.author.name = new_value
259
+ end
260
+
261
+ it { is_expected.to eq({ key => new_value }) }
262
+ end
195
263
  end
196
264
 
197
- it "raises a DocumentNotFound error with the shard key in the description on reload" do
198
- expect do
199
- instance.reload
200
- end.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Band with id #{instance.id.to_s} and shard key name: a-brand-name./)
265
+ context 'when record is persisted' do
266
+ let(:instance) { klass.create!(author: { name: value }) }
267
+
268
+ it { is_expected.to eq({ key => value }) }
269
+
270
+ context 'changing shard key value' do
271
+ let(:new_value) { 'Jules Verne' }
272
+
273
+ before do
274
+ instance.author.name = new_value
275
+ end
276
+
277
+ it { is_expected.to eq({ key => value }) }
278
+ end
279
+
280
+ context "when record is not found" do
281
+ let!(:instance) { klass.create!(author: { name: value }) }
282
+
283
+ before do
284
+ instance.destroy
285
+ end
286
+
287
+ it "raises a DocumentNotFound error with the shard key in the description on reload" do
288
+ expect do
289
+ instance.reload
290
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class SmReview with id #{instance.id.to_s} and shard key author.name: Arthur Conan Doyle./)
291
+ end
292
+ end
201
293
  end
202
294
  end
203
295
  end
@@ -2476,7 +2476,6 @@ describe Mongoid::Validatable::UniquenessValidator do
2476
2476
  describe "i18n" do
2477
2477
 
2478
2478
  context 'when using a different locale' do
2479
-
2480
2479
  around do |example|
2481
2480
  I18n.with_locale(:fr) { example.run }
2482
2481
  end