mongoid-history 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +22 -18
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +4 -0
  5. data/CONTRIBUTING.md +4 -4
  6. data/Gemfile +8 -6
  7. data/README.md +2 -12
  8. data/UPGRADING.md +20 -1
  9. data/lib/mongoid/history.rb +8 -4
  10. data/lib/mongoid/history/attributes/base.rb +2 -2
  11. data/lib/mongoid/history/attributes/create.rb +2 -2
  12. data/lib/mongoid/history/attributes/update.rb +2 -2
  13. data/lib/mongoid/history/options.rb +11 -20
  14. data/lib/mongoid/history/trackable.rb +71 -56
  15. data/lib/mongoid/history/tracker.rb +8 -5
  16. data/lib/mongoid/history/version.rb +1 -1
  17. data/spec/integration/embedded_in_polymorphic_spec.rb +26 -49
  18. data/spec/integration/integration_spec.rb +132 -120
  19. data/spec/integration/multi_relation_spec.rb +14 -20
  20. data/spec/integration/multiple_trackers_spec.rb +35 -38
  21. data/spec/integration/nested_embedded_documents_spec.rb +31 -51
  22. data/spec/integration/nested_embedded_polymorphic_documents_spec.rb +64 -76
  23. data/spec/integration/subclasses_spec.rb +17 -5
  24. data/spec/integration/track_history_order_spec.rb +59 -27
  25. data/spec/integration/validation_failure_spec.rb +21 -8
  26. data/spec/spec_helper.rb +6 -1
  27. data/spec/unit/attributes/base_spec.rb +17 -26
  28. data/spec/unit/attributes/create_spec.rb +152 -125
  29. data/spec/unit/attributes/destroy_spec.rb +68 -58
  30. data/spec/unit/attributes/update_spec.rb +71 -50
  31. data/spec/unit/callback_options_spec.rb +36 -30
  32. data/spec/unit/embedded_methods_spec.rb +42 -24
  33. data/spec/unit/history_spec.rb +12 -10
  34. data/spec/unit/my_instance_methods_spec.rb +191 -121
  35. data/spec/unit/options_spec.rb +49 -26
  36. data/spec/unit/singleton_methods_spec.rb +156 -88
  37. data/spec/unit/trackable_spec.rb +254 -156
  38. data/spec/unit/tracker_spec.rb +81 -54
  39. metadata +2 -2
@@ -179,10 +179,11 @@ module Mongoid
179
179
 
180
180
  def create_on_parent
181
181
  name = association_chain.last['name']
182
+
182
183
  if trackable_parent.class.embeds_one?(name)
183
- trackable_parent.create_embedded(name, localize_keys(original))
184
+ trackable_parent._create_relation(name, localize_keys(original))
184
185
  elsif trackable_parent.class.embeds_many?(name)
185
- trackable_parent.get_embedded(name).create!(localize_keys(original))
186
+ trackable_parent._get_relation(name).create!(localize_keys(original))
186
187
  else
187
188
  raise 'This should never happen. Please report bug!'
188
189
  end
@@ -205,11 +206,13 @@ module Mongoid
205
206
  klass = name.classify.constantize
206
207
  klass.unscoped.where(_id: node['id']).first
207
208
  elsif doc.class.embeds_one?(name)
208
- doc.get_embedded(name)
209
+ doc._get_relation(name)
209
210
  elsif doc.class.embeds_many?(name)
210
- doc.get_embedded(name).unscoped.where(_id: node['id']).first
211
+ doc._get_relation(name).unscoped.where(_id: node['id']).first
211
212
  else
212
- raise 'This should never happen. Please report bug.'
213
+ relation_klass = doc.class.relation_class_of(name) if doc
214
+ relation_klass ||= 'nil'
215
+ raise "Unexpected relation for field '#{name}': #{relation_klass}. This should never happen. Please report bug."
213
216
  end
214
217
  documents << doc
215
218
  break if chain.empty?
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module History
3
- VERSION = '0.8.0'.freeze
3
+ VERSION = '0.8.1'.freeze
4
4
  end
5
5
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Mongoid::History::Tracker do
4
- before :all do
4
+ before :each do
5
5
  class RealState
6
6
  include Mongoid::Document
7
7
  include Mongoid::History::Trackable
@@ -9,14 +9,9 @@ describe Mongoid::History::Tracker do
9
9
  field :name, type: String
10
10
  belongs_to :user
11
11
  embeds_one :address, class_name: 'Contact', as: :contactable
12
- embeds_one :embone, as: :embedable
13
-
14
- track_history on: :all, # track title and body fields only, default is :all
15
- modifier_field: :modifier, # adds "referenced_in :modifier" to track who made the change, default is :modifier
16
- version_field: :version, # adds "field :version, :type => Integer" to track current version, default is :version
17
- track_create: true, # track document creation, default is false
18
- track_update: true, # track document updates, default is true
19
- track_destroy: false # track document destruction, default is false
12
+ embeds_one :embone, as: :embedable
13
+
14
+ track_history
20
15
  end
21
16
 
22
17
  class Company
@@ -29,12 +24,7 @@ describe Mongoid::History::Tracker do
29
24
  embeds_one :second_address, class_name: 'Contact', as: :contactable
