audited 4.2.1 → 4.4.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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +20 -9
  3. data/Appraisals +11 -6
  4. data/CHANGELOG.md +190 -0
  5. data/Gemfile +1 -13
  6. data/README.md +65 -34
  7. data/Rakefile +3 -18
  8. data/gemfiles/rails40.gemfile +1 -5
  9. data/gemfiles/rails41.gemfile +1 -5
  10. data/gemfiles/rails42.gemfile +1 -5
  11. data/gemfiles/rails50.gemfile +7 -0
  12. data/gemfiles/rails51.gemfile +7 -0
  13. data/lib/audited/audit.rb +126 -56
  14. data/lib/audited/auditor.rb +76 -44
  15. data/lib/audited/rspec_matchers.rb +5 -1
  16. data/lib/audited/sweeper.rb +24 -46
  17. data/lib/audited/version.rb +1 -1
  18. data/lib/audited-rspec.rb +4 -0
  19. data/lib/audited.rb +16 -2
  20. data/lib/generators/audited/install_generator.rb +24 -0
  21. data/lib/generators/audited/migration.rb +15 -0
  22. data/lib/generators/audited/migration_helper.rb +9 -0
  23. data/lib/generators/audited/templates/add_association_to_audits.rb +11 -0
  24. data/lib/generators/audited/templates/add_comment_to_audits.rb +9 -0
  25. data/lib/generators/audited/templates/add_remote_address_to_audits.rb +10 -0
  26. data/lib/generators/audited/templates/add_request_uuid_to_audits.rb +10 -0
  27. data/lib/generators/audited/templates/install.rb +30 -0
  28. data/lib/generators/audited/templates/rename_association_to_associated.rb +23 -0
  29. data/lib/generators/audited/templates/rename_changes_to_audited_changes.rb +9 -0
  30. data/lib/generators/audited/templates/rename_parent_to_association.rb +11 -0
  31. data/lib/generators/audited/upgrade_generator.rb +59 -0
  32. data/spec/audited/audit_spec.rb +246 -0
  33. data/spec/audited/auditor_spec.rb +648 -0
  34. data/spec/audited/sweeper_spec.rb +108 -0
  35. data/spec/audited_spec_helpers.rb +6 -22
  36. data/spec/rails_app/config/environments/test.rb +7 -4
  37. data/spec/rails_app/config/initializers/secret_token.rb +1 -1
  38. data/spec/rails_app/config/routes.rb +1 -4
  39. data/spec/spec_helper.rb +7 -9
  40. data/spec/support/active_record/models.rb +24 -13
  41. data/spec/support/active_record/postgres/1_change_audited_changes_type_to_json.rb +12 -0
  42. data/spec/support/active_record/postgres/2_change_audited_changes_type_to_jsonb.rb +12 -0
  43. data/spec/support/active_record/schema.rb +37 -12
  44. data/test/db/version_1.rb +4 -4
  45. data/test/db/version_2.rb +4 -4
  46. data/test/db/version_3.rb +4 -4
  47. data/test/db/version_4.rb +4 -4
  48. data/test/db/version_5.rb +2 -2
  49. data/test/db/version_6.rb +2 -2
  50. data/test/install_generator_test.rb +31 -3
  51. data/test/upgrade_generator_test.rb +25 -10
  52. metadata +69 -43
  53. data/CHANGELOG +0 -34
  54. data/lib/audited/active_record/version.rb +0 -5
  55. data/lib/audited/mongo_mapper/version.rb +0 -5
  56. data/spec/support/mongo_mapper/connection.rb +0 -4
  57. data/spec/support/mongo_mapper/models.rb +0 -214
