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
@@ -9,8 +9,8 @@ module Mongoid
9
9
  attr_writer :trackable
10
10
 
11
11
  field :association_chain, type: Array, default: []
12
- field :modified, type: Hash
13
- field :original, type: Hash
12
+ field :modified, type: Hash, default: {}
13
+ field :original, type: Hash, default: {}
14
14
  field :version, type: Integer
15
15
  field :action, type: String
16
16
  field :scope, type: String
@@ -91,7 +91,7 @@ module Mongoid
91
91
  @tracked_changes ||= (modified.keys | original.keys).inject(HashWithIndifferentAccess.new) do |h, k|
92
92
  h[k] = { from: original[k], to: modified[k] }.delete_if { |_, vv| vv.nil? }
93
93
  h
94
- end.delete_if { |k, v| v.blank? || !trackable_parent_class.tracked_field?(k) }
94
+ end.delete_if { |k, v| v.blank? || !trackable_parent_class.tracked?(k) }
95
95
  end
96
96
 
97
97
  # Outputs summary of edit actions performed: :add, :modify, :remove, or :array.
@@ -104,28 +104,31 @@ module Mongoid
104
104
  # remove: { field_3: old_val },
105
105
  # array: { field_4: {add: ['foo', 'bar'], remove: ['baz']} } }
106
106
  def tracked_edits
107
- @tracked_edits ||= tracked_changes.inject(HashWithIndifferentAccess.new) do |h, (k, v)|
108
- unless v[:from].blank? && v[:to].blank?
109
- if v[:from].blank?
110
- h[:add] ||= {}
111
- h[:add][k] = v[:to]
112
- elsif v[:to].blank?
113
- h[:remove] ||= {}
114
- h[:remove][k] = v[:from]
115
- else
116
- if v[:from].is_a?(Array) && v[:to].is_a?(Array)
117
- h[:array] ||= {}
118
- old_values = v[:from] - v[:to]
119
- new_values = v[:to] - v[:from]
120
- h[:array][k] = { add: new_values, remove: old_values }.delete_if { |_, vv| vv.blank? }
121
- else
122
- h[:modify] ||= {}
123
- h[:modify][k] = v
124
- end
125
- end
107
+ return @tracked_edits if @tracked_edits
108
+ @tracked_edits = HashWithIndifferentAccess.new
109
+
110
+ tracked_changes.each do |k, v|
111
+ next if v[:from].blank? && v[:to].blank?
112
+
113
+ if trackable_parent_class.tracked_embeds_many?(k)
114
+ prepare_tracked_edits_for_embeds_many(k, v)
115
+ elsif v[:from].blank?
116
+ @tracked_edits[:add] ||= {}
117
+ @tracked_edits[:add][k] = v[:to]
118
+ elsif v[:to].blank?
119
+ @tracked_edits[:remove] ||= {}
120
+ @tracked_edits[:remove][k] = v[:from]
121
+ elsif v[:from].is_a?(Array) && v[:to].is_a?(Array)
122
+ @tracked_edits[:array] ||= {}
123
+ old_values = v[:from] - v[:to]
124
+ new_values = v[:to] - v[:from]
125
+ @tracked_edits[:array][k] = { add: new_values, remove: old_values }.delete_if { |_, vv| vv.blank? }
126
+ else
127
+ @tracked_edits[:modify] ||= {}
128
+ @tracked_edits[:modify][k] = v
126
129
  end
127
- h
128
130
  end
131
+ @tracked_edits
129
132
  end
130
133
 
131
134
  # Similar to #tracked_changes, but contains only a single value for each
@@ -217,6 +220,19 @@ module Mongoid
217
220
  end if klass.respond_to?(:localized_fields)
218
221
  hash
219
222
  end
223
+
224
+ def prepare_tracked_edits_for_embeds_many(key, value)
225
+ @tracked_edits[:embeds_many] ||= {}
226
+ value[:from] ||= []
227
+ value[:to] ||= []
228
+ modify_ids = value[:from].map { |vv| vv['_id'] }.compact & value[:to].map { |vv| vv['_id'] }.compact
229
+ modify_values = modify_ids.map { |id| { from: value[:from].detect { |vv| vv['_id'] == id }, to: value[:to].detect { |vv| vv['_id'] == id } } }
230
+ modify_values.delete_if { |vv| vv[:from] == vv[:to] }
231
+ ignore_values = modify_values.map { |vv| [vv[:from], vv[:to]] }.flatten
232
+ old_values = value[:from] - value[:to] - ignore_values
233
+ new_values = value[:to] - value[:from] - ignore_values
234
+ @tracked_edits[:embeds_many][key] = { add: new_values, remove: old_values, modify: modify_values }.delete_if { |_, vv| vv.blank? }
235
+ end
220
236
  end