30
25
  embeds_one :embone, as: :embedable
31
26
 
32
- track_history on: :all, # track title and body fields only, default is :all
33
- modifier_field: :modifier, # adds "referenced_in :modifier" to track who made the change, default is :modifier
34
- version_field: :version, # adds "field :version, :type => Integer" to track current version, default is :version
35
- track_create: true, # track document creation, default is false
36
- track_update: true, # track document updates, default is true
37
- track_destroy: false # track document destruction, default is false
27
+ track_history
38
28
  end
39
29
 
40
30
  class Embone
@@ -44,13 +34,7 @@ describe Mongoid::History::Tracker do
44
34
  field :name
45
35
  embedded_in :embedable, polymorphic: true
46
36
 
47
- track_history on: :all, # track title and body fields only, default is :all
48
- modifier_field: :modifier, # adds "referenced_in :modifier" to track who made the change, default is :modifier
49
- version_field: :version, # adds "field :version, :type => Integer" to track current version, default is :version
50
- track_create: true, # track document creation, default is false
51
- track_update: true, # track document updates, default is true
52
- track_destroy: false, # track document destruction, default is false
53
- scope: :embedable
37
+ track_history scope: :embedable
54
38
  end
55
39
 
56
40
  class Contact
@@ -62,13 +46,7 @@ describe Mongoid::History::Tracker do
62
46
  field :state
63
47
  embedded_in :contactable, polymorphic: true
64
48
 
65
- track_history on: :all, # track title and body fields only, default is :all
66
- modifier_field: :modifier, # adds "referenced_in :modifier" to track who made the change, default is :modifier
67
- version_field: :version, # adds "field :version, :type => Integer" to track current version, default is :version
68
- track_create: true, # track document creation, default is false
69
- track_update: true, # track document updates, default is true
70
- track_destroy: false, # track document destruction, default is false
71
- scope: %i[real_state company]
49
+ track_history scope: %i[real_state company]
72
50
  end
73
51
 
74
52
  class User
@@ -78,58 +56,57 @@ describe Mongoid::History::Tracker do
78
56
  end
79
57
  end
80
58
 
81
- it 'tracks history for nested embedded documents with polymorphic relations' do
82
- user = User.new
83
- user.save!
59
+ after :each do
60
+ Object.send(:remove_const, :RealState)
61
+ Object.send(:remove_const, :Company)
62
+ Object.send(:remove_const, :Embone)
63
+ Object.send(:remove_const, :Contact)
64
+ Object.send(:remove_const, :User)
65
+ end
84
66
 
85
- real_state = user.real_states.build(name: 'rs_name')
67
+ let!(:user) { User.create! }
68
+
69
+ it 'tracks history for nested embedded documents with polymorphic relations' do
70
+ real_state = user.real_states.build(name: 'rs_name', modifier: user)
86
71
  real_state.save!
87
- real_state.build_address(address: 'Main Street #123', city: 'Highland Park', state: 'IL').save!
72
+ real_state.build_address(address: 'Main Street #123', city: 'Highland Park', state: 'IL', modifier: user).save!
88
73
  expect(real_state.history_tracks.count).to eq(2)
89
74
  expect(real_state.address.history_tracks.count).to eq(1)
90
75
 
91
76
  real_state.reload
92
- real_state.address.update_attribute(:address, 'Second Street')
77
+ real_state.address.update_attributes!(address: 'Second Street', modifier: user)
93
78
  expect(real_state.history_tracks.count).to eq(3)
94
79
  expect(real_state.address.history_tracks.count).to eq(2)
95
80
  expect(real_state.history_tracks.last.action).to eq('update')
96
81
 
97
- real_state.build_embone(name: 'Lorem ipsum').save!
82
+ real_state.build_embone(name: 'Lorem ipsum', modifier: user).save!
98
83
  expect(real_state.history_tracks.count).to eq(4)
99
84
  expect(real_state.embone.history_tracks.count).to eq(1)
100
85
  expect(real_state.embone.history_tracks.last.action).to eq('create')
101
86
  expect(real_state.embone.history_tracks.last.association_chain.last['name']).to eq('embone')
102
87
 
103
- company = user.companies.build(name: 'co_name')
88
+ company = user.companies.build(name: 'co_name', modifier: user)
104
89
  company.save!
105
- company.build_address(address: 'Main Street #456', city: 'Evanston', state: 'IL').save!
90
+ company.build_address(address: 'Main Street #456', city: 'Evanston', state: 'IL', modifier: user).save!
106
91
  expect(company.history_tracks.count).to eq(2)
107
92
  expect(company.address.history_tracks.count).to eq(1)
108
93
 
109
94
  company.reload
110
- company.address.update_attribute(:address, 'Second Street')
95
+ company.address.update_attributes!(address: 'Second Street', modifier: user)
111
96
  expect(company.history_tracks.count).to eq(3)
112
97
  expect(company.address.history_tracks.count).to eq(2)
113
98
  expect(company.history_tracks.last.action).to eq('update')
114
99
 
115
- company.build_second_address(address: 'Main Street #789', city: 'Highland Park', state: 'IL').save!
100
+ company.build_second_address(address: 'Main Street #789', city: 'Highland Park', state: 'IL', modifier: user).save!
116
101
  expect(company.history_tracks.count).to eq(4)
