mongoid-history 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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