221
237
  end
222
238
  end
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module History
3
- VERSION = '0.5.0'
3
+ VERSION = '0.6.0'
4
4
  end
5
5
  end
@@ -22,12 +22,4 @@ Gem::Specification.new do |s|
22
22
  s.add_runtime_dependency 'mongoid', '>= 3.0'
23
23
  s.add_runtime_dependency 'mongoid-compatibility'
24
24
  s.add_runtime_dependency 'activesupport'
25
-
26
- s.add_development_dependency 'rake'
27
- s.add_development_dependency 'rspec', '~> 3.1'
28
- s.add_development_dependency 'bundler'
29
- s.add_development_dependency 'rubocop', '0.34.1'
30
- s.add_development_dependency 'yard'
31
- s.add_development_dependency 'gem-release'
32
- s.add_development_dependency 'coveralls'
33
25
  end
@@ -124,4 +124,12 @@ describe Mongoid::History::Tracker do
124
124
  expect(company.embone.history_tracks.last.action).to eq('create')
125
125
  expect(company.embone.history_tracks.last.association_chain.last['name']).to eq('embone')
126
126
  end
127
+
128
+ after :all do
129
+ Object.send(:remove_const, :RealState)
130
+ Object.send(:remove_const, :Company)
131
+ Object.send(:remove_const, :Embone)
132
+ Object.send(:remove_const, :Contact)
133
+ Object.send(:remove_const, :User)
134
+ end
127
135
  end
@@ -327,6 +327,10 @@ describe Mongoid::History do
327
327
  end
328
328
  end
329
329
  context 'with empty values' do
330
+ before do
331
+ allow(subject).to receive(:trackable_parent_class) { Tracker }
332
+ allow(Tracker).to receive(:tracked_embeds_many?) { false }
333
+ end
330
334
  subject { Tracker.new }
331
335
  it 'should skip empty values' do
332
336
  allow(subject).to receive(:tracked_changes) { { name: { to: '', from: [] }, city: { to: 'Toronto', from: '' } } }
@@ -2,12 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  describe Mongoid::History::Tracker do
4
4
  before :all do
5
- class Model
5
+ class Modelone
6
6
  include Mongoid::Document
7
7
  include Mongoid::History::Trackable
8
8
 
9
9
  field :name, type: String
10
- belongs_to :user, inverse_of: :models
10
+ belongs_to :user, inverse_of: :modelones
11
11
  embeds_many :embones
12
12
 
13
13
  track_history on: :all, # track title and body fields only, default is :all
@@ -24,7 +24,7 @@ describe Mongoid::History::Tracker do
24
24
 
25
25
  field :name
26
26
  embeds_many :embtwos, store_as: :ems
27
- embedded_in :model
27
+ embedded_in :modelone
28
28
 
29
29
  track_history on: :all, # track title and body fields only, default is :all
30
30
  modifier_field: :modifier, # adds "referenced_in :modifier" to track who made the change, default is :modifier
@@ -48,12 +48,12 @@ describe Mongoid::History::Tracker do
48
48
  track_create: false, # track document creation, default is false
49
49
  track_update: true, # track document updates, default is true
50
50
  track_destroy: false, # track document destruction, default is false
51
- scope: :model
51
+ scope: :modelone
52
52
  end
53
53
 
54
54
  class User
55
55
  include Mongoid::Document
56
- has_many :models, dependent: :destroy, inverse_of: :user
56
+ has_many :modelones, dependent: :destroy, inverse_of: :user
57
57
  end
58
58
  end
59
59
 
@@ -61,7 +61,7 @@ describe Mongoid::History::Tracker do
61
61
  user = User.new
62
62
  user.save!
63
63
 
64
- model = Model.new(name: 'm1name')
64
+ model = Modelone.new(name: 'm1name')
65
65
  model.user = user
66
66
  model.save!
67
67
  embedded1 = model.embones.create(name: 'e1name')