117
102
  expect(company.second_address.history_tracks.count).to eq(1)
118
103
  expect(company.second_address.history_tracks.last.action).to eq('create')
119
104
  expect(company.second_address.history_tracks.last.association_chain.last['name']).to eq('second_address')
120
105
 
121
- company.build_embone(name: 'Lorem ipsum').save!
106
+ company.build_embone(name: 'Lorem ipsum', modifier: user).save!
122
107
  expect(company.history_tracks.count).to eq(5)
123
108
  expect(company.embone.history_tracks.count).to eq(1)
124
109
  expect(company.embone.history_tracks.last.action).to eq('create')
125
110
  expect(company.embone.history_tracks.last.association_chain.last['name']).to eq('embone')
126
111
  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
135
112
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Mongoid::History do
4
- before :all do
4
+ before :each do
5
5
  class Post
6
6
  include Mongoid::Document
7
7
  include Mongoid::Timestamps
@@ -29,7 +29,8 @@ describe Mongoid::History do
29
29
  field :t, as: :title
30
30
  field :body
31
31
  embedded_in :commentable, polymorphic: true
32
- track_history on: %i[title body], scope: :post, track_create: true, track_destroy: true
32
+ # BUG: see https://github.com/mongoid/mongoid-history/issues/223, modifier_field_optional should not be necessary
33
+ track_history on: %i[title body], scope: :post, track_create: true, track_destroy: true, modifier_field_optional: true
33
34
  end
34
35
 
35
36
  class Section
@@ -54,7 +55,7 @@ describe Mongoid::History do
54
55
  field :city
55
56
  field :country
56
57
  field :aliases, type: Array
57
- track_history except: %i[email updated_at]
58
+ track_history except: %i[email updated_at], modifier_field_optional: true
58
59
  end
59
60
 
60
61
  class Tag
@@ -70,16 +71,22 @@ describe Mongoid::History do
70
71
 
71
72
  class Foo < Comment
72
73
  end
74
+ end
73
75
 
74
- @persisted_history_options = Mongoid::History.trackable_class_options
76
+ after :each do
77
+ Object.send(:remove_const, :Post)
78
+ Object.send(:remove_const, :Comment)
79
+ Object.send(:remove_const, :Section)
80
+ Object.send(:remove_const, :User)
81
+ Object.send(:remove_const, :Tag)
82
+ Object.send(:remove_const, :Foo)
75
83
  end
76
84
 
77
- before(:each) { Mongoid::History.trackable_class_options = @persisted_history_options }
78
85
  let(:user) { User.create!(name: 'Aaron', email: 'aaron@randomemail.com', aliases: ['bob'], country: 'Canada', city: 'Toronto', address: '21 Jump Street') }
79
86
  let(:another_user) { User.create!(name: 'Another Guy', email: 'anotherguy@randomemail.com') }
80
87
  let(:post) { Post.create!(title: 'Test', body: 'Post', modifier: user, views: 100) }
81
88
  let(:comment) { post.comments.create!(title: 'test', body: 'comment', modifier: user) }
82
- let(:tag) { Tag.create!(title: 'test') }
89
+ let(:tag) { Tag.create!(title: 'test', updated_by: user) }
83
90
 
84
91
  describe 'track' do
85
92
  describe 'on creation' do
@@ -96,7 +103,7 @@ describe Mongoid::History do
96
103
  end
97
104
 
98
105
  it 'should assign modifier' do
99
- expect(comment.history_tracks.first.modifier).to eq(user)
106
+ expect(comment.history_tracks.first.modifier.id).to eq(user.id)
100
107
  end
101
108
 
102
109
  it 'should assign version' do
@@ -150,65 +157,65 @@ describe Mongoid::History do
150
157
  it 'should create a history track if changed attributes match tracked attributes' do
151
158
  post # This will create history track records for creation
152
159
  expect do
153
- post.update_attributes(title: 'Another Test')
160
+ post.update_attributes!(title: 'Another Test')
154
161
  end.to change(Tracker, :count).by(1)
155
162
  end
156
163
 
157
164
  it 'should not create a history track if changed attributes do not match tracked attributes' do
158
165
  post # This will create history track records for creation
159
166
  expect do
160
- post.update_attributes(rating: 'untracked')
167
+ post.update_attributes!(rating: 'untracked')
161
168
  end.to change(Tracker, :count).by(0)
162
169
  end
163
170
 
164
171
  it 'should assign modified fields' do
165
- post.update_attributes(title: 'Another Test')
172
+ post.update_attributes!(title: 'Another Test')
166
173
  expect(post.history_tracks.last.modified).to eq(
167
174
  'title' => 'Another Test'
168
175
  )
169
176
  end
170
177
 
171
178
  it 'should assign method field' do
172
- post.update_attributes(title: 'Another Test')
179
+ post.update_attributes!(title: 'Another Test')
173
180
  expect(post.history_tracks.last.action).to eq('update')
174
181
  end
175
182
 
176
183
  it 'should assign original fields' do
177
- post.update_attributes(title: 'Another Test')
184
+ post.update_attributes!(title: 'Another Test')
178
185
  expect(post.history_tracks.last.original).to eq(
179
186
  'title' => 'Test'
180
187
  )