@@ -0,0 +1,648 @@
1
+ require "spec_helper"
2
+
3
+ describe Audited::Auditor do
4
+
5
+ describe "configuration" do
6
+ it "should include instance methods" do
7
+ expect(Models::ActiveRecord::User.new).to be_a_kind_of( Audited::Auditor::AuditedInstanceMethods)
8
+ end
9
+
10
+ it "should include class methods" do
11
+ expect(Models::ActiveRecord::User).to be_a_kind_of( Audited::Auditor::AuditedClassMethods )
12
+ end
13
+
14
+ ['created_at', 'updated_at', 'created_on', 'updated_on', 'lock_version', 'id', 'password'].each do |column|
15
+ it "should not audit #{column}" do
16
+ expect(Models::ActiveRecord::User.non_audited_columns).to include(column)
17
+ end
18
+ end
19
+
20
+ it "should be configurable which attributes are not audited via ignored_attributes" do
21
+ Audited.ignored_attributes = ['delta', 'top_secret', 'created_at']
22
+ class Secret < ::ActiveRecord::Base
23
+ audited
24
+ end
25
+
26
+ expect(Secret.non_audited_columns).to include('delta', 'top_secret', 'created_at')
27
+ end
28
+
29
+ it "should be configurable which attributes are not audited via non_audited_columns=" do
30
+ class Secret2 < ::ActiveRecord::Base
31
+ audited
32
+ self.non_audited_columns = ['delta', 'top_secret', 'created_at']
33
+ end
34
+
35
+ expect(Secret2.non_audited_columns).to include('delta', 'top_secret', 'created_at')
36
+ end
37
+
38
+ it "should not save non-audited columns" do
39
+ expect(create_user.audits.first.audited_changes.keys.any? { |col| ['created_at', 'updated_at', 'password'].include?( col ) }).to eq(false)
40
+ end
41
+
42
+ it "should not save other columns than specified in 'only' option" do
43
+ user = Models::ActiveRecord::UserOnlyPassword.create
44
+ user.instance_eval do
45
+ def non_column_attr
46
+ @non_column_attr
47
+ end
48
+
49
+ def non_column_attr=(val)
50
+ attribute_will_change!("non_column_attr")
51
+ @non_column_attr = val
52
+ end
53
+ end
54
+
55
+ user.password = "password"
56
+ user.non_column_attr = "some value"
57
+ user.save!
58
+ expect(user.audits.last.audited_changes.keys).to eq(%w{password})
59
+ end
60
+
61
+ if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' && Rails.version >= "4.2.0.0" # Postgres json and jsonb support was added in Rails 4.2
62
+ describe "'json' and 'jsonb' audited_changes column type" do
63
+ let(:migrations_path) { SPEC_ROOT.join("support/active_record/postgres") }
64
+
65
+ after do
66
+ ActiveRecord::Migrator.rollback([migrations_path])
67
+ end
68
+
69
+ it "should work if column type is 'json'" do
70
+ ActiveRecord::Migrator.up([migrations_path], 1)
71
+ Audited::Audit.reset_column_information
72
+ expect(Audited::Audit.columns_hash["audited_changes"].sql_type).to eq("json")
73
+
74
+ user = Models::ActiveRecord::User.create
75
+ user.name = "new name"
76
+ user.save!
77
+ expect(user.audits.last.audited_changes).to eq({"name" => [nil, "new name"]})
78
+ end
79
+
80
+ it "should work if column type is 'jsonb'" do
81
+ ActiveRecord::Migrator.up([migrations_path], 2)
82
+ Audited::Audit.reset_column_information
83
+ expect(Audited::Audit.columns_hash["audited_changes"].sql_type).to eq("jsonb")
84
+
85
+ user = Models::ActiveRecord::User.create
86
+ user.name = "new name"
87
+ user.save!
88
+ expect(user.audits.last.audited_changes).to eq({"name" => [nil, "new name"]})
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ describe :new do
95
+ it "should allow mass assignment of all unprotected attributes" do
96
+ yesterday = 1.day.ago
97
+
98
+ u = Models::ActiveRecord::NoAttributeProtectionUser.new(name: 'name',
99
+ username: 'username',
100
+ password: 'password',
101
+ activated: true,
102
+ suspended_at: yesterday,
103
+ logins: 2)
104
+
105
+ expect(u.name).to eq('name')
106
+ expect(u.username).to eq('username')
107
+ expect(u.password).to eq('password')
108
+ expect(u.activated).to eq(true)
109
+ expect(u.suspended_at.to_i).to eq(yesterday.to_i)
110
+ expect(u.logins).to eq(2)
111
+ end
112
+ end
113
+
114
+ describe "on create" do
115
+ let( :user ) { create_user audit_comment: "Create" }
116
+
117
+ it "should change the audit count" do
118
+ expect {
119
+ user
120
+ }.to change( Audited::Audit, :count ).by(1)
121
+ end
122
+
123
+ it "should create associated audit" do
124
+ expect(user.audits.count).to eq(1)
125
+ end
126
+
127
+ it "should set the action to create" do
128
+ expect(user.audits.first.action).to eq('create')
129
+ expect(Audited::Audit.creates.order(:id).last).to eq(user.audits.first)
130
+ expect(user.audits.creates.count).to eq(1)
131
+ expect(user.audits.updates.count).to eq(0)
132
+ expect(user.audits.destroys.count).to eq(0)
133
+ end
134
+
135
+ it "should store all the audited attributes" do
136
+ expect(user.audits.first.audited_changes).to eq(user.audited_attributes)
137
+ end
138
+
139
+ it "should store comment" do
140
+ expect(user.audits.first.comment).to eq('Create')
141
+ end
142
+
143
+ it "should not audit an attribute which is excepted if specified on create or destroy" do
144
+ on_create_destroy_except_name = Models::ActiveRecord::OnCreateDestroyExceptName.create(name: 'Bart')
145
+ expect(on_create_destroy_except_name.audits.first.audited_changes.keys.any?{|col| ['name'].include? col}).to eq(false)
146
+ end
147
+
148
+ it "should not save an audit if only specified on update/destroy" do
149
+ expect {
150
+ Models::ActiveRecord::OnUpdateDestroy.create!( name: 'Bart' )
151
+ }.to_not change( Audited::Audit, :count )
152
+ end
153
+ end
154
+
155
+ describe "on update" do
156
+ before do
157
+ @user = create_user( name: 'Brandon', audit_comment: 'Update' )
158
+ end
159
+
160
+ it "should save an audit" do
161
+ expect {
162
+ @user.update_attribute(:name, "Someone")
163
+ }.to change( Audited::Audit, :count ).by(1)
164
+ expect {
165
+ @user.update_attribute(:name, "Someone else")
166
+ }.to change( Audited::Audit, :count ).by(1)
167
+ end
168
+
169
+ it "should set the action to 'update'" do
170
+ @user.update_attributes name: 'Changed'
171
+ expect(@user.audits.last.action).to eq('update')
172
+ expect(Audited::Audit.updates.order(:id).last).to eq(@user.audits.last)
173
+ expect(@user.audits.updates.last).to eq(@user.audits.last)
174
+ end
175
+
176
+ it "should store the changed attributes" do
177
+ @user.update_attributes name: 'Changed'
178
+ expect(@user.audits.last.audited_changes).to eq({ 'name' => ['Brandon', 'Changed'] })
179
+ end
180
+
181
+ it "should store audit comment" do
182
+ expect(@user.audits.last.comment).to eq('Update')
183
+ end
184
+
185
+ it "should not save an audit if only specified on create/destroy" do
186
+ on_create_destroy = Models::ActiveRecord::OnCreateDestroy.create( name: 'Bart' )
187
+ expect {
188
+ on_create_destroy.update_attributes name: 'Changed'
189
+ }.to_not change( Audited::Audit, :count )
190
+ end
191
+
192
+ it "should not save an audit if the value doesn't change after type casting" do
193
+ @user.update_attributes! logins: 0, activated: true
194
+ expect { @user.update_attribute :logins, '0' }.to_not change( Audited::Audit, :count )
195
+ expect { @user.update_attribute :activated, 1 }.to_not change( Audited::Audit, :count )
196
+ expect { @user.update_attribute :activated, '1' }.to_not change( Audited::Audit, :count )
197
+ end
198
+
199
+ describe "with no dirty changes" do
200
+ it "does not create an audit if the record is not changed" do
201
+ expect {
202
+ @user.save!
203
+ }.to_not change( Audited::Audit, :count )
204
+ end
205
+
206
+ it "creates an audit when an audit comment is present" do
207
+ expect {
208
+ @user.audit_comment = "Comment"
209
+ @user.save!
210
+ }.to change( Audited::Audit, :count )
211
+ end
212
+ end
213
+ end
214
+
215
+ describe "on destroy" do
216
+ before do
217
+ @user = create_user
218
+ end
219
+
220
+ it "should save an audit" do
221
+ expect {
222
+ @user.destroy
223
+ }.to change( Audited::Audit, :count )
224
+
225
+ expect(@user.audits.size).to eq(2)
226
+ end
227
+
228
+ it "should set the action to 'destroy'" do
229
+ @user.destroy
230
+
231
+ expect(@user.audits.last.action).to eq('destroy')
232
+ expect(Audited::Audit.destroys.order(:id).last).to eq(@user.audits.last)
233
+ expect(@user.audits.destroys.last).to eq(@user.audits.last)
234
+ end
235
+
236
+ it "should store all of the audited attributes" do
237
+ @user.destroy
238
+
239
+ expect(@user.audits.last.audited_changes).to eq(@user.audited_attributes)
240
+ end
241
+
242
+ it "should be able to reconstruct a destroyed record without history" do
243
+ @user.audits.delete_all
244
+ @user.destroy
245
+
246
+ revision = @user.audits.first.revision
247
+ expect(revision.name).to eq(@user.name)
248
+ end
249
+
250
+ it "should not save an audit if only specified on create/update" do
251
+ on_create_update = Models::ActiveRecord::OnCreateUpdate.create!( name: 'Bart' )
252
+
253
+ expect {
254
+ on_create_update.destroy
255
+ }.to_not change( Audited::Audit, :count )
256
+ end
257
+
258
+ it "should audit dependent destructions" do
259
+ owner = Models::ActiveRecord::Owner.create!
260
+ company = owner.companies.create!
261
+
262
+ expect {
263
+ owner.destroy
264
+ }.to change( Audited::Audit, :count )
265
+
266
+ expect(company.audits.map { |a| a.action }).to eq(['create', 'destroy'])
267
+ end
268
+ end
269
+
270
+ describe "on destroy with unsaved object" do
271
+ let(:user) { Models::ActiveRecord::User.new }
272
+
273
+ it "should not audit on 'destroy'" do
274
+ expect {
275
+ user.destroy
276
+ }.to_not raise_error
277
+
278
+ expect( user.audits ).to be_empty
279
+ end
280
+ end
281
+
282
+ describe "associated with" do
283
+ let(:owner) { Models::ActiveRecord::Owner.create(name: 'Models::ActiveRecord::Owner') }
284
+ let(:owned_company) { Models::ActiveRecord::OwnedCompany.create!(name: 'The auditors', owner: owner) }
285
+
286
+ it "should record the associated object on create" do
287
+ expect(owned_company.audits.first.associated).to eq(owner)
288
+ end
289
+
290
+ it "should store the associated object on update" do
291
+ owned_company.update_attribute(:name, 'The Auditors')
292
+ expect(owned_company.audits.last.associated).to eq(owner)
293
+ end
294
+
295
+ it "should store the associated object on destroy" do
296
+ owned_company.destroy
297
+ expect(owned_company.audits.last.associated).to eq(owner)
298
+ end
299
+ end
300
+
301
+ describe "has associated audits" do
302
+ let!(:owner) { Models::ActiveRecord::Owner.create!(name: 'Models::ActiveRecord::Owner') }
303
+ let!(:owned_company) { Models::ActiveRecord::OwnedCompany.create!(name: 'The auditors', owner: owner) }
304
+
305
+ it "should list the associated audits" do
306
+ expect(owner.associated_audits.length).to eq(1)
307
+ expect(owner.associated_audits.first.auditable).to eq(owned_company)
308
+ end
309
+ end
310
+
311
+ describe "revisions" do
312
+ let( :user ) { create_versions }
313
+
314
+ it "should return an Array of Users" do
315
+ expect(user.revisions).to be_a_kind_of( Array )
316
+ user.revisions.each { |version| expect(version).to be_a_kind_of Models::ActiveRecord::User }
317
+ end
318
+
319
+ it "should have one revision for a new record" do
320
+ expect(create_user.revisions.size).to eq(1)
321
+ end
322
+
323
+ it "should have one revision for each audit" do
324
+ expect(user.audits.size).to eql( user.revisions.size )
325
+ end
326
+
327
+ it "should set the attributes for each revision" do
328
+ u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
329
+ u.update_attributes name: 'Foobar'
330
+ u.update_attributes name: 'Awesome', username: 'keepers'
331
+
332
+ expect(u.revisions.size).to eql(3)
333
+
334
+ expect(u.revisions[0].name).to eql('Brandon')
335
+ expect(u.revisions[0].username).to eql('brandon')
336
+
337
+ expect(u.revisions[1].name).to eql('Foobar')
338
+ expect(u.revisions[1].username).to eql('brandon')
339
+
340
+ expect(u.revisions[2].name).to eql('Awesome')
341
+ expect(u.revisions[2].username).to eql('keepers')
342
+ end
343
+
344
+ it "access to only recent revisions" do
345
+ u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
346
+ u.update_attributes name: 'Foobar'
347
+ u.update_attributes name: 'Awesome', username: 'keepers'
348
+
349
+ expect(u.revisions(2).size).to eq(2)
350
+
351
+ expect(u.revisions(2)[0].name).to eq('Foobar')
352
+ expect(u.revisions(2)[0].username).to eq('brandon')
353
+
354
+ expect(u.revisions(2)[1].name).to eq('Awesome')
355
+ expect(u.revisions(2)[1].username).to eq('keepers')
356
+ end
357
+
358
+ it "should be empty if no audits exist" do
359
+ user.audits.delete_all
360
+ expect(user.revisions).to be_empty
361
+ end
362
+
363
+ it "should ignore attributes that have been deleted" do
364
+ user.audits.last.update_attributes audited_changes: {old_attribute: 'old value'}
365
+ expect { user.revisions }.to_not raise_error
366
+ end
367
+ end
368
+
369
+ describe "revisions" do
370
+ let( :user ) { create_versions(5) }
371
+
372
+ it "should maintain identity" do
373
+ expect(user.revision(1)).to eq(user)
374
+ end
375
+
376
+ it "should find the given revision" do
377
+ revision = user.revision(3)
378
+ expect(revision).to be_a_kind_of( Models::ActiveRecord::User )
379
+ expect(revision.version).to eq(3)
380
+ expect(revision.name).to eq('Foobar 3')
381
+ end
382
+
383
+ it "should find the previous revision with :previous" do
384
+ revision = user.revision(:previous)
385
+ expect(revision.version).to eq(4)
386
+ #expect(revision).to eq(user.revision(4))
387
+ expect(revision.attributes).to eq(user.revision(4).attributes)
388
+ end
389
+
390
+ it "should be able to get the previous revision repeatedly" do
391
+ previous = user.revision(:previous)
392
+ expect(previous.version).to eq(4)
393
+ expect(previous.revision(:previous).version).to eq(3)
394
+ end
395
+
396
+ it "should be able to set protected attributes" do
397
+ u = Models::ActiveRecord::User.create(name: 'Brandon')
398
+ u.update_attribute :logins, 1
399
+ u.update_attribute :logins, 2
400
+
401
+ expect(u.revision(3).logins).to eq(2)
402
+ expect(u.revision(2).logins).to eq(1)
403
+ expect(u.revision(1).logins).to eq(0)
404
+ end
405
+
406
+ it "should set attributes directly" do
407
+ u = Models::ActiveRecord::User.create(name: '<Joe>')
408
+ expect(u.revision(1).name).to eq('&lt;Joe&gt;')
409
+ end
410
+
411
+ it "should set the attributes for each revision" do
412
+ u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
413
+ u.update_attributes name: 'Foobar'
414
+ u.update_attributes name: 'Awesome', username: 'keepers'
415
+
416
+ expect(u.revision(3).name).to eq('Awesome')
417
+ expect(u.revision(3).username).to eq('keepers')
418
+
419
+ expect(u.revision(2).name).to eq('Foobar')
420
+ expect(u.revision(2).username).to eq('brandon')
421
+
422
+ expect(u.revision(1).name).to eq('Brandon')
423
+ expect(u.revision(1).username).to eq('brandon')
424
+ end
425
+
426
+ it "should be able to get time for first revision" do
427
+ suspended_at = Time.zone.now
428
+ u = Models::ActiveRecord::User.create(suspended_at: suspended_at)
429
+ expect(u.revision(1).suspended_at.to_s).to eq(suspended_at.to_s)
430
+ end
431
+
432
+ it "should not raise an error when no previous audits exist" do
433
+ user.audits.destroy_all
434
+ expect { user.revision(:previous) }.to_not raise_error
435
+ end
436
+
437
+ it "should mark revision's attributes as changed" do
438
+ expect(user.revision(1).name_changed?).to eq(true)
439
+ end
440
+
441
+ it "should record new audit when saving revision" do
442
+ expect {
443
+ user.revision(1).save!
444
+ }.to change( user.audits, :count ).by(1)
445
+ end
446
+
447
+ it "should re-insert destroyed records" do
448
+ user.destroy
449
+ expect {
450
+ user.revision(1).save!
451
+ }.to change( Models::ActiveRecord::User, :count ).by(1)
452
+ end
453
+ end
454
+
455
+ describe "revision_at" do
456
+ let( :user ) { create_user }
457
+
458
+ it "should find the latest revision before the given time" do
459
+ audit = user.audits.first
460
+ audit.created_at = 1.hour.ago
461
+ audit.save!
462
+ user.update_attributes name: 'updated'
463
+ expect(user.revision_at( 2.minutes.ago ).version).to eq(1)
464
+ end
465
+
466
+ it "should be nil if given a time before audits" do
467
+ expect(user.revision_at( 1.week.ago )).to be_nil
468
+ end
469
+ end
470
+
471
+ describe "without auditing" do
472
+ it "should not save an audit when calling #save_without_auditing" do
473
+ expect {
474
+ u = Models::ActiveRecord::User.new(name: 'Brandon')
475
+ expect(u.save_without_auditing).to eq(true)
476
+ }.to_not change( Audited::Audit, :count )
477
+ end
478
+
479
+ it "should not save an audit inside of the #without_auditing block" do
480
+ expect {
481
+ Models::ActiveRecord::User.without_auditing { Models::ActiveRecord::User.create!( name: 'Brandon' ) }
482
+ }.to_not change( Audited::Audit, :count )
483
+ end
484
+
485
+ it "should reset auditing status even it raises an exception" do
486
+ Models::ActiveRecord::User.without_auditing { raise } rescue nil
487
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
488
+ end
489
+
490
+ it "should be thread safe using a #without_auditing block" do
491
+ begin
492
+ t1 = Thread.new do
493
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
494
+ Models::ActiveRecord::User.without_auditing do
495
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
496
+ Models::ActiveRecord::User.create!( name: 'Bart' )
497
+ sleep 1
498
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
499
+ end
500
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
501
+ end
502
+
503
+ t2 = Thread.new do
504
+ sleep 0.5
505
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
506
+ Models::ActiveRecord::User.create!( name: 'Lisa' )
507
+ end
508
+ t1.join
509
+ t2.join
510
+
511
+ expect(Models::ActiveRecord::User.find_by_name('Bart').audits.count).to eq(0)
512
+ expect(Models::ActiveRecord::User.find_by_name('Lisa').audits.count).to eq(1)
513
+ rescue ActiveRecord::StatementInvalid
514
+ STDERR.puts "Thread safety tests cannot be run with SQLite"
515
+ end
516
+ end
517
+ end
518
+
519
+ describe "comment required" do
520
+
521
+ describe "on create" do
522
+ it "should not validate when audit_comment is not supplied" do
523
+ expect(Models::ActiveRecord::CommentRequiredUser.new).not_to be_valid
524
+ end
525
+
526
+ it "should validate when audit_comment is supplied" do
527
+ expect(Models::ActiveRecord::CommentRequiredUser.new( audit_comment: 'Create')).to be_valid
528
+ end
529
+
530
+ it "should validate when audit_comment is not supplied, and auditing is disabled" do
531
+ Models::ActiveRecord::CommentRequiredUser.disable_auditing
532
+ expect(Models::ActiveRecord::CommentRequiredUser.new).to be_valid
533
+ Models::ActiveRecord::CommentRequiredUser.enable_auditing
534
+ end
535
+ end
536
+
537
+ describe "on update" do
538
+ let( :user ) { Models::ActiveRecord::CommentRequiredUser.create!( audit_comment: 'Create' ) }
539
+
540
+ it "should not validate when audit_comment is not supplied" do
541
+ expect(user.update_attributes(name: 'Test')).to eq(false)
542
+ end
543
+
544
+ it "should validate when audit_comment is supplied" do
545
+ expect(user.update_attributes(name: 'Test', audit_comment: 'Update')).to eq(true)
546
+ end
547
+
548
+ it "should validate when audit_comment is not supplied, and auditing is disabled" do
549
+ Models::ActiveRecord::CommentRequiredUser.disable_auditing
550
+ expect(user.update_attributes(name: 'Test')).to eq(true)
551
+ Models::ActiveRecord::CommentRequiredUser.enable_auditing
552
+ end
553
+ end
554
+
555
+ describe "on destroy" do
556
+ let( :user ) { Models::ActiveRecord::CommentRequiredUser.create!( audit_comment: 'Create' )}
557
+
558
+ it "should not validate when audit_comment is not supplied" do
559
+ expect(user.destroy).to eq(false)
560
+ end
561
+
562
+ it "should validate when audit_comment is supplied" do
563
+ user.audit_comment = "Destroy"
564
+ expect(user.destroy).to eq(user)
565
+ end
566
+
567
+ it "should validate when audit_comment is not supplied, and auditing is disabled" do
568
+ Models::ActiveRecord::CommentRequiredUser.disable_auditing
569
+ expect(user.destroy).to eq(user)
570
+ Models::ActiveRecord::CommentRequiredUser.enable_auditing
571
+ end
572
+ end
573
+
574
+ end
575
+
576
+ describe "attr_protected and attr_accessible" do
577
+
578
+ it "should not raise error when attr_accessible is set and protected is false" do
579
+ expect {
580
+ Models::ActiveRecord::AccessibleAfterDeclarationUser.new(name: 'No fail!')
581
+ }.to_not raise_error
582
+ end
583
+
584
+ it "should not rause an error when attr_accessible is declared before audited" do
585
+ expect {
586
+ Models::ActiveRecord::AccessibleAfterDeclarationUser.new(name: 'No fail!')
587
+ }.to_not raise_error
588
+ end
589
+ end
590
+
591
+ describe "audit_as" do
592
+ let( :user ) { Models::ActiveRecord::User.create name: 'Testing' }
593
+
594
+ it "should record user objects" do
595
+ Models::ActiveRecord::Company.audit_as( user ) do
596
+ company = Models::ActiveRecord::Company.create name: 'The auditors'
597
+ company.update_attributes name: 'The Auditors'
598
+
599
+ company.audits.each do |audit|
600
+ expect(audit.user).to eq(user)
601
+ end
602
+ end
603
+ end
604
+
605
+ it "should record usernames" do
606
+ Models::ActiveRecord::Company.audit_as( user.name ) do
607
+ company = Models::ActiveRecord::Company.create name: 'The auditors'
608
+ company.update_attributes name: 'The Auditors'
609
+
610
+ company.audits.each do |audit|
611
+ expect(audit.user).to eq(user.name)
612
+ end
613
+ end
614
+ end
615
+ end
616
+
617
+ describe "after_audit" do
618
+ let( :user ) { user = Models::ActiveRecord::UserWithAfterAudit.new }
619
+
620
+ it "should invoke after_audit callback on create" do
621
+ expect(user.bogus_attr).to be_nil
622
+ expect(user.save).to eq(true)
623
+ expect(user.bogus_attr).to eq("do something")
624
+ end
625
+ end
626
+
627
+ describe "around_audit" do
628
+ let( :user ) { user = Models::ActiveRecord::UserWithAfterAudit.new }
629
+
630
+ it "should invoke around_audit callback on create" do
631
+ expect(user.around_attr).to be_nil
632
+ expect(user.save).to eq(true)
633
+ expect(user.around_attr).to eq(user.audits.last)
634
+ end
635
+ end
636
+
637
+ describe "STI auditing" do
638
+ it "should correctly disable auditing when using STI" do
639
+ company = Models::ActiveRecord::Company::STICompany.create name: 'The auditors'
640
+ expect(company.type).to eq("Models::ActiveRecord::Company::STICompany")
641
+ expect {
642
+ Models::ActiveRecord::Company.auditing_enabled = false
643
+ company.update_attributes name: 'STI auditors'
644
+ Models::ActiveRecord::Company.auditing_enabled = true
645
+ }.to_not change( Audited::Audit, :count )
646
+ end
647
+ end
648
+ end