@@ -74,4 +74,11 @@ describe Mongoid::History::Tracker do
74
74
  expect(embedded1.reload.name).to eq('e1name')
75
75
  expect(embedded2.reload.name).to eq('e2name')
76
76
  end
77
+
78
+ after :all do
79
+ Object.send(:remove_const, :Modelone)
80
+ Object.send(:remove_const, :Embone)
81
+ Object.send(:remove_const, :Embtwo)
82
+ Object.send(:remove_const, :User)
83
+ end
77
84
  end
@@ -8,7 +8,7 @@ describe Mongoid::History::Tracker do
8
8
 
9
9
  field :name, type: String
10
10
  belongs_to :user
11
- embeds_one :embedded_one, as: :embedable
11
+ embeds_one :one_embedded, as: :embedable
12
12
 
13
13
  track_history on: :all,
14
14
  modifier_field: :modifier,
@@ -24,7 +24,7 @@ describe Mongoid::History::Tracker do
24
24
 
25
25
  field :name, type: String
26
26
  belongs_to :user
27
- embeds_one :embedded_one, as: :embedable
27
+ embeds_one :one_embedded, as: :embedable
28
28
 
29
29
  track_history on: :all,
30
30
  modifier_field: :modifier,
@@ -34,7 +34,7 @@ describe Mongoid::History::Tracker do
34
34
  track_destroy: true
35
35
  end
36
36
 
37
- class EmbeddedOne
37
+ class OneEmbedded
38
38
  include Mongoid::Document
39
39
  include Mongoid::History::Trackable
40
40
 
@@ -56,7 +56,7 @@ describe Mongoid::History::Tracker do
56
56
  include Mongoid::History::Trackable
57
57
 
58
58
  field :name
59
- embedded_in :embedded_one
59
+ embedded_in :one_embedded
60
60
 
61
61
  track_history on: :all,
62
62
  modifier_field: :modifier,
@@ -80,48 +80,48 @@ describe Mongoid::History::Tracker do
80
80
 
81
81
  modelone = user.modelones.build(name: 'modelone')
82
82
  modelone.save!
83
- modelone.build_embedded_one(name: 'modelone_embedded_one').save!
83
+ modelone.build_one_embedded(name: 'modelone_one_embedded').save!
84
84
  expect(modelone.history_tracks.count).to eq(2)
85
- expect(modelone.embedded_one.history_tracks.count).to eq(1)
85
+ expect(modelone.one_embedded.history_tracks.count).to eq(1)
86
86
 
87
87
  modelone.reload
88
- modelone.embedded_one.update_attribute(:name, 'modelone_embedded_one!')
88
+ modelone.one_embedded.update_attribute(:name, 'modelone_embedded_one!')
89
89
  expect(modelone.history_tracks.count).to eq(3)
90
- expect(modelone.embedded_one.history_tracks.count).to eq(2)
90
+ expect(modelone.one_embedded.history_tracks.count).to eq(2)
91
91
  expect(modelone.history_tracks.last.action).to eq('update')
92
92
 
93
- modelone.build_embedded_one(name: 'Lorem ipsum').save!
93
+ modelone.build_one_embedded(name: 'Lorem ipsum').save!
94
94
  expect(modelone.history_tracks.count).to eq(4)
95
- expect(modelone.embedded_one.history_tracks.count).to eq(1)
96
- expect(modelone.embedded_one.history_tracks.last.action).to eq('create')
97
- expect(modelone.embedded_one.history_tracks.last.association_chain.last['name']).to eq('embedded_one')
95
+ expect(modelone.one_embedded.history_tracks.count).to eq(1)
96
+ expect(modelone.one_embedded.history_tracks.last.action).to eq('create')
97
+ expect(modelone.one_embedded.history_tracks.last.association_chain.last['name']).to eq('one_embedded')
98
98
 
99
- embedded_one1 = modelone.embedded_one.embedded_twos.create(name: 'modelone_embedded_one_1')
99
+ embedded_one1 = modelone.one_embedded.embedded_twos.create(name: 'modelone_one_embedded_1')
100
100
  expect(modelone.history_tracks.count).to eq(5)
101
- expect(modelone.embedded_one.history_tracks.count).to eq(2)
101
+ expect(modelone.one_embedded.history_tracks.count).to eq(2)
102
102
  expect(embedded_one1.history_tracks.count).to eq(1)