181
188
  end
182
189
 
183
190
  it 'should assign modifier' do
184
- post.update_attributes(title: 'Another Test')
185
- expect(post.history_tracks.first.modifier).to eq(user)
191
+ post.update_attributes!(title: 'Another Test')
192
+ expect(post.history_tracks.first.modifier.id).to eq(user.id)
186
193
  end
187
194
 
188
195
  it 'should assign version on history tracks' do
189
- post.update_attributes(title: 'Another Test')
196
+ post.update_attributes!(title: 'Another Test')
190
197
  expect(post.history_tracks.first.version).to eq(1)
191
198
  end
192
199
 
193
200
  it 'should assign version on post' do
194
201
  expect(post.version).to eq(1) # Created
195
- post.update_attributes(title: 'Another Test')
202
+ post.update_attributes!(title: 'Another Test')
196
203
  expect(post.version).to eq(2) # Updated
197
204
  end
198
205
 
199
206
  it 'should assign scope' do
200
- post.update_attributes(title: 'Another Test')
207
+ post.update_attributes!(title: 'Another Test')
201
208
  expect(post.history_tracks.first.scope).to eq('post')
202
209
  end
203
210
 
204
211
  it 'should assign association_chain' do
205
- post.update_attributes(title: 'Another Test')
212
+ post.update_attributes!(title: 'Another Test')
206
213
  expect(post.history_tracks.last.association_chain).to eq([{ 'id' => post.id, 'name' => 'Post' }])
207
214
  end
208
215
 
209
216
  it 'should exclude defined options' do
210
217
  name = user.name
211
- user.update_attributes(name: 'Aaron2', email: 'aaronsnewemail@randomemail.com')
218
+ user.update_attributes!(name: 'Aaron2', email: 'aaronsnewemail@randomemail.com')
212
219
  expect(user.history_tracks.last.original.keys).to eq(['n'])
213
220
  expect(user.history_tracks.last.original['n']).to eq(name)
214
221
  expect(user.history_tracks.last.modified.keys).to eq(['n'])
@@ -217,7 +224,7 @@ describe Mongoid::History do
217
224
 
218
225
  it 'should undo field changes' do
219
226
  name = user.name
220
- user.update_attributes(name: 'Aaron2', email: 'aaronsnewemail@randomemail.com')
227
+ user.update_attributes!(name: 'Aaron2', email: 'aaronsnewemail@randomemail.com')
221
228
  user.history_tracks.last.undo! nil
222
229
  expect(user.reload.name).to eq(name)
223
230
  end
@@ -225,22 +232,22 @@ describe Mongoid::History do
225
232
  it 'should undo non-existing field changes' do
226
233
  post = Post.create!(modifier: user, views: 100)
227
234
  expect(post.reload.title).to be_nil
228
- post.update_attributes(title: 'Aaron2')
235
+ post.update_attributes!(title: 'Aaron2')
229
236
  expect(post.reload.title).to eq('Aaron2')
230
- post.history_tracks.last.undo! nil
237
+ post.history_tracks.last.undo! user
231
238
  expect(post.reload.title).to be_nil
232
239
  end
233
240
 
234
241
  it 'should track array changes' do
235
242
  aliases = user.aliases
236
- user.update_attributes(aliases: %w[bob joe])
243
+ user.update_attributes!(aliases: %w[bob joe])
237
244
  expect(user.history_tracks.last.original['aliases']).to eq(aliases)
238
245
  expect(user.history_tracks.last.modified['aliases']).to eq(user.aliases)
239
246
  end
240
247
 
241
248
  it 'should undo array changes' do
242
249
  aliases = user.aliases
243
- user.update_attributes(aliases: %w[bob joe])
250
+ user.update_attributes!(aliases: %w[bob joe])
244
251
  user.history_tracks.last.undo! nil
245
252
  expect(user.reload.aliases).to eq(aliases)
246
253
  end
@@ -265,7 +272,7 @@ describe Mongoid::History do
265
272
  context 'update action' do
266
273
  subject { user.history_tracks.last.tracked_changes }
267
274
  before do
268
- user.update_attributes(name: 'Aaron2', email: nil, country: '', city: nil, phone: '867-5309', aliases: ['', 'bill', 'james'])
275
+ user.update_attributes!(name: 'Aaron2', email: nil, country: '', city: nil, phone: '867-5309', aliases: ['', 'bill', 'james'])
269
276
  end
270
277
  it { is_expected.to be_a HashWithIndifferentAccess }
271
278
  it 'should track changed field' do
@@ -311,7 +318,7 @@ describe Mongoid::History do
311
318
  context 'update action' do
312
319
  subject { user.history_tracks.last.tracked_edits }
313
320
  before do
314
- user.update_attributes(name: 'Aaron2', email: nil, country: '', city: nil, phone: '867-5309', aliases: ['', 'bill', 'james'])
321
+ user.update_attributes!(name: 'Aaron2', email: nil, country: '', city: nil, phone: '867-5309', aliases: ['', 'bill', 'james'])
315
322
  end
316
323
  it { is_expected.to be_a HashWithIndifferentAccess }
