mongoid-history 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +16 -3
  3. data/.travis.yml +23 -8
  4. data/CHANGELOG.md +20 -6
  5. data/Dangerfile +1 -0
  6. data/Gemfile +22 -1
  7. data/LICENSE.txt +1 -1
  8. data/README.md +130 -18
  9. data/lib/mongoid/history.rb +32 -15
  10. data/lib/mongoid/history/attributes/base.rb +31 -0
  11. data/lib/mongoid/history/attributes/create.rb +52 -0
  12. data/lib/mongoid/history/attributes/destroy.rb +36 -0
  13. data/lib/mongoid/history/attributes/update.rb +43 -0
  14. data/lib/mongoid/history/options.rb +153 -0
  15. data/lib/mongoid/history/trackable.rb +170 -72
  16. data/lib/mongoid/history/tracker.rb +39 -23
  17. data/lib/mongoid/history/version.rb +1 -1
  18. data/mongoid-history.gemspec +0 -8
  19. data/spec/integration/embedded_in_polymorphic_spec.rb +8 -0
  20. data/spec/integration/integration_spec.rb +4 -0
  21. data/spec/integration/nested_embedded_documents_spec.rb +13 -6
  22. data/spec/integration/nested_embedded_polymorphic_documents_spec.rb +24 -24
  23. data/spec/spec_helper.rb +6 -0
  24. data/spec/unit/attributes/base_spec.rb +54 -0
  25. data/spec/unit/attributes/create_spec.rb +315 -0
  26. data/spec/unit/attributes/destroy_spec.rb +218 -0
  27. data/spec/unit/attributes/update_spec.rb +210 -0
  28. data/spec/unit/embedded_methods_spec.rb +69 -0
  29. data/spec/unit/history_spec.rb +35 -0
  30. data/spec/unit/my_instance_methods_spec.rb +485 -0
  31. data/spec/unit/options_spec.rb +294 -0
  32. data/spec/unit/singleton_methods_spec.rb +338 -0
  33. data/spec/unit/store/default_store_spec.rb +11 -0
  34. data/spec/unit/store/request_store_spec.rb +13 -0
  35. data/spec/unit/trackable_spec.rb +335 -68
  36. data/spec/unit/tracker_spec.rb +153 -0
  37. metadata +31 -102
