mongoid-history 0.8.3 → 0.8.5
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
- data/.coveralls.yml +1 -1
- data/.document +5 -5
- data/.github/workflows/test.yml +72 -0
- data/.gitignore +46 -46
- data/.rspec +2 -2
- data/.rubocop.yml +6 -6
- data/.rubocop_todo.yml +99 -99
- data/CHANGELOG.md +173 -163
- data/CONTRIBUTING.md +117 -118
- data/Dangerfile +1 -1
- data/Gemfile +49 -40
- data/LICENSE.txt +20 -20
- data/README.md +609 -608
- data/RELEASING.md +66 -67
- data/Rakefile +24 -24
- data/UPGRADING.md +53 -53
- data/lib/mongoid/history/attributes/base.rb +72 -72
- data/lib/mongoid/history/attributes/create.rb +45 -45
- data/lib/mongoid/history/attributes/destroy.rb +34 -34
- data/lib/mongoid/history/attributes/update.rb +104 -104
- data/lib/mongoid/history/options.rb +177 -177
- data/lib/mongoid/history/trackable.rb +588 -583
- data/lib/mongoid/history/tracker.rb +247 -247
- data/lib/mongoid/history/version.rb +5 -5
- data/lib/mongoid/history.rb +77 -77
- data/lib/mongoid-history.rb +1 -1
- data/mongoid-history.gemspec +25 -25
- data/perf/benchmark_modified_attributes_for_create.rb +65 -65
- data/perf/gc_suite.rb +21 -21
- data/spec/integration/embedded_in_polymorphic_spec.rb +112 -112
- data/spec/integration/integration_spec.rb +976 -976
- data/spec/integration/multi_relation_spec.rb +47 -47
- data/spec/integration/multiple_trackers_spec.rb +68 -68
- data/spec/integration/nested_embedded_documents_spec.rb +64 -64
- data/spec/integration/nested_embedded_documents_tracked_in_parent_spec.rb +124 -124
- data/spec/integration/nested_embedded_polymorphic_documents_spec.rb +115 -115
- data/spec/integration/subclasses_spec.rb +47 -47
- data/spec/integration/track_history_order_spec.rb +84 -84
- data/spec/integration/validation_failure_spec.rb +76 -76
- data/spec/spec_helper.rb +32 -30
- data/spec/support/error_helpers.rb +7 -0
- data/spec/support/mongoid.rb +11 -11
- data/spec/support/mongoid_history.rb +12 -12
- data/spec/unit/attributes/base_spec.rb +141 -141
- data/spec/unit/attributes/create_spec.rb +342 -342
- data/spec/unit/attributes/destroy_spec.rb +228 -228
- data/spec/unit/attributes/update_spec.rb +342 -342
- data/spec/unit/callback_options_spec.rb +165 -165
- data/spec/unit/embedded_methods_spec.rb +87 -87
- data/spec/unit/history_spec.rb +58 -58
- data/spec/unit/my_instance_methods_spec.rb +555 -555
- data/spec/unit/options_spec.rb +365 -365
- data/spec/unit/singleton_methods_spec.rb +406 -406
- data/spec/unit/store/default_store_spec.rb +11 -11
- data/spec/unit/store/request_store_spec.rb +13 -13
- data/spec/unit/trackable_spec.rb +1057 -987
- data/spec/unit/tracker_spec.rb +190 -190
- metadata +9 -7
- data/.travis.yml +0 -36
@@ -1,555 +1,555 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Mongoid::History::Trackable do
|
4
|
-
describe 'MyInstanceMethods' do
|
5
|
-
before :each do
|
6
|
-
class ModelOne
|
7
|
-
include Mongoid::Document
|
8
|
-
include Mongoid::History::Trackable
|
9
|
-
|
10
|
-
store_in collection: :model_ones
|
11
|
-
|
12
|
-
field :foo
|
13
|
-
field :b, as: :bar
|
14
|
-
|
15
|
-
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
16
|
-
embeds_one :emb_one
|
17
|
-
embeds_one :emb_two, store_as: :emt
|
18
|
-
embeds_many :emb_threes
|
19
|
-
embeds_many :emb_fours, store_as: :emfs
|
20
|
-
else
|
21
|
-
embeds_one :emb_one, inverse_class_name: 'EmbOne'
|
22
|
-
embeds_one :emb_two, store_as: :emt, inverse_class_name: 'EmbTwo'
|
23
|
-
embeds_many :emb_threes, inverse_class_name: 'EmbThree'
|
24
|
-
embeds_many :emb_fours, store_as: :emfs, inverse_class_name: 'EmbFour'
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class EmbOne
|
29
|
-
include Mongoid::Document
|
30
|
-
include Mongoid::History::Trackable
|
31
|
-
|
32
|
-
field :f_em_foo
|
33
|
-
field :fmb, as: :f_em_bar
|
34
|
-
|
35
|
-
embedded_in :model_one
|
36
|
-
end
|
37
|
-
|
38
|
-
class EmbTwo
|
39
|
-
include Mongoid::Document
|
40
|
-
include Mongoid::History::Trackable
|
41
|
-
|
42
|
-
field :baz
|
43
|
-
embedded_in :model_one
|
44
|
-
end
|
45
|
-
|
46
|
-
class EmbThree
|
47
|
-
include Mongoid::Document
|
48
|
-
include Mongoid::History::Trackable
|
49
|
-
|
50
|
-
field :f_em_foo
|
51
|
-
field :fmb, as: :f_em_bar
|
52
|
-
|
53
|
-
embedded_in :model_one
|
54
|
-
end
|
55
|
-
|
56
|
-
class EmbFour
|
57
|
-
include Mongoid::Document
|
58
|
-
include Mongoid::History::Trackable
|
59
|
-
|
60
|
-
field :baz
|
61
|
-
embedded_in :model_one
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
after :each do
|
66
|
-
Object.send(:remove_const, :ModelOne)
|
67
|
-
Object.send(:remove_const, :EmbOne)
|
68
|
-
Object.send(:remove_const, :EmbTwo)
|
69
|
-
Object.send(:remove_const, :EmbThree)
|
70
|
-
Object.send(:remove_const, :EmbFour)
|
71
|
-
end
|
72
|
-
|
73
|
-
let(:bson_class) { defined?(BSON::ObjectId) ? BSON::ObjectId : Moped::BSON::ObjectId }
|
74
|
-
|
75
|
-
let(:emb_one) { EmbOne.new(f_em_foo: 'Foo', f_em_bar: 'Bar') }
|
76
|
-
let(:emb_threes) { [EmbThree.new(f_em_foo: 'Foo', f_em_bar: 'Bar')] }
|
77
|
-
let(:model_one) { ModelOne.new(foo: 'Foo', bar: 'Bar', emb_one: emb_one, emb_threes: emb_threes) }
|
78
|
-
|
79
|
-
describe '#modified_attributes_for_create' do
|
80
|
-
before :each do
|
81
|
-
ModelOne.track_history modifier_field_optional: true, on: %i[foo emb_one emb_threes]
|
82
|
-
end
|
83
|
-
|
84
|
-
subject { model_one.send(:modified_attributes_for_create) }
|
85
|
-
|
86
|
-
context 'with tracked embeds_one object' do
|
87
|
-
before :each do
|
88
|
-
ModelOne.track_history(modifier_field_optional: true, on: { emb_one: :f_em_foo })
|
89
|
-
end
|
90
|
-
it 'should include tracked attributes only' do
|
91
|
-
expect(subject['emb_one'][0]).to be_nil
|
92
|
-
|
93
|
-
expect(subject['emb_one'][1].keys.size).to eq 2
|
94
|
-
expect(subject['emb_one'][1]['_id']).to eq emb_one._id
|
95
|
-
expect(subject['emb_one'][1]['f_em_foo']).to eq 'Foo'
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
context 'with untracked embeds_one object' do
|
100
|
-
before :each do
|
101
|
-
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
102
|
-
end
|
103
|
-
it 'should not include embeds_one attributes' do
|
104
|
-
expect(subject['emb_one']).to be_nil
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
context 'with tracked embeds_many objects' do
|
109
|
-
before :each do
|
110
|
-
ModelOne.track_history(modifier_field_optional: true, on: { emb_threes: :f_em_foo })
|
111
|
-
end
|
112
|
-
it 'should include tracked attributes only' do
|
113
|
-
expect(subject['emb_threes'][0]).to be_nil
|
114
|
-
|
115
|
-
expect(subject['emb_threes'][1][0].keys.count).to eq 2
|
116
|
-
expect(subject['emb_threes'][1][0]['_id']).to eq emb_threes.first._id
|
117
|
-
expect(subject['emb_threes'][1][0]['f_em_foo']).to eq 'Foo'
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'with untracked embeds_many objects' do
|
122
|
-
before :each do
|
123
|
-
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
124
|
-
end
|
125
|
-
it 'should include not tracked embeds_many attributes' do
|
126
|
-
expect(subject['emb_threes']).to be_nil
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
context 'when embeds_one object blank' do
|
131
|
-
let(:emb_one) { nil }
|
132
|
-
|
133
|
-
it 'should not include embeds_one model key' do
|
134
|
-
expect(subject.keys).to_not include 'emb_one'
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
describe 'embeds_one' do
|
139
|
-
before :each do
|
140
|
-
class Mail
|
141
|
-
include Mongoid::Document
|
142
|
-
include Mongoid::History::Trackable
|
143
|
-
|
144
|
-
store_in collection: :mails
|
145
|
-
field :provider
|
146
|
-
|
147
|
-
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
148
|
-
embeds_one :mail_subject
|
149
|
-
else
|
150
|
-
embeds_one :mail_subject, inverse_class_name: 'MailSubject'
|
151
|
-
end
|
152
|
-
|
153
|
-
track_history on: :mail_subject
|
154
|
-
end
|
155
|
-
|
156
|
-
class MailSubject
|
157
|
-
include Mongoid::Document
|
158
|
-
|
159
|
-
field :content
|
160
|
-
embedded_in :mail
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
after :each do
|
165
|
-
Object.send(:remove_const, :MailSubject)
|
166
|
-
Object.send(:remove_const, :Mail)
|
167
|
-
end
|
168
|
-
|
169
|
-
let(:mail) { Mail.new(mail_subject: mail_subject) }
|
170
|
-
let(:mail_subject) { nil }
|
171
|
-
subject { mail.send(:modified_attributes_for_create)['mail_subject'] }
|
172
|
-
|
173
|
-
context 'when obj not built' do
|
174
|
-
it { is_expected.to be_nil }
|
175
|
-
end
|
176
|
-
|
177
|
-
context 'when obj does not respond to paranoia_field' do
|
178
|
-
let(:mail_subject) { MailSubject.new(content: 'Content') }
|
179
|
-
it { is_expected.to eq [nil, { '_id' => mail_subject._id, 'content' => 'Content' }] }
|
180
|
-
end
|
181
|
-
|
182
|
-
context 'when obj not soft-deleted' do
|
183
|
-
before :each do
|
184
|
-
allow(mail_subject).to receive(:deleted_at) { nil }
|
185
|
-
end
|
186
|
-
let(:mail_subject) { MailSubject.new(content: 'Content') }
|
187
|
-
it { is_expected.to eq [nil, { '_id' => mail_subject._id, 'content' => 'Content' }] }
|
188
|
-
end
|
189
|
-
|
190
|
-
context 'when obj soft-deleted' do
|
191
|
-
before :each do
|
192
|
-
allow(mail_subject).to receive(:deleted_at) { Time.now }
|
193
|
-
end
|
194
|
-
let(:mail_subject) { MailSubject.new(content: 'Content') }
|
195
|
-
it { is_expected.to be_nil }
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
describe 'paranoia' do
|
200
|
-
before :each do
|
201
|
-
class ModelParanoia
|
202
|
-
include Mongoid::Document
|
203
|
-
include Mongoid::History::Trackable
|
204
|
-
|
205
|
-
store_in collection: :model_paranoias
|
206
|
-
|
207
|
-
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
208
|
-
embeds_many :emb_para_ones
|
209
|
-
else
|
210
|
-
embeds_many :emb_para_ones, inverse_class_name: 'EmbParaOne'
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
class EmbParaOne
|
215
|
-
include Mongoid::Document
|
216
|
-
|
217
|
-
field :em_foo
|
218
|
-
field :deleted_at
|
219
|
-
|
220
|
-
embedded_in :model_paranoia
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
after :each do
|
225
|
-
Object.send(:remove_const, :ModelParanoia)
|
226
|
-
Object.send(:remove_const, :EmbParaOne)
|
227
|
-
end
|
228
|
-
|
229
|
-
let(:emb_para_one) { EmbParaOne.new(em_foo: 'Em-Foo') }
|
230
|
-
let(:model_paranoia) { ModelParanoia.new(emb_para_ones: [emb_para_one]) }
|
231
|
-
|
232
|
-
context 'when does not respond to paranoia_field' do
|
233
|
-
before :each do
|
234
|
-
ModelParanoia.track_history(on: :emb_para_ones)
|
235
|
-
end
|
236
|
-
|
237
|
-
subject { model_paranoia.send(:modified_attributes_for_create) }
|
238
|
-
|
239
|
-
it 'should include tracked embeds_many objects attributes' do
|
240
|
-
expect(subject['emb_para_ones'][0]).to be_nil
|
241
|
-
expect(subject['emb_para_ones'][1].size).to eq 1
|
242
|
-
expect(subject['emb_para_ones'][1][0]['_id']).to be_a bson_class
|
243
|
-
expect(subject['emb_para_ones'][1][0]['em_foo']).to eq 'Em-Foo'
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
context 'when responds to paranoia_field' do
|
248
|
-
before :each do
|
249
|
-
ModelParanoia.track_history(on: :emb_para_ones)
|
250
|
-
allow(emb_para_one).to receive(:deleted_at) { Time.now }
|
251
|
-
allow(emb_para_one_2).to receive(:deleted_at) { nil }
|
252
|
-
end
|
253
|
-
|
254
|
-
let(:model_paranoia) { ModelParanoia.new(emb_para_ones: [emb_para_one, emb_para_one_2]) }
|
255
|
-
let(:emb_para_one) { EmbParaOne.new(em_foo: 'Em-Foo') }
|
256
|
-
let(:emb_para_one_2) { EmbParaOne.new(em_foo: 'Em-Foo-2') }
|
257
|
-
|
258
|
-
subject { model_paranoia.send(:modified_attributes_for_create) }
|
259
|
-
|
260
|
-
it 'should not include deleted objects attributes' do
|
261
|
-
expect(subject['emb_para_ones'][0]).to be_nil
|
262
|
-
expect(subject['emb_para_ones'][1]).to eq [{ '_id' => emb_para_one_2._id, 'em_foo' => 'Em-Foo-2' }]
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
describe '#modified_attributes_for_update' do
|
269
|
-
before :each do
|
270
|
-
model_one.save!
|
271
|
-
allow(ModelOne).to receive(:dynamic_enabled?) { false }
|
272
|
-
allow(model_one).to receive(:changes) { changes }
|
273
|
-
end
|
274
|
-
let(:changes) { {} }
|
275
|
-
subject { model_one.send(:modified_attributes_for_update) }
|
276
|
-
|
277
|
-
context 'when embeds_one attributes passed in options' do
|
278
|
-
before :each do
|
279
|
-
ModelOne.track_history(modifier_field_optional: true, on: { emb_one: :f_em_foo })
|
280
|
-
end
|
281
|
-
let(:changes) { { 'emb_one' => [{ 'f_em_foo' => 'Foo', 'fmb' => 'Bar' }, { 'f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new' }] } }
|
282
|
-
it { expect(subject['emb_one'][0]).to eq('f_em_foo' => 'Foo') }
|
283
|
-
it { expect(subject['emb_one'][1]).to eq('f_em_foo' => 'Foo-new') }
|
284
|
-
end
|
285
|
-
|
286
|
-
context 'when embeds_one relation passed in options' do
|
287
|
-
before :each do
|
288
|
-
ModelOne.track_history(modifier_field_optional: true, on: :emb_one)
|
289
|
-
end
|
290
|
-
let(:changes) { { 'emb_one' => [{ 'f_em_foo' => 'Foo', 'fmb' => 'Bar' }, { 'f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new' }] } }
|
291
|
-
it { expect(subject['emb_one'][0]).to eq('f_em_foo' => 'Foo', 'fmb' => 'Bar') }
|
292
|
-
it { expect(subject['emb_one'][1]).to eq('f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new') }
|
293
|
-
end
|
294
|
-
|
295
|
-
context 'when embeds_one relation not tracked' do
|
296
|
-
before :each do
|
297
|
-
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
298
|
-
end
|
299
|
-
let(:changes) { { 'emb_one' => [{ 'f_em_foo' => 'Foo' }, { 'f_em_foo' => 'Foo-new' }] } }
|
300
|
-
it { expect(subject['emb_one']).to be_nil }
|
301
|
-
end
|
302
|
-
|
303
|
-
context 'when embeds_many attributes passed in options' do
|
304
|
-
before :each do
|
305
|
-
ModelOne.track_history(modifier_field_optional: true, on: { emb_threes: :f_em_foo })
|
306
|
-
end
|
307
|
-
let(:changes) { { 'emb_threes' => [[{ 'f_em_foo' => 'Foo', 'fmb' => 'Bar' }], [{ 'f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new' }]] } }
|
308
|
-
it { expect(subject['emb_threes']).to eq [[{ 'f_em_foo' => 'Foo' }], [{ 'f_em_foo' => 'Foo-new' }]] }
|
309
|
-
end
|
310
|
-
|
311
|
-
context 'when embeds_many relation passed in options' do
|
312
|
-
before :each do
|
313
|
-
ModelOne.track_history(modifier_field_optional: true, on: :emb_threes)
|
314
|
-
end
|
315
|
-
let(:changes) { { 'emb_threes' => [[{ 'f_em_foo' => 'Foo', 'fmb' => 'Bar' }], [{ 'f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new' }]] } }
|
316
|
-
it { expect(subject['emb_threes']).to eq [[{ 'f_em_foo' => 'Foo', 'fmb' => 'Bar' }], [{ 'f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new' }]] }
|
317
|
-
end
|
318
|
-
|
319
|
-
context 'when embeds_many relation not tracked' do
|
320
|
-
before :each do
|
321
|
-
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
322
|
-
end
|
323
|
-
let(:changes) { { 'emb_threes' => [[{ 'f_em_foo' => 'Foo' }], [{ 'f_em_foo' => 'Foo-new' }]] } }
|
324
|
-
it { expect(subject['emb_threes']).to be_nil }
|
325
|
-
end
|
326
|
-
|
327
|
-
context 'when field tracked' do
|
328
|
-
before :each do
|
329
|
-
ModelOne.track_history(modifier_field_optional: true, on: :foo)
|
330
|
-
end
|
331
|
-
let(:changes) { { 'foo' => ['Foo', 'Foo-new'], 'b' => ['Bar', 'Bar-new'] } }
|
332
|
-
it { is_expected.to eq('foo' => ['Foo', 'Foo-new']) }
|
333
|
-
end
|
334
|
-
|
335
|
-
context 'when field not tracked' do
|
336
|
-
before :each do
|
337
|
-
ModelOne.track_history(modifier_field_optional: true, on: [])
|
338
|
-
end
|
339
|
-
let(:changes) { { 'foo' => ['Foo', 'Foo-new'] } }
|
340
|
-
it { is_expected.to eq({}) }
|
341
|
-
end
|
342
|
-
|
343
|
-
describe 'embeds_one' do
|
344
|
-
before :each do
|
345
|
-
class Email
|
346
|
-
include Mongoid::Document
|
347
|
-
include Mongoid::History::Trackable
|
348
|
-
|
349
|
-
store_in collection: :emails
|
350
|
-
field :provider
|
351
|
-
|
352
|
-
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
353
|
-
embeds_one :email_subject
|
354
|
-
else
|
355
|
-
embeds_one :email_subject, inverse_class_name: 'EmailSubject'
|
356
|
-
end
|
357
|
-
|
358
|
-
track_history on: :email_subject
|
359
|
-
end
|
360
|
-
|
361
|
-
class EmailSubject
|
362
|
-
include Mongoid::Document
|
363
|
-
include Mongoid::History::Trackable
|
364
|
-
|
365
|
-
field :content
|
366
|
-
embedded_in :email_subject
|
367
|
-
end
|
368
|
-
end
|
369
|
-
|
370
|
-
after :each do
|
371
|
-
Object.send(:remove_const, :EmailSubject)
|
372
|
-
Object.send(:remove_const, :Email)
|
373
|
-
end
|
374
|
-
|
375
|
-
before :each do
|
376
|
-
allow(Email).to receive(:dynamic_enabled?) { false }
|
377
|
-
allow(email).to receive(:changes) { changes }
|
378
|
-
end
|
379
|
-
|
380
|
-
let(:email) { Email.new }
|
381
|
-
let(:changes) { {} }
|
382
|
-
subject { email.send(:modified_attributes_for_update)['email_subject'] }
|
383
|
-
|
384
|
-
context 'when paranoia_field not present' do
|
385
|
-
let(:changes) { { 'email_subject' => [{ 'content' => 'Content' }, { 'content' => 'Content-new' }] } }
|
386
|
-
it { is_expected.to eq [{ 'content' => 'Content' }, { 'content' => 'Content-new' }] }
|
387
|
-
end
|
388
|
-
|
389
|
-
context 'when older soft-deleted' do
|
390
|
-
let(:changes) { { 'email_subject' => [{ 'content' => 'Content', 'deleted_at' => Time.now }, { 'content' => 'Content-new' }] } }
|
391
|
-
it { is_expected.to eq [{}, { 'content' => 'Content-new' }] }
|
392
|
-
end
|
393
|
-
|
394
|
-
context 'when new soft-deleted' do
|
395
|
-
let(:changes) { { 'email_subject' => [{ 'content' => 'Content' }, { 'content' => 'Content-new', 'deleted_at' => Time.now }] } }
|
396
|
-
it { is_expected.to eq [{ 'content' => 'Content' }, {}] }
|
397
|
-
end
|
398
|
-
|
399
|
-
context 'when not soft-deleted' do
|
400
|
-
let(:changes) do
|
401
|
-
{ 'email_subject' => [{ 'content' => 'Content', 'deleted_at' => nil }, { 'content' => 'Content-new', 'deleted_at' => nil }] }
|
402
|
-
end
|
403
|
-
it { is_expected.to eq [{ 'content' => 'Content' }, { 'content' => 'Content-new' }] }
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
|
-
describe 'paranoia_field' do
|
408
|
-
context 'when embeds_one has alias' do
|
409
|
-
before :each do
|
410
|
-
class ModelTwo
|
411
|
-
include Mongoid::Document
|
412
|
-
include Mongoid::History::Trackable
|
413
|
-
|
414
|
-
store_in collection: :model_twos
|
415
|
-
|
416
|
-
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
417
|
-
embeds_one :emb_two_one
|
418
|
-
else
|
419
|
-
embeds_one :emb_two_one, inverse_class_name: 'EmbTwoOne'
|
420
|
-
end
|
421
|
-
|
422
|
-
track_history on: :emb_two_one
|
423
|
-
end
|
424
|
-
|
425
|
-
class EmbTwoOne
|
426
|
-
include Mongoid::Document
|
427
|
-
include Mongoid::History::Trackable
|
428
|
-
|
429
|
-
field :foo
|
430
|
-
field :cncl, as: :cancelled_at
|
431
|
-
|
432
|
-
embedded_in :model_two
|
433
|
-
|
434
|
-
history_settings paranoia_field: :cancelled_at
|
435
|
-
end
|
436
|
-
end
|
437
|
-
|
438
|
-
after :each do
|
439
|
-
Object.send(:remove_const, :ModelTwo)
|
440
|
-
Object.send(:remove_const, :EmbTwoOne)
|
441
|
-
end
|
442
|
-
|
443
|
-
before :each do
|
444
|
-
allow(ModelTwo).to receive(:dynamic_enabled?) { false }
|
445
|
-
allow(model_two_obj).to receive(:changes) { changes }
|
446
|
-
end
|
447
|
-
|
448
|
-
let(:model_two_obj) { ModelTwo.new }
|
449
|
-
let(:changes) { { 'emb_two_one' => [{ 'foo' => 'Foo', 'cncl' => Time.now }, { 'foo' => 'Foo-new' }] } }
|
450
|
-
|
451
|
-
subject { model_two_obj.send(:modified_attributes_for_update)['emb_two_one'] }
|
452
|
-
it { is_expected.to eq [{}, { 'foo' => 'Foo-new' }] }
|
453
|
-
end
|
454
|
-
|
455
|
-
context 'when embeds_many has alias' do
|
456
|
-
before :each do
|
457
|
-
class ModelTwo
|
458
|
-
include Mongoid::Document
|
459
|
-
include Mongoid::History::Trackable
|
460
|
-
|
461
|
-
store_in collection: :model_twos
|
462
|
-
|
463
|
-
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
464
|
-
embeds_many :emb_two_ones
|
465
|
-
else
|
466
|
-
embeds_many :emb_two_ones, inverse_class_name: 'EmbTwoOne'
|
467
|
-
end
|
468
|
-
|
469
|
-
track_history on: :emb_two_ones
|
470
|
-
end
|
471
|
-
|
472
|
-
class EmbTwoOne
|
473
|
-
include Mongoid::Document
|
474
|
-
include Mongoid::History::Trackable
|
475
|
-
|
476
|
-
field :foo
|
477
|
-
field :cncl, as: :cancelled_at
|
478
|
-
|
479
|
-
embedded_in :model_two
|
480
|
-
|
481
|
-
history_settings paranoia_field: :cancelled_at
|
482
|
-
end
|
483
|
-
end
|
484
|
-
|
485
|
-
after :each do
|
486
|
-
Object.send(:remove_const, :ModelTwo)
|
487
|
-
Object.send(:remove_const, :EmbTwoOne)
|
488
|
-
end
|
489
|
-
|
490
|
-
before :each do
|
491
|
-
allow(ModelTwo).to receive(:dynamic_enabled?) { false }
|
492
|
-
allow(model_two_obj).to receive(:changes) { changes }
|
493
|
-
end
|
494
|
-
|
495
|
-
let(:model_two_obj) { ModelTwo.new }
|
496
|
-
let(:changes) { { 'emb_two_ones' => [[{ 'foo' => 'Foo', 'cncl' => Time.now }], [{ 'foo' => 'Foo-new' }]] } }
|
497
|
-
subject { model_two_obj.send(:modified_attributes_for_update)['emb_two_ones'] }
|
498
|
-
it { is_expected.to eq [[], [{ 'foo' => 'Foo-new' }]] }
|
499
|
-
end
|
500
|
-
end
|
501
|
-
end
|
502
|
-
|
503
|
-
describe '#modified_attributes_for_destroy' do
|
504
|
-
before :each do
|
505
|
-
allow(ModelOne).to receive(:dynamic_enabled?) { false }
|
506
|
-
model_one.save!
|
507
|
-
end
|
508
|
-
subject { model_one.send(:modified_attributes_for_destroy) }
|
509
|
-
|
510
|
-
context 'with tracked embeds_one object' do
|
511
|
-
before :each do
|
512
|
-
ModelOne.track_history(modifier_field_optional: true, on: { emb_one: :f_em_foo })
|
513
|
-
end
|
514
|
-
it 'should include tracked attributes only' do
|
515
|
-
expect(subject['emb_one'][0].keys.size).to eq 2
|
516
|
-
expect(subject['emb_one'][0]['_id']).to eq emb_one._id
|
517
|
-
expect(subject['emb_one'][0]['f_em_foo']).to eq 'Foo'
|
518
|
-
|
519
|
-
expect(subject['emb_one'][1]).to be_nil
|
520
|
-
end
|
521
|
-
end
|
522
|
-
|
523
|
-
context 'with untracked embeds_one object' do
|
524
|
-
before :each do
|
525
|
-
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
526
|
-
end
|
527
|
-
it 'should not include embeds_one attributes' do
|
528
|
-
expect(subject['emb_one']).to be_nil
|
529
|
-
end
|
530
|
-
end
|
531
|
-
|
532
|
-
context 'with tracked embeds_many objects' do
|
533
|
-
before :each do
|
534
|
-
ModelOne.track_history(modifier_field_optional: true, on: { emb_threes: :f_em_foo })
|
535
|
-
end
|
536
|
-
it 'should include tracked attributes only' do
|
537
|
-
expect(subject['emb_threes'][0][0].keys.count).to eq 2
|
538
|
-
expect(subject['emb_threes'][0][0]['_id']).to eq emb_threes.first._id
|
539
|
-
expect(subject['emb_threes'][0][0]['f_em_foo']).to eq 'Foo'
|
540
|
-
|
541
|
-
expect(subject['emb_threes'][1]).to be_nil
|
542
|
-
end
|
543
|
-
end
|
544
|
-
|
545
|
-
context 'with untracked embeds_many objects' do
|
546
|
-
before :each do
|
547
|
-
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
548
|
-
end
|
549
|
-
it 'should include not tracked embeds_many attributes' do
|
550
|
-
expect(subject['emb_threes']).to be_nil
|
551
|
-
end
|
552
|
-
end
|
553
|
-
end
|
554
|
-
end
|
555
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongoid::History::Trackable do
|
4
|
+
describe 'MyInstanceMethods' do
|
5
|
+
before :each do
|
6
|
+
class ModelOne
|
7
|
+
include Mongoid::Document
|
8
|
+
include Mongoid::History::Trackable
|
9
|
+
|
10
|
+
store_in collection: :model_ones
|
11
|
+
|
12
|
+
field :foo
|
13
|
+
field :b, as: :bar
|
14
|
+
|
15
|
+
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
16
|
+
embeds_one :emb_one
|
17
|
+
embeds_one :emb_two, store_as: :emt
|
18
|
+
embeds_many :emb_threes
|
19
|
+
embeds_many :emb_fours, store_as: :emfs
|
20
|
+
else
|
21
|
+
embeds_one :emb_one, inverse_class_name: 'EmbOne'
|
22
|
+
embeds_one :emb_two, store_as: :emt, inverse_class_name: 'EmbTwo'
|
23
|
+
embeds_many :emb_threes, inverse_class_name: 'EmbThree'
|
24
|
+
embeds_many :emb_fours, store_as: :emfs, inverse_class_name: 'EmbFour'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class EmbOne
|
29
|
+
include Mongoid::Document
|
30
|
+
include Mongoid::History::Trackable
|
31
|
+
|
32
|
+
field :f_em_foo
|
33
|
+
field :fmb, as: :f_em_bar
|
34
|
+
|
35
|
+
embedded_in :model_one
|
36
|
+
end
|
37
|
+
|
38
|
+
class EmbTwo
|
39
|
+
include Mongoid::Document
|
40
|
+
include Mongoid::History::Trackable
|
41
|
+
|
42
|
+
field :baz
|
43
|
+
embedded_in :model_one
|
44
|
+
end
|
45
|
+
|
46
|
+
class EmbThree
|
47
|
+
include Mongoid::Document
|
48
|
+
include Mongoid::History::Trackable
|
49
|
+
|
50
|
+
field :f_em_foo
|
51
|
+
field :fmb, as: :f_em_bar
|
52
|
+
|
53
|
+
embedded_in :model_one
|
54
|
+
end
|
55
|
+
|
56
|
+
class EmbFour
|
57
|
+
include Mongoid::Document
|
58
|
+
include Mongoid::History::Trackable
|
59
|
+
|
60
|
+
field :baz
|
61
|
+
embedded_in :model_one
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
after :each do
|
66
|
+
Object.send(:remove_const, :ModelOne)
|
67
|
+
Object.send(:remove_const, :EmbOne)
|
68
|
+
Object.send(:remove_const, :EmbTwo)
|
69
|
+
Object.send(:remove_const, :EmbThree)
|
70
|
+
Object.send(:remove_const, :EmbFour)
|
71
|
+
end
|
72
|
+
|
73
|
+
let(:bson_class) { defined?(BSON::ObjectId) ? BSON::ObjectId : Moped::BSON::ObjectId }
|
74
|
+
|
75
|
+
let(:emb_one) { EmbOne.new(f_em_foo: 'Foo', f_em_bar: 'Bar') }
|
76
|
+
let(:emb_threes) { [EmbThree.new(f_em_foo: 'Foo', f_em_bar: 'Bar')] }
|
77
|
+
let(:model_one) { ModelOne.new(foo: 'Foo', bar: 'Bar', emb_one: emb_one, emb_threes: emb_threes) }
|
78
|
+
|
79
|
+
describe '#modified_attributes_for_create' do
|
80
|
+
before :each do
|
81
|
+
ModelOne.track_history modifier_field_optional: true, on: %i[foo emb_one emb_threes]
|
82
|
+
end
|
83
|
+
|
84
|
+
subject { model_one.send(:modified_attributes_for_create) }
|
85
|
+
|
86
|
+
context 'with tracked embeds_one object' do
|
87
|
+
before :each do
|
88
|
+
ModelOne.track_history(modifier_field_optional: true, on: { emb_one: :f_em_foo })
|
89
|
+
end
|
90
|
+
it 'should include tracked attributes only' do
|
91
|
+
expect(subject['emb_one'][0]).to be_nil
|
92
|
+
|
93
|
+
expect(subject['emb_one'][1].keys.size).to eq 2
|
94
|
+
expect(subject['emb_one'][1]['_id']).to eq emb_one._id
|
95
|
+
expect(subject['emb_one'][1]['f_em_foo']).to eq 'Foo'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'with untracked embeds_one object' do
|
100
|
+
before :each do
|
101
|
+
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
102
|
+
end
|
103
|
+
it 'should not include embeds_one attributes' do
|
104
|
+
expect(subject['emb_one']).to be_nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'with tracked embeds_many objects' do
|
109
|
+
before :each do
|
110
|
+
ModelOne.track_history(modifier_field_optional: true, on: { emb_threes: :f_em_foo })
|
111
|
+
end
|
112
|
+
it 'should include tracked attributes only' do
|
113
|
+
expect(subject['emb_threes'][0]).to be_nil
|
114
|
+
|
115
|
+
expect(subject['emb_threes'][1][0].keys.count).to eq 2
|
116
|
+
expect(subject['emb_threes'][1][0]['_id']).to eq emb_threes.first._id
|
117
|
+
expect(subject['emb_threes'][1][0]['f_em_foo']).to eq 'Foo'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'with untracked embeds_many objects' do
|
122
|
+
before :each do
|
123
|
+
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
124
|
+
end
|
125
|
+
it 'should include not tracked embeds_many attributes' do
|
126
|
+
expect(subject['emb_threes']).to be_nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when embeds_one object blank' do
|
131
|
+
let(:emb_one) { nil }
|
132
|
+
|
133
|
+
it 'should not include embeds_one model key' do
|
134
|
+
expect(subject.keys).to_not include 'emb_one'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'embeds_one' do
|
139
|
+
before :each do
|
140
|
+
class Mail
|
141
|
+
include Mongoid::Document
|
142
|
+
include Mongoid::History::Trackable
|
143
|
+
|
144
|
+
store_in collection: :mails
|
145
|
+
field :provider
|
146
|
+
|
147
|
+
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
148
|
+
embeds_one :mail_subject
|
149
|
+
else
|
150
|
+
embeds_one :mail_subject, inverse_class_name: 'MailSubject'
|
151
|
+
end
|
152
|
+
|
153
|
+
track_history on: :mail_subject
|
154
|
+
end
|
155
|
+
|
156
|
+
class MailSubject
|
157
|
+
include Mongoid::Document
|
158
|
+
|
159
|
+
field :content
|
160
|
+
embedded_in :mail
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
after :each do
|
165
|
+
Object.send(:remove_const, :MailSubject)
|
166
|
+
Object.send(:remove_const, :Mail)
|
167
|
+
end
|
168
|
+
|
169
|
+
let(:mail) { Mail.new(mail_subject: mail_subject) }
|
170
|
+
let(:mail_subject) { nil }
|
171
|
+
subject { mail.send(:modified_attributes_for_create)['mail_subject'] }
|
172
|
+
|
173
|
+
context 'when obj not built' do
|
174
|
+
it { is_expected.to be_nil }
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'when obj does not respond to paranoia_field' do
|
178
|
+
let(:mail_subject) { MailSubject.new(content: 'Content') }
|
179
|
+
it { is_expected.to eq [nil, { '_id' => mail_subject._id, 'content' => 'Content' }] }
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'when obj not soft-deleted' do
|
183
|
+
before :each do
|
184
|
+
allow(mail_subject).to receive(:deleted_at) { nil }
|
185
|
+
end
|
186
|
+
let(:mail_subject) { MailSubject.new(content: 'Content') }
|
187
|
+
it { is_expected.to eq [nil, { '_id' => mail_subject._id, 'content' => 'Content' }] }
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'when obj soft-deleted' do
|
191
|
+
before :each do
|
192
|
+
allow(mail_subject).to receive(:deleted_at) { Time.now }
|
193
|
+
end
|
194
|
+
let(:mail_subject) { MailSubject.new(content: 'Content') }
|
195
|
+
it { is_expected.to be_nil }
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe 'paranoia' do
|
200
|
+
before :each do
|
201
|
+
class ModelParanoia
|
202
|
+
include Mongoid::Document
|
203
|
+
include Mongoid::History::Trackable
|
204
|
+
|
205
|
+
store_in collection: :model_paranoias
|
206
|
+
|
207
|
+
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
208
|
+
embeds_many :emb_para_ones
|
209
|
+
else
|
210
|
+
embeds_many :emb_para_ones, inverse_class_name: 'EmbParaOne'
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
class EmbParaOne
|
215
|
+
include Mongoid::Document
|
216
|
+
|
217
|
+
field :em_foo
|
218
|
+
field :deleted_at
|
219
|
+
|
220
|
+
embedded_in :model_paranoia
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
after :each do
|
225
|
+
Object.send(:remove_const, :ModelParanoia)
|
226
|
+
Object.send(:remove_const, :EmbParaOne)
|
227
|
+
end
|
228
|
+
|
229
|
+
let(:emb_para_one) { EmbParaOne.new(em_foo: 'Em-Foo') }
|
230
|
+
let(:model_paranoia) { ModelParanoia.new(emb_para_ones: [emb_para_one]) }
|
231
|
+
|
232
|
+
context 'when does not respond to paranoia_field' do
|
233
|
+
before :each do
|
234
|
+
ModelParanoia.track_history(on: :emb_para_ones)
|
235
|
+
end
|
236
|
+
|
237
|
+
subject { model_paranoia.send(:modified_attributes_for_create) }
|
238
|
+
|
239
|
+
it 'should include tracked embeds_many objects attributes' do
|
240
|
+
expect(subject['emb_para_ones'][0]).to be_nil
|
241
|
+
expect(subject['emb_para_ones'][1].size).to eq 1
|
242
|
+
expect(subject['emb_para_ones'][1][0]['_id']).to be_a bson_class
|
243
|
+
expect(subject['emb_para_ones'][1][0]['em_foo']).to eq 'Em-Foo'
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context 'when responds to paranoia_field' do
|
248
|
+
before :each do
|
249
|
+
ModelParanoia.track_history(on: :emb_para_ones)
|
250
|
+
allow(emb_para_one).to receive(:deleted_at) { Time.now }
|
251
|
+
allow(emb_para_one_2).to receive(:deleted_at) { nil }
|
252
|
+
end
|
253
|
+
|
254
|
+
let(:model_paranoia) { ModelParanoia.new(emb_para_ones: [emb_para_one, emb_para_one_2]) }
|
255
|
+
let(:emb_para_one) { EmbParaOne.new(em_foo: 'Em-Foo') }
|
256
|
+
let(:emb_para_one_2) { EmbParaOne.new(em_foo: 'Em-Foo-2') }
|
257
|
+
|
258
|
+
subject { model_paranoia.send(:modified_attributes_for_create) }
|
259
|
+
|
260
|
+
it 'should not include deleted objects attributes' do
|
261
|
+
expect(subject['emb_para_ones'][0]).to be_nil
|
262
|
+
expect(subject['emb_para_ones'][1]).to eq [{ '_id' => emb_para_one_2._id, 'em_foo' => 'Em-Foo-2' }]
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe '#modified_attributes_for_update' do
|
269
|
+
before :each do
|
270
|
+
model_one.save!
|
271
|
+
allow(ModelOne).to receive(:dynamic_enabled?) { false }
|
272
|
+
allow(model_one).to receive(:changes) { changes }
|
273
|
+
end
|
274
|
+
let(:changes) { {} }
|
275
|
+
subject { model_one.send(:modified_attributes_for_update) }
|
276
|
+
|
277
|
+
context 'when embeds_one attributes passed in options' do
|
278
|
+
before :each do
|
279
|
+
ModelOne.track_history(modifier_field_optional: true, on: { emb_one: :f_em_foo })
|
280
|
+
end
|
281
|
+
let(:changes) { { 'emb_one' => [{ 'f_em_foo' => 'Foo', 'fmb' => 'Bar' }, { 'f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new' }] } }
|
282
|
+
it { expect(subject['emb_one'][0]).to eq('f_em_foo' => 'Foo') }
|
283
|
+
it { expect(subject['emb_one'][1]).to eq('f_em_foo' => 'Foo-new') }
|
284
|
+
end
|
285
|
+
|
286
|
+
context 'when embeds_one relation passed in options' do
|
287
|
+
before :each do
|
288
|
+
ModelOne.track_history(modifier_field_optional: true, on: :emb_one)
|
289
|
+
end
|
290
|
+
let(:changes) { { 'emb_one' => [{ 'f_em_foo' => 'Foo', 'fmb' => 'Bar' }, { 'f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new' }] } }
|
291
|
+
it { expect(subject['emb_one'][0]).to eq('f_em_foo' => 'Foo', 'fmb' => 'Bar') }
|
292
|
+
it { expect(subject['emb_one'][1]).to eq('f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new') }
|
293
|
+
end
|
294
|
+
|
295
|
+
context 'when embeds_one relation not tracked' do
|
296
|
+
before :each do
|
297
|
+
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
298
|
+
end
|
299
|
+
let(:changes) { { 'emb_one' => [{ 'f_em_foo' => 'Foo' }, { 'f_em_foo' => 'Foo-new' }] } }
|
300
|
+
it { expect(subject['emb_one']).to be_nil }
|
301
|
+
end
|
302
|
+
|
303
|
+
context 'when embeds_many attributes passed in options' do
|
304
|
+
before :each do
|
305
|
+
ModelOne.track_history(modifier_field_optional: true, on: { emb_threes: :f_em_foo })
|
306
|
+
end
|
307
|
+
let(:changes) { { 'emb_threes' => [[{ 'f_em_foo' => 'Foo', 'fmb' => 'Bar' }], [{ 'f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new' }]] } }
|
308
|
+
it { expect(subject['emb_threes']).to eq [[{ 'f_em_foo' => 'Foo' }], [{ 'f_em_foo' => 'Foo-new' }]] }
|
309
|
+
end
|
310
|
+
|
311
|
+
context 'when embeds_many relation passed in options' do
|
312
|
+
before :each do
|
313
|
+
ModelOne.track_history(modifier_field_optional: true, on: :emb_threes)
|
314
|
+
end
|
315
|
+
let(:changes) { { 'emb_threes' => [[{ 'f_em_foo' => 'Foo', 'fmb' => 'Bar' }], [{ 'f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new' }]] } }
|
316
|
+
it { expect(subject['emb_threes']).to eq [[{ 'f_em_foo' => 'Foo', 'fmb' => 'Bar' }], [{ 'f_em_foo' => 'Foo-new', 'fmb' => 'Bar-new' }]] }
|
317
|
+
end
|
318
|
+
|
319
|
+
context 'when embeds_many relation not tracked' do
|
320
|
+
before :each do
|
321
|
+
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
322
|
+
end
|
323
|
+
let(:changes) { { 'emb_threes' => [[{ 'f_em_foo' => 'Foo' }], [{ 'f_em_foo' => 'Foo-new' }]] } }
|
324
|
+
it { expect(subject['emb_threes']).to be_nil }
|
325
|
+
end
|
326
|
+
|
327
|
+
context 'when field tracked' do
|
328
|
+
before :each do
|
329
|
+
ModelOne.track_history(modifier_field_optional: true, on: :foo)
|
330
|
+
end
|
331
|
+
let(:changes) { { 'foo' => ['Foo', 'Foo-new'], 'b' => ['Bar', 'Bar-new'] } }
|
332
|
+
it { is_expected.to eq('foo' => ['Foo', 'Foo-new']) }
|
333
|
+
end
|
334
|
+
|
335
|
+
context 'when field not tracked' do
|
336
|
+
before :each do
|
337
|
+
ModelOne.track_history(modifier_field_optional: true, on: [])
|
338
|
+
end
|
339
|
+
let(:changes) { { 'foo' => ['Foo', 'Foo-new'] } }
|
340
|
+
it { is_expected.to eq({}) }
|
341
|
+
end
|
342
|
+
|
343
|
+
describe 'embeds_one' do
|
344
|
+
before :each do
|
345
|
+
class Email
|
346
|
+
include Mongoid::Document
|
347
|
+
include Mongoid::History::Trackable
|
348
|
+
|
349
|
+
store_in collection: :emails
|
350
|
+
field :provider
|
351
|
+
|
352
|
+
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
353
|
+
embeds_one :email_subject
|
354
|
+
else
|
355
|
+
embeds_one :email_subject, inverse_class_name: 'EmailSubject'
|
356
|
+
end
|
357
|
+
|
358
|
+
track_history on: :email_subject
|
359
|
+
end
|
360
|
+
|
361
|
+
class EmailSubject
|
362
|
+
include Mongoid::Document
|
363
|
+
include Mongoid::History::Trackable
|
364
|
+
|
365
|
+
field :content
|
366
|
+
embedded_in :email_subject
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
after :each do
|
371
|
+
Object.send(:remove_const, :EmailSubject)
|
372
|
+
Object.send(:remove_const, :Email)
|
373
|
+
end
|
374
|
+
|
375
|
+
before :each do
|
376
|
+
allow(Email).to receive(:dynamic_enabled?) { false }
|
377
|
+
allow(email).to receive(:changes) { changes }
|
378
|
+
end
|
379
|
+
|
380
|
+
let(:email) { Email.new }
|
381
|
+
let(:changes) { {} }
|
382
|
+
subject { email.send(:modified_attributes_for_update)['email_subject'] }
|
383
|
+
|
384
|
+
context 'when paranoia_field not present' do
|
385
|
+
let(:changes) { { 'email_subject' => [{ 'content' => 'Content' }, { 'content' => 'Content-new' }] } }
|
386
|
+
it { is_expected.to eq [{ 'content' => 'Content' }, { 'content' => 'Content-new' }] }
|
387
|
+
end
|
388
|
+
|
389
|
+
context 'when older soft-deleted' do
|
390
|
+
let(:changes) { { 'email_subject' => [{ 'content' => 'Content', 'deleted_at' => Time.now }, { 'content' => 'Content-new' }] } }
|
391
|
+
it { is_expected.to eq [{}, { 'content' => 'Content-new' }] }
|
392
|
+
end
|
393
|
+
|
394
|
+
context 'when new soft-deleted' do
|
395
|
+
let(:changes) { { 'email_subject' => [{ 'content' => 'Content' }, { 'content' => 'Content-new', 'deleted_at' => Time.now }] } }
|
396
|
+
it { is_expected.to eq [{ 'content' => 'Content' }, {}] }
|
397
|
+
end
|
398
|
+
|
399
|
+
context 'when not soft-deleted' do
|
400
|
+
let(:changes) do
|
401
|
+
{ 'email_subject' => [{ 'content' => 'Content', 'deleted_at' => nil }, { 'content' => 'Content-new', 'deleted_at' => nil }] }
|
402
|
+
end
|
403
|
+
it { is_expected.to eq [{ 'content' => 'Content' }, { 'content' => 'Content-new' }] }
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
describe 'paranoia_field' do
|
408
|
+
context 'when embeds_one has alias' do
|
409
|
+
before :each do
|
410
|
+
class ModelTwo
|
411
|
+
include Mongoid::Document
|
412
|
+
include Mongoid::History::Trackable
|
413
|
+
|
414
|
+
store_in collection: :model_twos
|
415
|
+
|
416
|
+
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
417
|
+
embeds_one :emb_two_one
|
418
|
+
else
|
419
|
+
embeds_one :emb_two_one, inverse_class_name: 'EmbTwoOne'
|
420
|
+
end
|
421
|
+
|
422
|
+
track_history on: :emb_two_one
|
423
|
+
end
|
424
|
+
|
425
|
+
class EmbTwoOne
|
426
|
+
include Mongoid::Document
|
427
|
+
include Mongoid::History::Trackable
|
428
|
+
|
429
|
+
field :foo
|
430
|
+
field :cncl, as: :cancelled_at
|
431
|
+
|
432
|
+
embedded_in :model_two
|
433
|
+
|
434
|
+
history_settings paranoia_field: :cancelled_at
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
after :each do
|
439
|
+
Object.send(:remove_const, :ModelTwo)
|
440
|
+
Object.send(:remove_const, :EmbTwoOne)
|
441
|
+
end
|
442
|
+
|
443
|
+
before :each do
|
444
|
+
allow(ModelTwo).to receive(:dynamic_enabled?) { false }
|
445
|
+
allow(model_two_obj).to receive(:changes) { changes }
|
446
|
+
end
|
447
|
+
|
448
|
+
let(:model_two_obj) { ModelTwo.new }
|
449
|
+
let(:changes) { { 'emb_two_one' => [{ 'foo' => 'Foo', 'cncl' => Time.now }, { 'foo' => 'Foo-new' }] } }
|
450
|
+
|
451
|
+
subject { model_two_obj.send(:modified_attributes_for_update)['emb_two_one'] }
|
452
|
+
it { is_expected.to eq [{}, { 'foo' => 'Foo-new' }] }
|
453
|
+
end
|
454
|
+
|
455
|
+
context 'when embeds_many has alias' do
|
456
|
+
before :each do
|
457
|
+
class ModelTwo
|
458
|
+
include Mongoid::Document
|
459
|
+
include Mongoid::History::Trackable
|
460
|
+
|
461
|
+
store_in collection: :model_twos
|
462
|
+
|
463
|
+
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
464
|
+
embeds_many :emb_two_ones
|
465
|
+
else
|
466
|
+
embeds_many :emb_two_ones, inverse_class_name: 'EmbTwoOne'
|
467
|
+
end
|
468
|
+
|
469
|
+
track_history on: :emb_two_ones
|
470
|
+
end
|
471
|
+
|
472
|
+
class EmbTwoOne
|
473
|
+
include Mongoid::Document
|
474
|
+
include Mongoid::History::Trackable
|
475
|
+
|
476
|
+
field :foo
|
477
|
+
field :cncl, as: :cancelled_at
|
478
|
+
|
479
|
+
embedded_in :model_two
|
480
|
+
|
481
|
+
history_settings paranoia_field: :cancelled_at
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
after :each do
|
486
|
+
Object.send(:remove_const, :ModelTwo)
|
487
|
+
Object.send(:remove_const, :EmbTwoOne)
|
488
|
+
end
|
489
|
+
|
490
|
+
before :each do
|
491
|
+
allow(ModelTwo).to receive(:dynamic_enabled?) { false }
|
492
|
+
allow(model_two_obj).to receive(:changes) { changes }
|
493
|
+
end
|
494
|
+
|
495
|
+
let(:model_two_obj) { ModelTwo.new }
|
496
|
+
let(:changes) { { 'emb_two_ones' => [[{ 'foo' => 'Foo', 'cncl' => Time.now }], [{ 'foo' => 'Foo-new' }]] } }
|
497
|
+
subject { model_two_obj.send(:modified_attributes_for_update)['emb_two_ones'] }
|
498
|
+
it { is_expected.to eq [[], [{ 'foo' => 'Foo-new' }]] }
|
499
|
+
end
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
describe '#modified_attributes_for_destroy' do
|
504
|
+
before :each do
|
505
|
+
allow(ModelOne).to receive(:dynamic_enabled?) { false }
|
506
|
+
model_one.save!
|
507
|
+
end
|
508
|
+
subject { model_one.send(:modified_attributes_for_destroy) }
|
509
|
+
|
510
|
+
context 'with tracked embeds_one object' do
|
511
|
+
before :each do
|
512
|
+
ModelOne.track_history(modifier_field_optional: true, on: { emb_one: :f_em_foo })
|
513
|
+
end
|
514
|
+
it 'should include tracked attributes only' do
|
515
|
+
expect(subject['emb_one'][0].keys.size).to eq 2
|
516
|
+
expect(subject['emb_one'][0]['_id']).to eq emb_one._id
|
517
|
+
expect(subject['emb_one'][0]['f_em_foo']).to eq 'Foo'
|
518
|
+
|
519
|
+
expect(subject['emb_one'][1]).to be_nil
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
context 'with untracked embeds_one object' do
|
524
|
+
before :each do
|
525
|
+
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
526
|
+
end
|
527
|
+
it 'should not include embeds_one attributes' do
|
528
|
+
expect(subject['emb_one']).to be_nil
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
context 'with tracked embeds_many objects' do
|
533
|
+
before :each do
|
534
|
+
ModelOne.track_history(modifier_field_optional: true, on: { emb_threes: :f_em_foo })
|
535
|
+
end
|
536
|
+
it 'should include tracked attributes only' do
|
537
|
+
expect(subject['emb_threes'][0][0].keys.count).to eq 2
|
538
|
+
expect(subject['emb_threes'][0][0]['_id']).to eq emb_threes.first._id
|
539
|
+
expect(subject['emb_threes'][0][0]['f_em_foo']).to eq 'Foo'
|
540
|
+
|
541
|
+
expect(subject['emb_threes'][1]).to be_nil
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
context 'with untracked embeds_many objects' do
|
546
|
+
before :each do
|
547
|
+
ModelOne.track_history(modifier_field_optional: true, on: :fields)
|
548
|
+
end
|
549
|
+
it 'should include not tracked embeds_many attributes' do
|
550
|
+
expect(subject['emb_threes']).to be_nil
|
551
|
+
end
|
552
|
+
end
|
553
|
+
end
|
554
|
+
end
|
555
|
+
end
|