317
324
  it 'should track changed field' do
@@ -353,74 +360,74 @@ describe Mongoid::History do
353
360
  describe 'on update non-embedded twice' do
354
361
  it 'should assign version on post' do
355
362
  expect(post.version).to eq(1)
356
- post.update_attributes(title: 'Test2')
357
- post.update_attributes(title: 'Test3')
363
+ post.update_attributes!(title: 'Test2')
364
+ post.update_attributes!(title: 'Test3')
358
365
  expect(post.version).to eq(3)
359
366
  end
360
367
 
361
368
  it 'should create a history track if changed attributes match tracked attributes' do
362
369
  post # Created
363
370
  expect do
364
- post.update_attributes(title: 'Test2')
365
- post.update_attributes(title: 'Test3')
371
+ post.update_attributes!(title: 'Test2')
372
+ post.update_attributes!(title: 'Test3')
366
373
  end.to change(Tracker, :count).by(2)
367
374
  end
368
375
 
369
376
  it 'should create a history track of version 2' do
370
- post.update_attributes(title: 'Test2')
371
- post.update_attributes(title: 'Test3')
377
+ post.update_attributes!(title: 'Test2')
378
+ post.update_attributes!(title: 'Test3')
372
379
  expect(post.history_tracks.where(version: 2).first).not_to be_nil
373
380
  end
374
381
 
375
382
  it 'should assign modified fields' do
376
- post.update_attributes(title: 'Test2')
377
- post.update_attributes(title: 'Test3')
383
+ post.update_attributes!(title: 'Test2')
384
+ post.update_attributes!(title: 'Test3')
378
385
  expect(post.history_tracks.where(version: 3).first.modified).to eq(
379
386
  'title' => 'Test3'
380
387
  )
381
388
  end
382
389
 
383
390
  it 'should assign original fields' do
384
- post.update_attributes(title: 'Test2')
385
- post.update_attributes(title: 'Test3')
391
+ post.update_attributes!(title: 'Test2')
392
+ post.update_attributes!(title: 'Test3')
386
393
  expect(post.history_tracks.where(version: 3).first.original).to eq(
387
394
  'title' => 'Test2'
388
395
  )
389
396
  end
390
397
 
391
398
  it 'should assign modifier' do
392
- post.update_attributes(title: 'Another Test', modifier: another_user)
393
- expect(post.history_tracks.last.modifier).to eq(another_user)
399
+ post.update_attributes!(title: 'Another Test', modifier: another_user)
400
+ expect(post.history_tracks.last.modifier.id).to eq(another_user.id)
394
401
  end
395
402
  end
396
403
 
397
404
  describe 'on update embedded 1..N (embeds_many)' do
398
405
  it 'should assign version on comment' do
399
- comment.update_attributes(title: 'Test2')
406
+ comment.update_attributes!(title: 'Test2')
400
407
  expect(comment.version).to eq(2) # first track generated on creation
401
408
  end
402
409
 
403
410
  it 'should create a history track of version 2' do
404
- comment.update_attributes(title: 'Test2')
411
+ comment.update_attributes!(title: 'Test2')
405
412
  expect(comment.history_tracks.where(version: 2).first).not_to be_nil
406
413
  end
407
414
 
408
415
  it 'should assign modified fields' do
409
- comment.update_attributes(t: 'Test2')
416
+ comment.update_attributes!(t: 'Test2')
410
417
  expect(comment.history_tracks.where(version: 2).first.modified).to eq(
411
418
  't' => 'Test2'
412
419
  )
413
420
  end
414
421
 
415
422
  it 'should assign original fields' do
416
- comment.update_attributes(title: 'Test2')
423
+ comment.update_attributes!(title: 'Test2')
417
424
  expect(comment.history_tracks.where(version: 2).first.original).to eq(
418
425
  't' => 'test'
419
426
  )
420
427
  end
421
428
 
422
429
  it 'should be possible to undo from parent' do
423
- comment.update_attributes(title: 'Test 2')
430
+ comment.update_attributes!(title: 'Test 2')
424
431
  user
425
432
  post.history_tracks.last.undo!(user)
426
433
  comment.reload
@@ -428,16 +435,17 @@ describe Mongoid::History do
428
435
  end
429
436
 
430
437
  it 'should assign modifier' do
431
- post.update_attributes(title: 'Another Test', modifier: another_user)
432
- expect(post.history_tracks.last.modifier).to eq(another_user)
438
+ post.update_attributes!(title: 'Another Test', modifier: another_user)
439
+ expect(post.history_tracks.last.modifier.id).to eq(another_user.id)
433
440
  end
434
441
  end
435
442
 
436
443
  describe 'on update embedded 1..1 (embeds_one)' do
437
- let(:section) { Section.new(title: 'Technology') }
444
+ let(:section) { Section.new(title: 'Technology', modifier: user) }
438
445
 
439
446
  before(:each) do
440
447
  post.section = section
448
+ post.modifier = user
441
449
  post.save!
442
450
  post.reload
443
451
  post.section
@@ -448,39 +456,39 @@ describe Mongoid::History do
448
456
  end
449
457
 
450
458
  it 'should assign version on section' do