@@ -0,0 +1,294 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongoid::History::Options do
4
+ before :all do
5
+ ModelOne = Class.new do
6
+ include Mongoid::Document
7
+ include Mongoid::History::Trackable
8
+ store_in collection: :model_ones
9
+ field :foo
10
+ field :b, as: :bar
11
+ embeds_one :emb_one, inverse_class_name: 'EmbOne'
12
+ embeds_one :emb_two, store_as: :emtw, inverse_class_name: 'EmbTwo'
13
+ embeds_many :emb_threes, inverse_class_name: 'EmbThree'
14
+ embeds_many :emb_fours, store_as: :emfs, inverse_class_name: 'EmbFour'
15
+ track_history
16
+ end
17
+
18
+ EmbOne = Class.new do
19
+ include Mongoid::Document
20
+ field :f_em_foo
21
+ field :fmb, as: :f_em_bar
22
+ embedded_in :model_one
23
+ end
24
+
25
+ EmbTwo = Class.new do
26
+ include Mongoid::Document
27
+ field :f_em_baz
28
+ embedded_in :model_one
29
+ end
30
+
31
+ EmbThree = Class.new do
32
+ include Mongoid::Document
33
+ field :f_em_foo
34
+ field :fmb, as: :f_em_bar
35
+ embedded_in :model_one
36
+ end
37
+
38
+ EmbFour = Class.new do
39
+ include Mongoid::Document
40
+ field :f_em_baz
41
+ embedded_in :model_one
42
+ end
43
+ end
44
+
45
+ let(:service) { described_class.new(ModelOne) }
46
+
47
+ subject { service }
48
+
49
+ it { is_expected.to respond_to :trackable }
50
+ it { is_expected.to respond_to :options }
51
+
52
+ describe '#initialize' do
53
+ it { expect(service.trackable).to eq ModelOne }
54
+ end
55
+
56
+ describe '#scope' do
57
+ it { expect(service.scope).to eq :model_one }
58
+ end
59
+
60
+ describe '#parse' do
61
+ describe '#default_options' do
62
+ let(:expected_options) do
63
+ { on: :all,
64
+ except: [:created_at, :updated_at],
65
+ tracker_class_name: nil,
66
+ modifier_field: :modifier,
67
+ version_field: :version,
68
+ changes_method: :changes,
69
+ scope: :model_one,
70
+ track_create: false,
71
+ track_update: true,
72
+ track_destroy: false }
73
+ end
74
+ it { expect(service.send(:default_options)).to eq expected_options }
75
+ end
76
+
77
+ describe '#prepare_skipped_fields' do
78
+ let(:options) { { except: value } }
79
+ subject { service.parse(options) }
80
+
81
+ context 'with field' do
82
+ let(:value) { :foo }
83
+ it { expect(subject[:except]).to eq %w(foo) }
84
+ end
85
+
86
+ context 'with array of fields' do
87
+ let(:value) { %i(foo) }
88
+ it { expect(subject[:except]).to eq %w(foo) }
89
+ end
90
+
91
+ context 'with field alias' do
92
+ let(:value) { %i(foo bar) }
93
+ it { expect(subject[:except]).to eq %w(foo b) }
94
+ end
95
+
96
+ context 'with duplicate values' do
97
+ let(:value) { %i(foo bar b) }
98
+ it { expect(subject[:except]).to eq %w(foo b) }
99
+ end
100
+
101
+ context 'with blank values' do
102
+ let(:value) { %i(foo) | [nil] }
103
+ it { expect(subject[:except]).to eq %w(foo) }
104
+ end
105
+ end
106
+
107
+ describe '#parse_tracked_fields_and_relations' do
108
+ context 'when options not passed' do
109
+ let(:expected_options) do
110
+ { on: %i(foo b),
111
+ except: %w(created_at updated_at),
112
+ tracker_class_name: nil,
113
+ modifier_field: :modifier,
114
+ version_field: :version,
115
+ changes_method: :changes,
116
+ scope: :model_one,
117
+ track_create: false,
118
+ track_update: true,
119
+ track_destroy: false,
120
+ fields: %w(foo b),
121
+ dynamic: [],
122
+ relations: { embeds_one: {}, embeds_many: {} } }
123
+ end
124
+ it { expect(service.parse).to eq expected_options }
125
+ end
126
+
127
+ context 'when options passed' do
128
+ subject { service.parse(options) }
129
+
130
+ describe '@options' do
131
+ let(:options) { { on: value } }
132
+
133
+ context 'with field' do
134
+ let(:value) { :foo }
135
+ it { expect(subject[:on]).to eq %i(foo) }
136
+ it { expect(subject[:fields]).to eq %w(foo) }
137
+ end
138
+
139
+ context 'with array of fields' do
140
+ let(:value) { %i(foo) }
141
+ it { expect(subject[:on]).to eq %i(foo) }
142
+ it { expect(subject[:fields]).to eq %w(foo) }
143
+ end
144
+
145
+ context 'with embeds_one relation attributes' do
146
+ let(:value) { { emb_one: %i(f_em_foo) } }
147
+ it { expect(subject[:on]).to eq [[:emb_one, %i(f_em_foo)]] }
148
+ end
149
+
150
+ context 'with fields and embeds_one relation attributes' do
151
+ let(:value) { [:foo, emb_one: %i(f_em_foo)] }
152
+ it { expect(subject[:on]).to eq [:foo, emb_one: %i(f_em_foo)] }
153
+ end
154
+
155
+ context 'with :all' do
156
+ let(:value) { :all }
157
+ it { expect(subject[:on]).to eq %i(foo b) }
158
+ end
159
+
160
+ context 'with :fields' do
161
+ let(:value) { :fields }
162
+ it { expect(subject[:on]).to eq %i(foo b) }
163
+ end
164
+
165
+ describe '#categorize_tracked_option' do
166
+ context 'with skipped field' do
167
+ let(:options) { { on: %i(foo bar), except: :foo } }
168
+ it { expect(subject[:fields]).to eq %w(b) }
169
+ end
170
+
171
+ context 'with skipped embeds_one relation' do
172
+ let(:options) { { on: %i(fields emb_one emb_two), except: :emb_one } }
173
+ it { expect(subject[:relations][:embeds_one]).to eq('emtw' => %w(_id f_em_baz)) }
174
+ end
175
+
176
+ context 'with skipped embeds_many relation' do
177
+ let(:options) { { on: %i(fields emb_threes emb_fours), except: :emb_threes } }
178
+ it { expect(subject[:relations][:embeds_many]).to eq('emfs' => %w(_id f_em_baz)) }
179
+ end
180
+
181
+ context 'with reserved field' do
182
+ let(:options) { { on: %i(_id _type foo deleted_at) } }
183
+ it { expect(subject[:fields]).to eq %w(foo) }
184
+ end
185
+
186
+ context 'when embeds_one attribute passed' do
187
+ let(:options) { { on: { emb_one: :f_em_foo } } }
188
+ it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w(_id f_em_foo)) }
189
+ end
190
+
191
+ context 'when embeds_one attributes array passed' do
192
+ let(:options) { { on: { emb_one: %i(f_em_foo) } } }
193
+ it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w(_id f_em_foo)) }
194
+ end
195
+
196
+ context 'when embeds_many attribute passed' do
197
+ let(:options) { { on: { emb_threes: :f_em_foo } } }
198
+ it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w(_id f_em_foo)) }
199
+ end
200
+
201
+ context 'when embeds_many attributes array passed' do
202
+ let(:options) { { on: { emb_threes: %i(f_em_foo) } } }
203
+ it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w(_id f_em_foo)) }
204
+ end
205
+
206
+ context 'when embeds_one attributes not passed' do
207
+ let(:options) { { on: :emb_one } }
208
+ it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w(_id f_em_foo fmb)) }
209
+ end
210
+
211
+ context 'when embeds_many attributes not passed' do
212
+ let(:options) { { on: :emb_threes } }
213
+ it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w(_id f_em_foo fmb)) }
214
+ end
215
+
216
+ context 'when embeds_one attribute alias passed' do
217
+ let(:options) { { on: { emb_one: %i(f_em_bar) } } }
218
+ it { expect(subject[:relations][:embeds_one]).to eq('emb_one' => %w(_id fmb)) }
219
+ end
220
+
221
+ context 'when embeds_many attribute alias passed' do
222
+ let(:options) { { on: { emb_threes: %i(f_em_bar) } } }
223
+ it { expect(subject[:relations][:embeds_many]).to eq('emb_threes' => %w(_id fmb)) }
224
+ end
225
+
226
+ context 'with field alias' do
227
+ let(:options) { { on: :bar } }
228
+ it { expect(subject[:fields]).to eq %w(b) }
229
+ end
230
+
231
+ context 'with dynamic field name' do
232
+ let(:options) { { on: :my_field } }
233
+ it { expect(subject[:dynamic]).to eq %w(my_field) }
234
+ end
235
+ end
236
+ end
237
+
238
+ describe ':modifier_field' do
239
+ let(:options) { { modifier_field: :my_modifier_field } }
240
+ it { expect(subject[:modifier_field]).to eq :my_modifier_field }
241
+ end
242
+
243
+ describe ':version_field' do
244
+ let(:options) { { version_field: :my_version_field } }
245
+ it { expect(subject[:version_field]).to eq :my_version_field }
246
+ end
247
+
248
+ describe ':paranoia_field' do
249
+ let(:options) { { paranoia_field: :my_paranoia_field } }
250
+ it { expect(subject[:paranoia_field]).to eq :my_paranoia_field }
251
+ end
252
+
253
+ describe ':changes_method' do
254
+ let(:options) { { changes_method: :my_changes_method } }
255
+ it { expect(subject[:changes_method]).to eq :my_changes_method }
256
+ end
257
+
258
+ describe ':scope' do
259
+ let(:options) { { scope: :my_scope } }
260
+ it { expect(subject[:scope]).to eq :my_scope }
261
+ end
262
+
263
+ describe ':track_create' do
264
+ let(:options) { { track_create: true } }
265
+ it { expect(subject[:track_create]).to be true }
266
+ end
267
+
268
+ describe ':track_update' do
269
+ let(:options) { { track_update: false } }
270
+ it { expect(subject[:track_update]).to be false }
271
+ end
272
+
273
+ describe ':track_destroy' do
274
+ let(:options) { { track_destroy: true } }
275
+ it { expect(subject[:track_destroy]).to be true }
276
+ end
277
+
278
+ describe '#remove_reserved_fields' do
279
+ let(:options) { { on: [:_id, :_type, :foo, :version, :modifier_id] } }
280
+ it { expect(subject[:fields]).to eq %w(foo) }
281
+ it { expect(subject[:dynamic]).to eq [] }
282
+ end
283
+ end
284
+ end
285
+ end
286
+
287
+ after :all do
288
+ Object.send(:remove_const, :ModelOne)
289
+ Object.send(:remove_const, :EmbOne)
290
+ Object.send(:remove_const, :EmbTwo)
291
+ Object.send(:remove_const, :EmbThree)
292
+ Object.send(:remove_const, :EmbFour)
293
+ end
294
+ end
@@ -0,0 +1,338 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongoid::History::Trackable do
4
+ describe 'SingletonMethods' do
5
+ before :all do
6
+ MyTrackableModel = Class.new do
7
+ include Mongoid::Document
8
+ include Mongoid::History::Trackable
9
+ field :foo
10
+ field :b, as: :bar
11
+ embeds_one :my_embed_one_model, inverse_class_name: 'MyEmbedOneModel'
12
+ embeds_one :my_untracked_embed_one_model, inverse_class_name: 'MyUntrackedEmbedOneModel'
13
+ embeds_many :my_embed_many_models, inverse_class_name: 'MyEmbedManyModel'
14
+ end
15
+
16
+ MyEmbedOneModel = Class.new do
17
+ include Mongoid::Document
18
+ field :baz
19
+ embedded_in :my_trackable_model
20
+ end
21
+
22
+ MyUntrackedEmbedOneModel = Class.new do
23
+ include Mongoid::Document
24
+ field :baz
25
+ embedded_in :my_trackable_model
26
+ end
27
+
28
+ MyEmbedManyModel = Class.new do
29
+ include Mongoid::Document
30
+ field :bla
31
+ embedded_in :my_trackable_model
32
+ end
33
+
34
+ MyTrackableModel.track_history(on: [:foo, :my_embed_one_model, :my_embed_many_models, :my_dynamic_field])
35
+ end
36
+
37
+ describe '#tracked?' do
38
+ before { allow(MyTrackableModel).to receive(:dynamic_enabled?) { false } }
39
+ it { expect(MyTrackableModel.tracked?(:foo)).to be true }
40
+ it { expect(MyTrackableModel.tracked?(:bar)).to be false }
41
+ it { expect(MyTrackableModel.tracked?(:my_embed_one_model)).to be true }
42
+ it { expect(MyTrackableModel.tracked?(:my_untracked_embed_one_model)).to be false }
43
+ it { expect(MyTrackableModel.tracked?(:my_embed_many_models)).to be true }
44
+ it { expect(MyTrackableModel.tracked?(:my_dynamic_field)).to be true }
45
+ end
46
+
47
+ describe '#dynamic_field?' do
48
+ before(:all) do
49
+ class EmbOne
50
+ include Mongoid::Document
51
+ embedded_in :my_model
52
+ end
53
+ end
54
+
55
+ context 'when dynamic enabled' do
56
+ context 'with embeds one relation' do
57
+ let(:my_model) do
58
+ Class.new do
59
+ include Mongoid::Document
60
+ include Mongoid::History::Trackable
61
+ store_in collection: :my_models
62
+ embeds_one :emb_one
63
+ track_history
64
+ end
65
+ end
66
+
67
+ it 'should track dynamic field' do
68
+ # Using `let` to define class and use that class inside `before` block to stub a method raises following error.
69
+ # RuntimeError:
70
+ # let declaration `my_model` accessed in a `before(:context)` hook at:
71
+ # /Users/vmc/projects/mongoid-history/spec/unit/singleton_methods_spec.rb:51:in `block (6 levels) in <top (required)>'
72
+ #
73
+ # `let` and `subject` declarations are not intended to be called
74
+ # in a `before(:context)` hook, as they exist to define state that
75
+ # is reset between each example, while `before(:context)` exists to
76
+ # define state that is shared across examples in an example group.
77
+ allow(my_model).to receive(:dynamic_enabled?) { true }
78
+ expect(my_model.dynamic_field?(:foo)).to be true
79
+ end
80
+
81
+ it 'should not track embeds_one relation' do
82
+ allow(my_model).to receive(:dynamic_enabled?) { true }
83
+ expect(my_model.dynamic_field?(:emb_one)).to be false
84
+ end
85
+ end
86
+
87
+ context 'with embeds one relation and alias' do
88
+ let(:my_model) do
89
+ Class.new do
90
+ include Mongoid::Document
91
+ include Mongoid::History::Trackable
92
+ store_in collection: :my_models
93
+ embeds_one :emb_one, inverse_class_name: 'EmbOne', store_as: :emo
94
+ track_history
95
+ end
96
+ end
97
+
98
+ it 'should not track embeds_one relation' do
99
+ allow(my_model).to receive(:dynamic_enabled?) { true }
100
+ expect(my_model.dynamic_field?(:emo)).to be false
101
+ end
102
+ end
103
+
104
+ context 'with embeds many relation' do
105
+ let(:my_model) do
106
+ Class.new do
107
+ include Mongoid::Document
108
+ include Mongoid::History::Trackable
109
+ store_in collection: :my_models
110
+ embeds_many :emb_ones, inverse_class_name: 'EmbOne'
111
+ track_history
112
+ end
113
+ end
114
+
115
+ it 'should not track embeds_many relation' do
116
+ allow(my_model).to receive(:dynamic_enabled?) { true }
117
+ expect(my_model.dynamic_field?(:emb_ones)).to be false
118
+ end
119
+ end
120
+
121
+ context 'with embeds many relation and alias' do
122
+ let(:my_model) do
123
+ Class.new do
124
+ include Mongoid::Document
125
+ include Mongoid::History::Trackable
126
+ store_in collection: :my_models
127
+ embeds_many :emb_ones, inverse_class_name: 'EmbOne', store_as: :emos
128
+ track_history
129
+ end
130
+ end
131
+
132
+ it 'should not track embeds_many relation' do
133
+ allow(my_model).to receive(:dynamic_enabled?) { true }
134
+ expect(my_model.dynamic_field?(:emos)).to be false
135
+ end
136
+ end
137
+ end
138
+
139
+ after(:all) do
140
+ Object.send(:remove_const, :EmbOne)
141
+ end
142
+ end
143
+
144
+ describe '#tracked_fields' do
145
+ it 'should include fields and dynamic fields' do
146
+ expect(MyTrackableModel.tracked_fields).to eq %w(foo my_dynamic_field)
147
+ end
148
+ end
149
+
150
+ describe '#tracked_relation?' do
151
+ it 'should return true if a relation is tracked' do
152
+ expect(MyTrackableModel.tracked_relation?(:my_embed_one_model)).to be true
153
+ expect(MyTrackableModel.tracked_relation?(:my_untracked_embed_one_model)).to be false
154
+ expect(MyTrackableModel.tracked_relation?(:my_embed_many_models)).to be true
155
+ end
156
+ end
157
+
158
+ describe '#tracked_embeds_one?' do
159
+ it { expect(MyTrackableModel.tracked_embeds_one?(:my_embed_one_model)).to be true }
160
+ it { expect(MyTrackableModel.tracked_embeds_one?(:my_untracked_embed_one_model)).to be false }
161
+ it { expect(MyTrackableModel.tracked_embeds_one?(:my_embed_many_models)).to be false }
162
+ end
163
+
164
+ describe '#tracked_embeds_one' do
165
+ it { expect(MyTrackableModel.tracked_embeds_one).to include 'my_embed_one_model' }
166
+ it { expect(MyTrackableModel.tracked_embeds_one).to_not include 'my_untracked_embed_one_model' }
167
+ end
168
+
169
+ describe '#tracked_embeds_one_attributes' do
170
+ before(:all) do
171
+ ModelOne = Class.new do
172
+ include Mongoid::Document
173
+ include Mongoid::History::Trackable
174
+ embeds_one :emb_one, inverse_class_name: 'EmbOne'
175
+ embeds_one :emb_two, store_as: :emt, inverse_class_name: 'EmbTwo'
176
+ embeds_one :emb_three, inverse_class_name: 'EmbThree'
177
+ end
178
+
179
+ EmbOne = Class.new do
180
+ include Mongoid::Document
181
+ field :em_foo
182
+ field :em_bar
183
+ embedded_in :model_one
184
+ end
185
+
186
+ EmbTwo = Class.new do
187
+ include Mongoid::Document
188
+ field :em_bar
189
+ embedded_in :model_one
190
+ end
191
+
192
+ EmbThree = Class.new do
193
+ include Mongoid::Document
194
+ field :em_baz
195
+ embedded_in :model_one
196
+ end
197
+ end
198
+ before(:each) { ModelOne.instance_variable_set(:@history_trackable_options, nil) }
199
+
200
+ context 'when relation tracked' do
201
+ before(:each) { ModelOne.track_history(on: :emb_one) }
202
+ it { expect(ModelOne.tracked_embeds_one_attributes('emb_one')).to eq %w(_id em_foo em_bar) }
203
+ end
204
+
205
+ context 'when relation tracked with alias' do
206
+ before(:each) { ModelOne.track_history(on: :emb_two) }
207
+ it { expect(ModelOne.tracked_embeds_one_attributes('emb_two')).to eq %w(_id em_bar) }
208
+ end
209
+
210
+ context 'when relation tracked with attributes' do
211
+ before(:each) { ModelOne.track_history(on: { emb_one: :em_foo }) }
212
+ it { expect(ModelOne.tracked_embeds_one_attributes('emb_one')).to eq %w(_id em_foo) }
213
+ end
214
+
215
+ context 'when relation not tracked' do
216
+ before(:each) { ModelOne.track_history(on: :fields) }
217
+ it { expect(ModelOne.tracked_embeds_one_attributes('emb_one')).to be_nil }
218
+ end
219
+
220
+ after(:all) do
221
+ Object.send(:remove_const, :ModelOne)
222
+ Object.send(:remove_const, :EmbOne)
223
+ Object.send(:remove_const, :EmbTwo)
224
+ Object.send(:remove_const, :EmbThree)
225
+ end
226
+ end
227
+
228
+ describe '#tracked_embeds_many?' do
229
+ it { expect(MyTrackableModel.tracked_embeds_many?(:my_embed_one_model)).to be false }
230
+ it { expect(MyTrackableModel.tracked_embeds_many?(:my_untracked_embed_one_model)).to be false }
231
+ it { expect(MyTrackableModel.tracked_embeds_many?(:my_embed_many_models)).to be true }
232
+ end
233
+
234
+ describe '#tracked_embeds_many' do
235
+ it { expect(MyTrackableModel.tracked_embeds_many).to eq ['my_embed_many_models'] }
236
+ end
237
+
238
+ describe '#tracked_embeds_many_attributes' do
239
+ before(:all) do
240
+ ModelOne = Class.new do
241
+ include Mongoid::Document
242
+ include Mongoid::History::Trackable
243
+ embeds_many :emb_ones, inverse_class_name: 'EmbOne'
244
+ embeds_many :emb_twos, store_as: :emts, inverse_class_name: 'EmbTwo'
245
+ embeds_many :emb_threes, inverse_class_name: 'EmbThree'
246
+ end
247
+
248
+ EmbOne = Class.new do
249
+ include Mongoid::Document
250
+ field :em_foo
251
+ field :em_bar
252
+ embedded_in :model_one
253
+ end
254
+
255
+ EmbTwo = Class.new do
256
+ include Mongoid::Document
257
+ field :em_bar
258
+ embedded_in :model_one
259
+ end
260
+
261
+ EmbThree = Class.new do
262
+ include Mongoid::Document
263
+ field :em_baz
264
+ embedded_in :model_one
265
+ end
266
+ end
267
+ before(:each) { ModelOne.instance_variable_set(:@history_trackable_options, nil) }
268
+
269
+ context 'when relation tracked' do
270
+ before(:each) { ModelOne.track_history(on: :emb_ones) }
271
+ it { expect(ModelOne.tracked_embeds_many_attributes('emb_ones')).to eq %w(_id em_foo em_bar) }
272
+ end
273
+
274
+ context 'when relation tracked with alias' do
275
+ before(:each) { ModelOne.track_history(on: :emb_twos) }
276
+ it { expect(ModelOne.tracked_embeds_many_attributes('emb_twos')).to eq %w(_id em_bar) }
277
+ end
278
+
279
+ context 'when relation tracked with attributes' do
280
+ before(:each) { ModelOne.track_history(on: { emb_ones: :em_foo }) }
281
+ it { expect(ModelOne.tracked_embeds_many_attributes('emb_ones')).to eq %w(_id em_foo) }
282
+ end
283
+
284
+ context 'when relation not tracked' do
285
+ before(:each) { ModelOne.track_history(on: :fields) }
286
+ it { expect(ModelOne.tracked_embeds_many_attributes('emb_ones')).to be_nil }
287
+ end
288
+
289
+ after(:all) do
290
+ Object.send(:remove_const, :ModelOne)
291
+ Object.send(:remove_const, :EmbOne)
292
+ Object.send(:remove_const, :EmbTwo)
293
+ Object.send(:remove_const, :EmbThree)
294
+ end
295
+ end
296
+
297
+ describe '#trackable_scope' do
298
+ let(:model_one) do
299
+ Class.new do
300
+ include Mongoid::Document
301
+ include Mongoid::History::Trackable
302
+ store_in collection: :model_ones
303
+ track_history
304
+ end
305
+ end
306
+
307
+ it { expect(model_one.trackable_scope).to eq(:model_one) }
308
+ end
309
+
310
+ describe '#clear_trackable_memoization' do
311
+ before do
312
+ MyTrackableModel.instance_variable_set(:@reserved_tracked_fields, %w(_id _type))
313
+ MyTrackableModel.instance_variable_set(:@history_trackable_options, on: %w(fields))
314
+ MyTrackableModel.instance_variable_set(:@trackable_settings, paranoia_field: 'deleted_at')
315
+ MyTrackableModel.instance_variable_set(:@tracked_fields, %w(foo))
316
+ MyTrackableModel.instance_variable_set(:@tracked_embeds_one, %w(my_embed_one_model))
317
+ MyTrackableModel.instance_variable_set(:@tracked_embeds_many, %w(my_embed_many_models))
318
+ MyTrackableModel.clear_trackable_memoization
319
+ end
320
+
321
+ it 'should clear all the trackable memoization' do
322
+ expect(MyTrackableModel.instance_variable_get(:@reserved_tracked_fields)).to be_nil
323
+ expect(MyTrackableModel.instance_variable_get(:@history_trackable_options)).to be_nil
324
+ expect(MyTrackableModel.instance_variable_get(:@trackable_settings)).to be_nil
325
+ expect(MyTrackableModel.instance_variable_get(:@tracked_fields)).to be_nil
326
+ expect(MyTrackableModel.instance_variable_get(:@tracked_embeds_one)).to be_nil
327
+ expect(MyTrackableModel.instance_variable_get(:@tracked_embeds_many)).to be_nil
328
+ end
329
+ end
330
+
331
+ after :all do
332
+ Object.send(:remove_const, :MyTrackableModel)
333
+ Object.send(:remove_const, :MyEmbedOneModel)
334
+ Object.send(:remove_const, :MyUntrackedEmbedOneModel)
335
+ Object.send(:remove_const, :MyEmbedManyModel)
336
+ end
337
+ end
338
+ end