103
103
 
104
104
  modeltwo = user.modeltwos.build(name: 'modeltwo')
105
105
  modeltwo.save!
106
- modeltwo.build_embedded_one(name: 'modeltwo_embedded_one').save!
106
+ modeltwo.build_one_embedded(name: 'modeltwo_one_embedded').save!
107
107
  expect(modeltwo.history_tracks.count).to eq(2)
108
- expect(modeltwo.embedded_one.history_tracks.count).to eq(1)
108
+ expect(modeltwo.one_embedded.history_tracks.count).to eq(1)
109
109
 
110
110
  modeltwo.reload
111
- modeltwo.embedded_one.update_attribute(:name, 'modeltwo_embedded_one!')
111
+ modeltwo.one_embedded.update_attribute(:name, 'modeltwo_one_embedded!')
112
112
  expect(modeltwo.history_tracks.count).to eq(3)
113
- expect(modeltwo.embedded_one.history_tracks.count).to eq(2)
113
+ expect(modeltwo.one_embedded.history_tracks.count).to eq(2)
114
114
  expect(modeltwo.history_tracks.last.action).to eq('update')
115
115
 
116
- modeltwo.build_embedded_one(name: 'Lorem ipsum').save!
116
+ modeltwo.build_one_embedded(name: 'Lorem ipsum').save!
117
117
  expect(modeltwo.history_tracks.count).to eq(4)
118
- expect(modeltwo.embedded_one.history_tracks.count).to eq(1)
119
- expect(modeltwo.embedded_one.history_tracks.last.action).to eq('create')
120
- expect(modeltwo.embedded_one.history_tracks.last.association_chain.last['name']).to eq('embedded_one')
118
+ expect(modeltwo.one_embedded.history_tracks.count).to eq(1)
119
+ expect(modeltwo.one_embedded.history_tracks.last.action).to eq('create')
120
+ expect(modeltwo.one_embedded.history_tracks.last.association_chain.last['name']).to eq('one_embedded')
121
121
 
122
- embedded_one2 = modeltwo.embedded_one.embedded_twos.create(name: 'modeltwo_embedded_one_1')
122
+ embedded_one2 = modeltwo.one_embedded.embedded_twos.create(name: 'modeltwo_one_embedded_1')
123
123
  expect(modeltwo.history_tracks.count).to eq(5)
124
- expect(modeltwo.embedded_one.history_tracks.count).to eq(2)
124
+ expect(modeltwo.one_embedded.history_tracks.count).to eq(2)
125
125
  expect(embedded_one2.history_tracks.count).to eq(1)
126
126
  end
127
127
  end
@@ -5,6 +5,11 @@ $LOAD_PATH.push File.expand_path('../../lib', __FILE__)
5
5
 
6
6
  require 'active_support/all'
7
7
  require 'mongoid'
8
+ require 'request_store'
9
+
10
+ # Undefine RequestStore so that it may be stubbed in specific tests
11
+ RequestStoreTemp = RequestStore
12
+ Object.send(:remove_const, :RequestStore)
8
13
 
9
14
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
10
15
 
@@ -15,5 +20,6 @@ RSpec.configure do |config|
15
20
  config.before :all do
16
21
  Mongoid.logger.level = Logger::INFO
17
22
  Mongo::Logger.logger.level = Logger::INFO if Mongoid::Compatibility::Version.mongoid5?
23
+ Mongoid.belongs_to_required_by_default = false if Mongoid::Compatibility::Version.mongoid6?
18
24
  end
19
25
  end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongoid::History::Attributes::Base do