451
- section.update_attributes(title: 'Technology 2')
459
+ section.update_attributes!(title: 'Technology 2')
452
460
  expect(section.version).to eq(2) # first track generated on creation
453
461
  end
454
462
 
455
463
  it 'should create a history track of version 2' do
456
- section.update_attributes(title: 'Technology 2')
464
+ section.update_attributes!(title: 'Technology 2')
457
465
  expect(section.history_tracks.where(version: 2).first).not_to be_nil
458
466
  end
459
467
 
460
468
  it 'should assign modified fields' do
461
- section.update_attributes(title: 'Technology 2')
469
+ section.update_attributes!(title: 'Technology 2')
462
470
  expect(section.history_tracks.where(version: 2).first.modified).to eq(
463
471
  't' => 'Technology 2'
464
472
  )
465
473
  end
466
474
 
467
475
  it 'should assign original fields' do
468
- section.update_attributes(title: 'Technology 2')
476
+ section.update_attributes!(title: 'Technology 2')
469
477
  expect(section.history_tracks.where(version: 2).first.original).to eq(
470
478
  't' => 'Technology'
471
479
  )
472
480
  end
473
481
 
474
482
  it 'should be possible to undo from parent' do
475
- section.update_attributes(title: 'Technology 2')
483
+ section.update_attributes!(title: 'Technology 2')
476
484
  post.history_tracks.last.undo!(user)
477
485
  section.reload
478
486
  expect(section.title).to eq('Technology')
479
487
  end
480
488
 
481
489
  it 'should assign modifier' do
482
- section.update_attributes(title: 'Business', modifier: another_user)
483
- expect(post.history_tracks.last.modifier).to eq(another_user)
490
+ section.update_attributes!(title: 'Business', modifier: another_user)
491
+ expect(post.history_tracks.last.modifier.id).to eq(another_user.id)
484
492
  end
485
493
  end
486
494
 
@@ -509,28 +517,23 @@ describe Mongoid::History do
509
517
 
510
518
  it 'should be possible to create with redo after undo create embedded from parent' do
511
519
  comment # initialize
512
- post.comments.create!(title: 'The second one')
520
+ post.comments.create!(title: 'The second one', modifier: user)
513
521
  track = post.history_tracks[2]
522
+ expect(post.reload.comments.count).to eq 2
514
523
  track.undo!(user)
524
+ expect(post.reload.comments.count).to eq 1
515
525
  track.redo!(user)
516
- post.reload
517
- expect(post.comments.count).to eq(2)
526
+ expect(post.reload.comments.count).to eq 2
518
527
  end
519
528
  end
520
529
 
521
530
  describe 'embedded with cascading callbacks' do
522
531
  let(:tag_foo) { post.tags.create!(title: 'foo', updated_by: user) }
523
- let(:tag_bar) { post.tags.create!(title: 'bar') }
524
-
525
- # it "should have cascaded the creation callbacks and set timestamps" do
526
- # tag_foo; tag_bar # initialize
527
- # tag_foo.created_at.should_not be_nil
528
- # tag_foo.updated_at.should_not be_nil
529
- # end
532
+ let(:tag_bar) { post.tags.create!(title: 'bar', updated_by: user) }
530
533
 
531
534
  it 'should allow an update through the parent model' do
532
535
  update_hash = { 'post' => { 'tags_attributes' => { '1234' => { 'id' => tag_bar.id, 'title' => 'baz' } } } }
533
- post.update_attributes(update_hash['post'])
536
+ post.update_attributes!(update_hash['post'])
534
537
  expect(post.tags.last.title).to eq('baz')
535
538
  end
536
539
 
@@ -539,14 +542,14 @@ describe Mongoid::History do
539
542
  tag_bar # initialize
540
543
  expect(post.tags.count).to eq(2)
541
544
  update_hash = { 'post' => { 'tags_attributes' => { '1234' => { 'id' => tag_bar.id, 'title' => 'baz', '_destroy' => 'true' } } } }
542
- post.update_attributes(update_hash['post'])
545
+ post.update_attributes!(update_hash['post'])
543
546
  expect(post.tags.count).to eq(1)
544
547
  expect(post.history_tracks.to_a.last.action).to eq('destroy')
545
548
  end
546
549
 
547
550
  it 'should write relationship name for association_chain hiearchy instead of class name when using _destroy macro' do
548
551
  update_hash = { 'tags_attributes' => { '1234' => { 'id' => tag_foo.id, '_destroy' => '1' } } }
549
- post.update_attributes(update_hash)
552
+ post.update_attributes!(update_hash)
550
553
 
551
554
  # historically this would have evaluated to 'Tags' and an error would be thrown
552
555
  # on any call that walked up the association_chain, e.g. 'trackable'
@@ -557,7 +560,7 @@ describe Mongoid::History do
557
560
 
558
561
  describe 'non-embedded' do
559
562
  it 'should undo changes' do
560
- post.update_attributes(title: 'Test2')
563
+ post.update_attributes!(title: 'Test2')
561
564
  post.history_tracks.where(version: 2).last.undo!(user)
562
565
  post.reload
563
566
  expect(post.title).to eq('Test')
@@ -571,21 +574,21 @@ describe Mongoid::History do
571
574
 
572
575
  it 'should create a new history track after undo' do
573
576
  comment # initialize
574
- post.update_attributes(title: 'Test2')
577
+ post.update_attributes!(title: 'Test2')
575
578
  post.history_tracks.last.undo!(user)
576
579
  post.reload
577
580
  expect(post.history_tracks.count).to eq(4)
578
581
  end
579
582
 
580
583
  it 'should assign user as the modifier of the newly created history track' do
581
- post.update_attributes(title: 'Test2')
584
+ post.update_attributes!(title: 'Test2')
582
585
  post.history_tracks.where(version: 2).last.undo!(user)
583
586
  post.reload
584
- expect(post.history_tracks.where(version: 2).last.modifier).to eq(user)
587
+ expect(post.history_tracks.where(version: 2).last.modifier.id).to eq(user.id)
585
588
  end
586
589
 
587
590
  it 'should stay the same after undo and redo' do
588
- post.update_attributes(title: 'Test2')
591
+ post.update_attributes!(title: 'Test2')
589
592
  track = post.history_tracks.last
590
593
  track.undo!(user)
591
594
  track.redo!(user)
@@ -605,28 +608,28 @@ describe Mongoid::History do
605
608
 
606
609
  describe 'embedded' do
607
610
  it 'should undo changes' do
608
- comment.update_attributes(title: 'Test2')
611
+ comment.update_attributes!(title: 'Test2')
609
612
  comment.history_tracks.where(version: 2).first.undo!(user)
610
613
  comment.reload
611
614
  expect(comment.title).to eq('test')
612
615
  end
613
616
 
614
617
  it 'should create a new history track after undo' do
615
- comment.update_attributes(title: 'Test2')
618
+ comment.update_attributes!(title: 'Test2')
616
619
  comment.history_tracks.where(version: 2).first.undo!(user)
617
620
  comment.reload
618
621
  expect(comment.history_tracks.count).to eq(3)
619
622
  end
620
623
 
621
624
  it 'should assign user as the modifier of the newly created history track' do
622
- comment.update_attributes(title: 'Test2')
625
+ comment.update_attributes!(title: 'Test2')
623
626
  comment.history_tracks.where(version: 2).first.undo!(user)
624
627
  comment.reload
625
- expect(comment.history_tracks.where(version: 3).first.modifier).to eq(user)
628
+ expect(comment.history_tracks.where(version: 3).first.modifier.id).to eq(user.id)
626
629
  end
627
630
 
628
631
  it 'should stay the same after undo and redo' do
629
- comment.update_attributes(title: 'Test2')
632
+ comment.update_attributes!(title: 'Test2')
630
633
  track = comment.history_tracks.where(version: 2).first
631
634
  track.undo!(user)
632
635
  track.redo!(user)
@@ -702,7 +705,7 @@ describe Mongoid::History do
702
705
  [nil, :reload].each do |method|
703
706
  context (method || 'instance').to_s do
704
707
  before :each do
705
- comment.update_attributes(title: 'Test5')
708
+ comment.update_attributes!(title: 'Test5')
706
709
  end
707
710
 
708
711
  it 'should recognize :from, :to options' do
@@ -757,39 +760,8 @@ describe Mongoid::History do
757
760
  end
758
761
  end
759
762
 
760
- describe 'localized fields' do
761
- before :each do
762
- class Sausage
763
- include Mongoid::Document
764
- include Mongoid::History::Trackable
765
-
766
- field :flavour, localize: true
767
- track_history on: [:flavour], track_destroy: true
768
- end
769
- end
770
- it 'should correctly undo and redo' do
771
- if Sausage.respond_to?(:localized_fields)
772
- sausage = Sausage.create!(flavour_translations: { 'en' => 'Apple', 'nl' => 'Appel' })
773
- sausage.update_attributes(flavour: 'Guinness')
774
-
775
- track = sausage.history_tracks.last
776
-
777
- track.undo! user
778
- expect(sausage.reload.flavour).to eq('Apple')
779
-
780
- track.redo! user
781
- expect(sausage.reload.flavour).to eq('Guinness')
782
-
783
- sausage.destroy
784
- expect(sausage.history_tracks.last.action).to eq('destroy')
785
- sausage.history_tracks.last.undo! user
786
- expect(sausage.reload.flavour).to eq('Guinness')
787
- end
788
- end
789
- end
790
-
791
763
  describe 'embedded with a polymorphic trackable' do
792
- let(:foo) { Foo.new(title: 'a title', body: 'a body') }
764
+ let(:foo) { Foo.new(title: 'a title', body: 'a body', modifier: user) }
793
765
  before :each do
794
766
  post.comments << foo
795
767
  post.save!
@@ -815,7 +787,7 @@ describe Mongoid::History do
815
787
  end
816
788
  context 'an embedded model' do
817
789
  it 'should return the trackable parent class' do
818
- comment.update_attributes(title: 'Foo')
790
+ comment.update_attributes!(title: 'Foo')
819
791
  expect(comment.history_tracks.first.trackable_parent_class).to eq(Post)
820
792
  end
821
793
  it 'should return the parent class even if the trackable is deleted' do
@@ -827,7 +799,7 @@ describe Mongoid::History do
827
799
  end
828
800
 
829
801
  describe 'when default scope is present' do