4
+ let(:model_one) do
5
+ Class.new do
6
+ include Mongoid::Document
7
+ include Mongoid::History::Trackable
8
+ field :foo
9
+ field :b, as: :bar
10
+ def self.name
11
+ 'ModelOne'
12
+ end
13
+ end
14
+ end
15
+
16
+ let(:obj_one) { model_one.new }
17
+ let(:base) { described_class.new(obj_one) }
18
+ subject { base }
19
+
20
+ it { is_expected.to respond_to(:trackable) }
21
+
22
+ describe '#initialize' do
23
+ it { expect(base.instance_variable_get(:@trackable)).to eq obj_one }
24
+ end
25
+
26
+ describe '#trackable_class' do
27
+ subject { base.send(:trackable_class) }
28
+ it { is_expected.to eq model_one }
29
+ end
30
+
31
+ describe '#aliased_fields' do
32
+ subject { base.send(:aliased_fields) }
33
+ it { is_expected.to eq('id' => '_id', 'bar' => 'b') }
34
+ end
35
+
36
+ describe '#changes_method' do
37
+ before(:each) do
38
+ model_one.instance_variable_set(:@history_trackable_options, nil)
39
+ model_one.track_history changes_method: :my_changes
40
+ end
41
+ subject { base.send(:changes_method) }
42
+ it { is_expected.to eq :my_changes }
43
+ end
44
+
45
+ describe '#changes' do
46
+ before(:each) do
47
+ model_one.instance_variable_set(:@history_trackable_options, nil)
48
+ model_one.track_history
49
+ allow(obj_one).to receive(:changes) { { 'foo' => ['Foo', 'Foo-new'] } }
50
+ end
51
+ subject { base.send(:changes) }
52
+ it { is_expected.to eq('foo' => ['Foo', 'Foo-new']) }
53
+ end
54
+ end
@@ -0,0 +1,315 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongoid::History::Attributes::Create do
4
+ let(:model_one) do
5
+ 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
+ def self.name
12
+ 'ModelOne'
13
+ end
14
+ end
15
+ end
16
+
17
+ let(:obj_one) { model_one.new }
18
+ let(:base) { described_class.new(obj_one) }
19
+ subject { base }
20
+
21
+ describe '#attributes' do
22
+ subject { base.attributes }
23
+
24
+ describe 'fields' do
25
+ before(:each) do
26
+ model_one.instance_variable_set(:@history_trackable_options, nil)
27
+ model_one.track_history on: :foo
28
+ end
29
+ let(:obj_one) { model_one.new(foo: 'Foo', bar: 'Bar') }
30
+ it { is_expected.to eq('foo' => [nil, 'Foo']) }
31
+ end
32
+
33
+ describe '#insert_embeds_one_changes' do
34
+ context 'when untracked relation' do
35
+ before(:all) do
36
+ # Need class name constant
37
+ class ModelTwo
38
+ include Mongoid::Document
39
+ include Mongoid::History::Trackable
40
+ store_in collection: :model_twos
41
+ embeds_one :emb_one_one, inverse_class_name: 'EmbOneOne'
42
+ end
43
+
44
+ class EmbOneOne
45
+ include Mongoid::Document
46
+ field :em_bar
47
+ embedded_in :model_one
48
+ end
49
+ end
50
+
51
+ before(:each) do
52
+ ModelTwo.instance_variable_set(:@history_trackable_options, nil)
53
+ ModelTwo.track_history on: :fields
54
+ end
55
+
56
+ let(:obj_one) { ModelTwo.new(emb_one_one: emb_obj_one) }
57
+ let(:emb_obj_one) { EmbOneOne.new(em_bar: 'Em-Bar') }
58
+
59
+ it { is_expected.to eq({}) }
60
+
61
+ after(:all) do
62
+ Object.send(:remove_const, :ModelTwo)
63
+ Object.send(:remove_const, :EmbOneOne)
64
+ end
65
+ end
66
+
67
+ context 'when tracked relation' do
68
+ before(:all) do
69
+ # Need class name constant
70
+ class ModelTwo
71
+ include Mongoid::Document
72
+ include Mongoid::History::Trackable
73
+ store_in collection: :model_twos
74
+ embeds_one :emb_one_one, inverse_class_name: 'EmbOneOne'
75
+ end
76
+
77
+ class EmbOneOne
78
+ include Mongoid::Document
79
+ field :em_bar
80
+ embedded_in :model_one
81
+ end
82
+ end
83
+
84
+ before(:each) do
85
+ ModelTwo.instance_variable_set(:@history_trackable_options, nil)
86
+ ModelTwo.track_history on: :emb_one_one
87
+ end
88
+
89
+ let(:obj_one) { ModelTwo.new(emb_one_one: emb_obj_one) }
90
+ let(:emb_obj_one) { EmbOneOne.new(em_bar: 'Em-Bar') }
91
+
92
+ it { is_expected.to eq('emb_one_one' => [nil, { '_id' => emb_obj_one._id, 'em_bar' => 'Em-Bar' }]) }
93
+
94
+ after(:all) do
95
+ Object.send(:remove_const, :ModelTwo)
96
+ Object.send(:remove_const, :EmbOneOne)
97
+ end
98
+ end
99
+
100
+ context 'when paranoia_field without alias' do
101
+ before(:all) do
102
+ # Need class name constant
103
+ class ModelTwo
104
+ include Mongoid::Document
105
+ include Mongoid::History::Trackable
106
+ store_in collection: :model_twos
107
+ embeds_one :emb_one_one, inverse_class_name: 'EmbOneOne'
108
+ end
109
+
110
+ class EmbOneOne
111
+ include Mongoid::Document
112
+ include Mongoid::History::Trackable
113
+ field :em_bar
114
+ field :removed_at
115
+ embedded_in :model_one
116
+ end
117
+ end
118
+
119
+ before(:each) do
120
+ ModelTwo.instance_variable_set(:@history_trackable_options, nil)
121
+ EmbOneOne.instance_variable_set(:@rackable_settings, nil)
122
+ ModelTwo.track_history on: :emb_one_one
123
+ EmbOneOne.history_settings paranoia_field: :removed_at
124
+ end
125
+
126
+ let(:obj_one) { ModelTwo.new(emb_one_one: emb_obj_one) }
127
+ let(:emb_obj_one) { EmbOneOne.new(em_bar: 'Em-Bar', removed_at: Time.now) }
128
+
129
+ it { is_expected.to eq({}) }
130
+
131
+ after(:all) do
132
+ Object.send(:remove_const, :ModelTwo)
133
+ Object.send(:remove_const, :EmbOneOne)
134
+ end
135
+ end
136
+
137
+ context 'when paranoia_field with alias' do
138
+ before(:all) do
139
+ # Need class name constant
140
+ class ModelTwo
141
+ include Mongoid::Document
142
+ include Mongoid::History::Trackable
143
+ store_in collection: :model_twos
144
+ embeds_one :emb_one_one, inverse_class_name: 'EmbOneOne'
145
+ end
146
+
147
+ class EmbOneOne
148
+ include Mongoid::Document
149
+ include Mongoid::History::Trackable
150
+ field :em_bar
151
+ field :rmvt, as: :removed_at
152
+ embedded_in :model_one
153
+ end
154
+ end
155
+
156
+ before(:each) do
157
+ ModelTwo.instance_variable_set(:@history_trackable_options, nil)
158
+ EmbOneOne.instance_variable_set(:@rackable_settings, nil)
159
+ ModelTwo.track_history on: :emb_one_one
160
+ EmbOneOne.history_settings paranoia_field: :removed_at
161
+ end
162
+
163
+ let(:obj_one) { ModelTwo.new(emb_one_one: emb_obj_one) }
164
+ let(:emb_obj_one) { EmbOneOne.new(em_bar: 'Em-Bar', removed_at: Time.now) }
165
+
166
+ it { is_expected.to eq({}) }
167
+
168
+ after(:all) do
169
+ Object.send(:remove_const, :ModelTwo)
170
+ Object.send(:remove_const, :EmbOneOne)
171
+ end
172
+ end
173
+
174
+ context 'with permitted attributes' do
175
+ before(:all) do
176
+ # Need class name constant
177
+ class ModelTwo
178
+ include Mongoid::Document
179
+ include Mongoid::History::Trackable
180
+ store_in collection: :model_twos
181
+ embeds_one :emb_one_one, inverse_class_name: 'EmbOneOne'
182
+ end
183
+
184
+ class EmbOneOne
185
+ include Mongoid::Document
186
+ include Mongoid::History::Trackable
187
+ field :em_foo
188
+ field :em_bar
189
+ embedded_in :model_one
190
+ end
191
+ end
192
+
193
+ before(:each) do
194
+ ModelTwo.instance_variable_set(:@history_trackable_options, nil)
195
+ ModelTwo.track_history on: [{ emb_one_one: :em_bar }]
196
+ end
197
+
198
+ let(:obj_one) { ModelTwo.new(emb_one_one: emb_obj_one) }
199
+ let(:emb_obj_one) { EmbOneOne.new(em_foo: 'Em-Foo', em_bar: 'Em-Bar') }
200
+
201
+ it { is_expected.to eq('emb_one_one' => [nil, { '_id' => emb_obj_one._id, 'em_bar' => 'Em-Bar' }]) }
202
+
203
+ after(:all) do
204
+ Object.send(:remove_const, :ModelTwo)
205
+ Object.send(:remove_const, :EmbOneOne)
206
+ end
207
+ end
208
+
209
+ context 'when relation with alias' do
210
+ before(:all) do
211
+ # Need class name constant
212
+ class ModelTwo
213
+ include Mongoid::Document
214
+ include Mongoid::History::Trackable
215
+ store_in collection: :model_twos
216
+ embeds_one :emb_one_one, store_as: :eoo, inverse_class_name: 'EmbOneOne'
217
+ end
218
+
219
+ class EmbOneOne
220
+ include Mongoid::Document
221
+ field :em_bar
222
+ embedded_in :model_one
223
+ end
224
+ end
225
+
226
+ before(:each) do
227
+ ModelTwo.instance_variable_set(:@history_trackable_options, nil)
228
+ ModelTwo.track_history on: :emb_one_one
229
+ end
230
+
231
+ let(:obj_one) { ModelTwo.new(emb_one_one: emb_obj_one) }
232
+ let(:emb_obj_one) { EmbOneOne.new(em_bar: 'Em-Bar') }
233
+
234
+ it { is_expected.to eq('emb_one_one' => [nil, { '_id' => emb_obj_one._id, 'em_bar' => 'Em-Bar' }]) }
235
+
236
+ after(:all) do
237
+ Object.send(:remove_const, :ModelTwo)
238
+ Object.send(:remove_const, :EmbOneOne)
239
+ end
240
+ end
241
+
242
+ context 'when no object' do
243
+ before(:all) do
244
+ # Need class name constant
245
+ class ModelTwo
246
+ include Mongoid::Document
247
+ include Mongoid::History::Trackable
248
+ store_in collection: :model_twos
249
+ embeds_one :emb_one_one, store_as: :eoo, inverse_class_name: 'EmbOneOne'
250
+ end
251
+
252
+ class EmbOneOne
253
+ include Mongoid::Document
254
+ field :em_bar
255
+ embedded_in :model_one
256
+ end
257
+ end
258
+
259
+ before(:each) do
260
+ ModelTwo.instance_variable_set(:@history_trackable_options, nil)
261
+ ModelTwo.track_history on: :emb_one_one
262
+ end
263
+
264
+ let(:obj_one) { ModelTwo.new }
265
+
266
+ it { is_expected.to eq({}) }
267
+
268
+ after(:all) do
269
+ Object.send(:remove_const, :ModelTwo)
270
+ Object.send(:remove_const, :EmbOneOne)
271
+ end
272
+ end
273
+
274
+ context 'when object not paranoid' do
275
+ before(:all) do
276
+ # Need class name constant
277
+ class ModelTwo
278
+ include Mongoid::Document
279
+ include Mongoid::History::Trackable
280
+ store_in collection: :model_twos
281
+ embeds_one :emb_one_one, store_as: :eoo, inverse_class_name: 'EmbOneOne'
282
+ end
283
+
284
+ class EmbOneOne
285
+ include Mongoid::Document
286
+ include Mongoid::History::Trackable
287
+ field :em_bar
288
+ field :cancelled_at
289
+ embedded_in :model_one
290
+ end
291
+ end
292
+
293
+ before(:each) do
294
+ ModelTwo.instance_variable_set(:@history_trackable_options, nil)
295
+ EmbOneOne.instance_variable_set(:@trackable_settings, nil)
296
+ ModelTwo.track_history on: :emb_one_one
297
+ EmbOneOne.history_settings paranoia_field: :cancelled_at
298
+ end
299
+
300
+ let(:obj_one) { ModelTwo.new(emb_one_one: emb_obj_one) }
301
+ let(:emb_obj_one) { EmbOneOne.new(em_bar: 'Em-Bar') }
302
+
303
+ it { is_expected.to eq('emb_one_one' => [nil, { '_id' => emb_obj_one._id, 'em_bar' => 'Em-Bar' }]) }
304
+
305
+ after(:all) do
306
+ Object.send(:remove_const, :ModelTwo)
307
+ Object.send(:remove_const, :EmbOneOne)
308
+ end
309
+ end
310
+ end
311
+
312
+ describe '#insert_embeds_many_changes' do
313
+ end
314
+ end
315
+ end