830
- before do
802
+ before :each do
831
803
  class Post
832
804
  default_scope -> { where(title: nil) }
833
805
  end
@@ -844,7 +816,7 @@ describe Mongoid::History do
844
816
 
845
817
  describe 'post' do
846
818
  it 'should correctly undo and redo' do
847
- post.update_attributes(title: 'a new title')
819
+ post.update_attributes!(title: 'a new title')
848
820
  track = post.history_tracks.last
849
821
  track.undo! user
850
822
  expect(post.reload.title).to eq('Test')
@@ -853,7 +825,7 @@ describe Mongoid::History do
853
825
  end
854
826
 
855
827
  it 'should stay the same after undo and redo' do
856
- post.update_attributes(title: 'testing')
828
+ post.update_attributes!(title: 'testing')
857
829
  track = post.history_tracks.last
858
830
  track.undo! user
859
831
  track.redo! user
@@ -862,7 +834,7 @@ describe Mongoid::History do
862
834
  end
863
835
  describe 'comment' do
864
836
  it 'should correctly undo and redo' do
865
- comment.update_attributes(title: 'a new title')
837
+ comment.update_attributes!(title: 'a new title')
866
838
  track = comment.history_tracks.last
867
839
  track.undo! user
868
840
  expect(comment.reload.title).to eq('test')
@@ -871,7 +843,7 @@ describe Mongoid::History do
871
843
  end
872
844
 
873
845
  it 'should stay the same after undo and redo' do
874
- comment.update_attributes(title: 'testing')
846
+ comment.update_attributes!(title: 'testing')
875
847
  track = comment.history_tracks.last
876
848
  track.undo! user
877
849
  track.redo! user
@@ -880,7 +852,7 @@ describe Mongoid::History do
880
852
  end
881
853
  describe 'user' do
882
854
  it 'should correctly undo and redo' do
883
- user.update_attributes(name: 'a new name')
855
+ user.update_attributes!(name: 'a new name')
884
856
  track = user.history_tracks.last
885
857
  track.undo! user
886
858
  expect(user.reload.name).to eq('Aaron')
@@ -889,7 +861,7 @@ describe Mongoid::History do
889
861
  end
890
862
 
891
863
  it 'should stay the same after undo and redo' do
892
- user.update_attributes(name: 'testing')
864
+ user.update_attributes!(name: 'testing')
893
865
  track = user.history_tracks.last
894
866
  track.undo! user
895
867
  track.redo! user
@@ -898,7 +870,7 @@ describe Mongoid::History do
898
870
  end
899
871
  describe 'tag' do
900
872
  it 'should correctly undo and redo' do
901
- tag.update_attributes(title: 'a new title')
873
+ tag.update_attributes!(title: 'a new title')
902
874
  track = tag.history_tracks.last
903
875
  track.undo! user
904
876
  expect(tag.reload.title).to eq('test')
@@ -907,7 +879,7 @@ describe Mongoid::History do
907
879
  end
908
880
 
909
881
  it 'should stay the same after undo and redo' do
910
- tag.update_attributes(title: 'testing')
882
+ tag.update_attributes!(title: 'testing')
911
883
  track = tag.history_tracks.last
912
884
  track.undo! user
913
885
  track.redo! user
@@ -930,13 +902,53 @@ describe Mongoid::History do
930
902
  end
931
903
  end
932
904
 
905
+ after :each do
906
+ Object.send(:remove_const, :OverriddenChangesMethod)
907
+ end
908
+
933
909
  it 'should add foo to the changes history' do
934
- o = OverriddenChangesMethod.create
910
+ o = OverriddenChangesMethod.create(modifier: user)
935
911
  o.save!
936
912
  track = o.history_tracks.last
937
913
  expect(track.modified).to eq('foo' => 'baz')
938
914
  expect(track.original).to eq('foo' => 'bar')
939
915
  end
940
916
  end
917
+
918
+ describe 'localized fields' do
919
+ before :each do
920
+ class Sausage
921
+ include Mongoid::Document
922
+ include Mongoid::History::Trackable
923
+
924
+ field :flavour, localize: true
925
+ track_history on: [:flavour], track_destroy: true, modifier_field_optional: true
926
+ end
927
+ end
928
+
929
+ after :each do
930
+ Object.send(:remove_const, :Sausage)
931
+ end
932
+
933
+ it 'should correctly undo and redo' do
934
+ pending unless Sausage.respond_to?(:localized_fields)
935
+
936
+ sausage = Sausage.create!(flavour_translations: { 'en' => 'Apple', 'nl' => 'Appel' }, modifier: user)
937
+ sausage.update_attributes!(flavour: 'Guinness')
938
+
939
+ track = sausage.history_tracks.last
940
+
941
+ track.undo! user
942
+ expect(sausage.reload.flavour).to eq('Apple')
943
+
944
+ track.redo! user
945
+ expect(sausage.reload.flavour).to eq('Guinness')
946
+
947
+ sausage.destroy
948
+ expect(sausage.history_tracks.last.action).to eq('destroy')
949
+ sausage.history_tracks.last.undo! user
950
+ expect(sausage.reload.flavour).to eq('Guinness')
951
+ end
952
+ end
941
953
  end
942
954
  end