audited 4.7.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of audited might be problematic. Click here for more details.

Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/.standard.yml +5 -0
  4. data/.travis.yml +35 -26
  5. data/Appraisals +27 -18
  6. data/CHANGELOG.md +106 -2
  7. data/Gemfile +1 -1
  8. data/README.md +88 -19
  9. data/Rakefile +6 -6
  10. data/gemfiles/rails50.gemfile +3 -0
  11. data/gemfiles/rails51.gemfile +3 -0
  12. data/gemfiles/rails52.gemfile +4 -2
  13. data/gemfiles/rails60.gemfile +10 -0
  14. data/gemfiles/rails61.gemfile +10 -0
  15. data/lib/audited-rspec.rb +3 -1
  16. data/lib/audited.rb +26 -8
  17. data/lib/audited/audit.rb +48 -43
  18. data/lib/audited/auditor.rb +135 -56
  19. data/lib/audited/railtie.rb +16 -0
  20. data/lib/audited/rspec_matchers.rb +5 -3
  21. data/lib/audited/sweeper.rb +3 -10
  22. data/lib/audited/version.rb +3 -1
  23. data/lib/generators/audited/install_generator.rb +9 -7
  24. data/lib/generators/audited/migration.rb +2 -0
  25. data/lib/generators/audited/migration_helper.rb +3 -1
  26. data/lib/generators/audited/templates/add_association_to_audits.rb +2 -0
  27. data/lib/generators/audited/templates/add_comment_to_audits.rb +2 -0
  28. data/lib/generators/audited/templates/add_remote_address_to_audits.rb +2 -0
  29. data/lib/generators/audited/templates/add_request_uuid_to_audits.rb +2 -0
  30. data/lib/generators/audited/templates/add_version_to_auditable_index.rb +23 -0
  31. data/lib/generators/audited/templates/install.rb +3 -1
  32. data/lib/generators/audited/templates/rename_association_to_associated.rb +2 -0
  33. data/lib/generators/audited/templates/rename_changes_to_audited_changes.rb +2 -0
  34. data/lib/generators/audited/templates/rename_parent_to_association.rb +2 -0
  35. data/lib/generators/audited/templates/revert_polymorphic_indexes_order.rb +2 -0
  36. data/lib/generators/audited/upgrade_generator.rb +20 -14
  37. data/spec/audited/audit_spec.rb +151 -62
  38. data/spec/audited/auditor_spec.rb +456 -239
  39. data/spec/audited/sweeper_spec.rb +29 -20
  40. data/spec/audited_spec.rb +18 -0
  41. data/spec/audited_spec_helpers.rb +7 -7
  42. data/spec/rails_app/app/assets/config/manifest.js +2 -0
  43. data/spec/rails_app/config/application.rb +7 -2
  44. data/spec/rails_app/config/database.yml +1 -0
  45. data/spec/rails_app/config/environment.rb +1 -1
  46. data/spec/rails_app/config/environments/test.rb +5 -5
  47. data/spec/rails_app/config/initializers/secret_token.rb +2 -2
  48. data/spec/spec_helper.rb +15 -13
  49. data/spec/support/active_record/models.rb +37 -11
  50. data/spec/support/active_record/postgres/1_change_audited_changes_type_to_json.rb +1 -2
  51. data/spec/support/active_record/postgres/2_change_audited_changes_type_to_jsonb.rb +1 -2
  52. data/spec/support/active_record/schema.rb +28 -20
  53. data/test/db/version_1.rb +2 -2
  54. data/test/db/version_2.rb +2 -2
  55. data/test/db/version_3.rb +2 -3
  56. data/test/db/version_4.rb +2 -3
  57. data/test/db/version_5.rb +0 -1
  58. data/test/db/version_6.rb +2 -0
  59. data/test/install_generator_test.rb +18 -19
  60. data/test/test_helper.rb +6 -7
  61. data/test/upgrade_generator_test.rb +22 -17
  62. metadata +64 -29
  63. data/gemfiles/rails40.gemfile +0 -9
  64. data/gemfiles/rails41.gemfile +0 -8
  65. data/gemfiles/rails42.gemfile +0 -8
  66. data/spec/rails_app/config/environments/development.rb +0 -21
  67. data/spec/rails_app/config/environments/production.rb +0 -35
@@ -1,17 +1,79 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Audited::Auditor do
3
+ SingleCov.covered! uncovered: 9 # not testing proxy_respond_to? hack / 2 methods / deprecation of `version`
4
+
5
+ class ConditionalPrivateCompany < ::ActiveRecord::Base
6
+ self.table_name = "companies"
7
+
8
+ audited if: :foo?
9
+
10
+ private def foo?
11
+ true
12
+ end
13
+ end
14
+
15
+ class ConditionalCompany < ::ActiveRecord::Base
16
+ self.table_name = "companies"
17
+
18
+ audited if: :public?
19
+
20
+ def public?
21
+ end
22
+ end
23
+
24
+ class ExclusiveCompany < ::ActiveRecord::Base
25
+ self.table_name = "companies"
26
+ audited if: proc { false }
27
+ end
28
+
29
+ class ExclusionaryCompany < ::ActiveRecord::Base
30
+ self.table_name = "companies"
31
+
32
+ audited unless: :non_profit?
33
+
34
+ def non_profit?
35
+ end
36
+ end
4
37
 
38
+ class ExclusionaryCompany2 < ::ActiveRecord::Base
39
+ self.table_name = "companies"
40
+ audited unless: proc { |c| c.exclusive? }
41
+
42
+ def exclusive?
43
+ true
44
+ end
45
+ end
46
+
47
+ class InclusiveCompany < ::ActiveRecord::Base
48
+ self.table_name = "companies"
49
+ audited if: proc { true }
50
+ end
51
+
52
+ class InclusiveCompany2 < ::ActiveRecord::Base
53
+ self.table_name = "companies"
54
+ audited unless: proc { false }
55
+ end
56
+
57
+ class Secret < ::ActiveRecord::Base
58
+ audited
59
+ end
60
+
61
+ class Secret2 < ::ActiveRecord::Base
62
+ audited
63
+ self.non_audited_columns = ["delta", "top_secret", "created_at"]
64
+ end
65
+
66
+ describe Audited::Auditor do
5
67
  describe "configuration" do
6
68
  it "should include instance methods" do
7
- expect(Models::ActiveRecord::User.new).to be_a_kind_of( Audited::Auditor::AuditedInstanceMethods)
69
+ expect(Models::ActiveRecord::User.new).to be_a_kind_of(Audited::Auditor::AuditedInstanceMethods)
8
70
  end
9
71
 
10
72
  it "should include class methods" do
11
- expect(Models::ActiveRecord::User).to be_a_kind_of( Audited::Auditor::AuditedClassMethods )
73
+ expect(Models::ActiveRecord::User).to be_a_kind_of(Audited::Auditor::AuditedClassMethods)
12
74
  end
13
75
 
14
- ['created_at', 'updated_at', 'created_on', 'updated_on', 'lock_version', 'id', 'password'].each do |column|
76
+ ["created_at", "updated_at", "created_on", "updated_on", "lock_version", "id", "password"].each do |column|
15
77
  it "should not audit #{column}" do
16
78
  expect(Models::ActiveRecord::User.non_audited_columns).to include(column)
17
79
  end
@@ -20,49 +82,32 @@ describe Audited::Auditor do
20
82
  context "should be configurable which conditions are audited" do
21
83
  subject { ConditionalCompany.new.send(:auditing_enabled) }
22
84
 
23
- context "when passing a method name" do
24
- before do
25
- class ConditionalCompany < ::ActiveRecord::Base
26
- self.table_name = 'companies'
27
-
28
- audited if: :public?
85
+ context "when condition method is private" do
86
+ subject { ConditionalPrivateCompany.new.send(:auditing_enabled) }
29
87
 
30
- def public?; end
31
- end
32
- end
88
+ it { is_expected.to be_truthy }
89
+ end
33
90
 
91
+ context "when passing a method name" do
34
92
  context "when conditions are true" do
35
93
  before { allow_any_instance_of(ConditionalCompany).to receive(:public?).and_return(true) }
36
- it { is_expected.to be_truthy }
94
+ it { is_expected.to be_truthy }
37
95
  end
38
96
 
39
97
  context "when conditions are false" do
40
98
  before { allow_any_instance_of(ConditionalCompany).to receive(:public?).and_return(false) }
41
- it { is_expected.to be_falsey }
99
+ it { is_expected.to be_falsey }
42
100
  end
43
101
  end
44
102
 
45
103
  context "when passing a Proc" do
46
104
  context "when conditions are true" do
47
- before do
48
- class InclusiveCompany < ::ActiveRecord::Base
49
- self.table_name = 'companies'
50
- audited if: Proc.new { true }
51
- end
52
- end
53
-
54
105
  subject { InclusiveCompany.new.send(:auditing_enabled) }
55
106
 
56
107
  it { is_expected.to be_truthy }
57
108
  end
58
109
 
59
110
  context "when conditions are false" do
60
- before do
61
- class ExclusiveCompany < ::ActiveRecord::Base
62
- self.table_name = 'companies'
63
- audited if: Proc.new { false }
64
- end
65
- end
66
111
  subject { ExclusiveCompany.new.send(:auditing_enabled) }
67
112
  it { is_expected.to be_falsey }
68
113
  end
@@ -71,76 +116,40 @@ describe Audited::Auditor do
71
116
 
72
117
  context "should be configurable which conditions aren't audited" do
73
118
  context "when using a method name" do
74
- before do
75
- class ExclusionaryCompany < ::ActiveRecord::Base
76
- self.table_name = 'companies'
77
-
78
- audited unless: :non_profit?
79
-
80
- def non_profit?; end
81
- end
82
- end
83
-
84
119
  subject { ExclusionaryCompany.new.send(:auditing_enabled) }
85
120
 
86
121
  context "when conditions are true" do
87
122
  before { allow_any_instance_of(ExclusionaryCompany).to receive(:non_profit?).and_return(true) }
88
- it { is_expected.to be_falsey }
123
+ it { is_expected.to be_falsey }
89
124
  end
90
125
 
91
126
  context "when conditions are false" do
92
127
  before { allow_any_instance_of(ExclusionaryCompany).to receive(:non_profit?).and_return(false) }
93
- it { is_expected.to be_truthy }
128
+ it { is_expected.to be_truthy }
94
129
  end
95
130
  end
96
131
 
97
132
  context "when using a proc" do
98
133
  context "when conditions are true" do
99
- before do
100
- class ExclusionaryCompany < ::ActiveRecord::Base
101
- self.table_name = 'companies'
102
- audited unless: Proc.new { |c| c.exclusive? }
103
-
104
- def exclusive?
105
- true
106
- end
107
- end
108
- end
109
-
110
- subject { ExclusionaryCompany.new.send(:auditing_enabled) }
111
- it { is_expected.to be_falsey }
134
+ subject { ExclusionaryCompany2.new.send(:auditing_enabled) }
135
+ it { is_expected.to be_falsey }
112
136
  end
113
137
 
114
138
  context "when conditions are false" do
115
- before do
116
- class InclusiveCompany < ::ActiveRecord::Base
117
- self.table_name = 'companies'
118
- audited unless: Proc.new { false }
119
- end
120
- end
121
-
122
- subject { InclusiveCompany.new.send(:auditing_enabled) }
123
- it { is_expected.to be_truthy }
139
+ subject { InclusiveCompany2.new.send(:auditing_enabled) }
140
+ it { is_expected.to be_truthy }
124
141
  end
125
142
  end
126
143
  end
127
144
 
128
145
  it "should be configurable which attributes are not audited via ignored_attributes" do
129
- Audited.ignored_attributes = ['delta', 'top_secret', 'created_at']
130
- class Secret < ::ActiveRecord::Base
131
- audited
132
- end
146
+ Audited.ignored_attributes = ["delta", "top_secret", "created_at"]
133
147
 
134
- expect(Secret.non_audited_columns).to include('delta', 'top_secret', 'created_at')
148
+ expect(Secret.non_audited_columns).to include("delta", "top_secret", "created_at")
135
149
  end
136
150
 
137
151
  it "should be configurable which attributes are not audited via non_audited_columns=" do
138
- class Secret2 < ::ActiveRecord::Base
139
- audited
140
- self.non_audited_columns = ['delta', 'top_secret', 'created_at']
141
- end
142
-
143
- expect(Secret2.non_audited_columns).to include('delta', 'top_secret', 'created_at')
152
+ expect(Secret2.non_audited_columns).to include("delta", "top_secret", "created_at")
144
153
  end
145
154
 
146
155
  it "should not save non-audited columns" do
@@ -148,7 +157,7 @@ describe Audited::Auditor do
148
157
  begin
149
158
  Models::ActiveRecord::User.non_audited_columns += [:favourite_device]
150
159
 
151
- expect(create_user.audits.first.audited_changes.keys.any? { |col| ['favourite_device', 'created_at', 'updated_at', 'password'].include?( col ) }).to eq(false)
160
+ expect(create_user.audits.first.audited_changes.keys.any? { |col| ["favourite_device", "created_at", "updated_at", "password"].include?(col) }).to eq(false)
152
161
  ensure
153
162
  Models::ActiveRecord::User.non_audited_columns = previous
154
163
  end
@@ -170,7 +179,7 @@ describe Audited::Auditor do
170
179
  user.password = "password"
171
180
  user.non_column_attr = "some value"
172
181
  user.save!
173
- expect(user.audits.last.audited_changes.keys).to eq(%w{password})
182
+ expect(user.audits.last.audited_changes.keys).to eq(%w[password])
174
183
  end
175
184
 
176
185
  it "should save attributes not specified in 'except' option" do
@@ -189,10 +198,43 @@ describe Audited::Auditor do
189
198
  user.password = "password"
190
199
  user.non_column_attr = "some value"
191
200
  user.save!
192
- expect(user.audits.last.audited_changes.keys).to eq(%w{non_column_attr})
201
+ expect(user.audits.last.audited_changes.keys).to eq(%w[non_column_attr])
193
202
  end
194
203
 
195
- if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' && Rails.version >= "4.2.0.0" # Postgres json and jsonb support was added in Rails 4.2
204
+ it "should redact columns specified in 'redacted' option" do
205
+ redacted = Audited::Auditor::AuditedInstanceMethods::REDACTED
206
+ user = Models::ActiveRecord::UserRedactedPassword.create(password: "password")
207
+ user.save!
208
+ expect(user.audits.last.audited_changes["password"]).to eq(redacted)
209
+ user.password = "new_password"
210
+ user.save!
211
+ expect(user.audits.last.audited_changes["password"]).to eq([redacted, redacted])
212
+ end
213
+
214
+ it "should redact columns specified in 'redacted' option when there are multiple specified" do
215
+ redacted = Audited::Auditor::AuditedInstanceMethods::REDACTED
216
+ user =
217
+ Models::ActiveRecord::UserMultipleRedactedAttributes.create(
218
+ password: "password",
219
+ ssn: 123456789
220
+ )
221
+ user.save!
222
+ expect(user.audits.last.audited_changes["password"]).to eq(redacted)
223
+ expect(user.audits.last.audited_changes["ssn"]).to eq(redacted)
224
+ user.password = "new_password"
225
+ user.ssn = 987654321
226
+ user.save!
227
+ expect(user.audits.last.audited_changes["password"]).to eq([redacted, redacted])
228
+ expect(user.audits.last.audited_changes["ssn"]).to eq([redacted, redacted])
229
+ end
230
+
231
+ it "should redact columns in 'redacted' column with custom option" do
232
+ user = Models::ActiveRecord::UserRedactedPasswordCustomRedaction.create(password: "password")
233
+ user.save!
234
+ expect(user.audits.last.audited_changes["password"]).to eq(["My", "Custom", "Value", 7])
235
+ end
236
+
237
+ if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
196
238
  describe "'json' and 'jsonb' audited_changes column type" do
197
239
  let(:migrations_path) { SPEC_ROOT.join("support/active_record/postgres") }
198
240
 
@@ -229,16 +271,16 @@ describe Audited::Auditor do
229
271
  it "should allow mass assignment of all unprotected attributes" do
230
272
  yesterday = 1.day.ago
231
273
 
232
- u = Models::ActiveRecord::NoAttributeProtectionUser.new(name: 'name',
233
- username: 'username',
234
- password: 'password',
235
- activated: true,
236
- suspended_at: yesterday,
237
- logins: 2)
274
+ u = Models::ActiveRecord::NoAttributeProtectionUser.new(name: "name",
275
+ username: "username",
276
+ password: "password",
277
+ activated: true,
278
+ suspended_at: yesterday,
279
+ logins: 2)
238
280
 
239
- expect(u.name).to eq('name')
240
- expect(u.username).to eq('username')
241
- expect(u.password).to eq('password')
281
+ expect(u.name).to eq("name")
282
+ expect(u.username).to eq("username")
283
+ expect(u.password).to eq("password")
242
284
  expect(u.activated).to eq(true)
243
285
  expect(u.suspended_at.to_i).to eq(yesterday.to_i)
244
286
  expect(u.logins).to eq(2)
@@ -246,12 +288,12 @@ describe Audited::Auditor do
246
288
  end
247
289
 
248
290
  describe "on create" do
249
- let( :user ) { create_user audit_comment: "Create" }
291
+ let(:user) { create_user status: :reliable, audit_comment: "Create" }
250
292
 
251
293
  it "should change the audit count" do
252
294
  expect {
253
295
  user
254
- }.to change( Audited::Audit, :count ).by(1)
296
+ }.to change(Audited::Audit, :count).by(1)
255
297
  end
256
298
 
257
299
  it "should create associated audit" do
@@ -259,7 +301,7 @@ describe Audited::Auditor do
259
301
  end
260
302
 
261
303
  it "should set the action to create" do
262
- expect(user.audits.first.action).to eq('create')
304
+ expect(user.audits.first.action).to eq("create")
263
305
  expect(Audited::Audit.creates.order(:id).last).to eq(user.audits.first)
264
306
  expect(user.audits.creates.count).to eq(1)
265
307
  expect(user.audits.updates.count).to eq(0)
@@ -270,91 +312,109 @@ describe Audited::Auditor do
270
312
  expect(user.audits.first.audited_changes).to eq(user.audited_attributes)
271
313
  end
272
314
 
315
+ it "should store enum value" do
316
+ expect(user.audits.first.audited_changes["status"]).to eq(1)
317
+ end
318
+
319
+ context "when store_synthesized_enums is set to true" do
320
+ before { Audited.store_synthesized_enums = true }
321
+ after { Audited.store_synthesized_enums = false }
322
+
323
+ it "should store enum value as Rails synthesized value" do
324
+ expect(user.audits.first.audited_changes["status"]).to eq("reliable")
325
+ end
326
+ end
327
+
273
328
  it "should store comment" do
274
- expect(user.audits.first.comment).to eq('Create')
329
+ expect(user.audits.first.comment).to eq("Create")
275
330
  end
276
331
 
277
332
  it "should not audit an attribute which is excepted if specified on create or destroy" do
278
- on_create_destroy_except_name = Models::ActiveRecord::OnCreateDestroyExceptName.create(name: 'Bart')
279
- expect(on_create_destroy_except_name.audits.first.audited_changes.keys.any?{|col| ['name'].include? col}).to eq(false)
333
+ on_create_destroy_except_name = Models::ActiveRecord::OnCreateDestroyExceptName.create(name: "Bart")
334
+ expect(on_create_destroy_except_name.audits.first.audited_changes.keys.any? { |col| ["name"].include? col }).to eq(false)
280
335
  end
281
336
 
282
337
  it "should not save an audit if only specified on update/destroy" do
283
338
  expect {
284
- Models::ActiveRecord::OnUpdateDestroy.create!( name: 'Bart' )
285
- }.to_not change( Audited::Audit, :count )
339
+ Models::ActiveRecord::OnUpdateDestroy.create!(name: "Bart")
340
+ }.to_not change(Audited::Audit, :count)
286
341
  end
287
342
  end
288
343
 
289
344
  describe "on update" do
290
345
  before do
291
- @user = create_user( name: 'Brandon', audit_comment: 'Update' )
346
+ @user = create_user(name: "Brandon", status: :active, audit_comment: "Update")
292
347
  end
293
348
 
294
349
  it "should save an audit" do
295
350
  expect {
296
351
  @user.update_attribute(:name, "Someone")
297
- }.to change( Audited::Audit, :count ).by(1)
352
+ }.to change(Audited::Audit, :count).by(1)
298
353
  expect {
299
354
  @user.update_attribute(:name, "Someone else")
300
- }.to change( Audited::Audit, :count ).by(1)
355
+ }.to change(Audited::Audit, :count).by(1)
301
356
  end
302
357
 
303
358
  it "should set the action to 'update'" do
304
- @user.update_attributes name: 'Changed'
305
- expect(@user.audits.last.action).to eq('update')
359
+ @user.update! name: "Changed"
360
+ expect(@user.audits.last.action).to eq("update")
306
361
  expect(Audited::Audit.updates.order(:id).last).to eq(@user.audits.last)
307
362
  expect(@user.audits.updates.last).to eq(@user.audits.last)
308
363
  end
309
364
 
310
365
  it "should store the changed attributes" do
311
- @user.update_attributes name: 'Changed'
312
- expect(@user.audits.last.audited_changes).to eq({ 'name' => ['Brandon', 'Changed'] })
366
+ @user.update! name: "Changed"
367
+ expect(@user.audits.last.audited_changes).to eq({"name" => ["Brandon", "Changed"]})
368
+ end
369
+
370
+ it "should store changed enum values" do
371
+ @user.update! status: 1
372
+ expect(@user.audits.last.audited_changes["status"]).to eq([0, 1])
313
373
  end
314
374
 
315
375
  it "should store audit comment" do
316
- expect(@user.audits.last.comment).to eq('Update')
376
+ expect(@user.audits.last.comment).to eq("Update")
317
377
  end
318
378
 
319
379
  it "should not save an audit if only specified on create/destroy" do
320
- on_create_destroy = Models::ActiveRecord::OnCreateDestroy.create( name: 'Bart' )
380
+ on_create_destroy = Models::ActiveRecord::OnCreateDestroy.create(name: "Bart")
321
381
  expect {
322
- on_create_destroy.update_attributes name: 'Changed'
323
- }.to_not change( Audited::Audit, :count )
382
+ on_create_destroy.update! name: "Changed"
383
+ }.to_not change(Audited::Audit, :count)
324
384
  end
325
385
 
326
386
  it "should not save an audit if the value doesn't change after type casting" do
327
- @user.update_attributes! logins: 0, activated: true
328
- expect { @user.update_attribute :logins, '0' }.to_not change( Audited::Audit, :count )
329
- expect { @user.update_attribute :activated, 1 }.to_not change( Audited::Audit, :count )
330
- expect { @user.update_attribute :activated, '1' }.to_not change( Audited::Audit, :count )
387
+ @user.update! logins: 0, activated: true
388
+ expect { @user.update_attribute :logins, "0" }.to_not change(Audited::Audit, :count)
389
+ expect { @user.update_attribute :activated, 1 }.to_not change(Audited::Audit, :count)
390
+ expect { @user.update_attribute :activated, "1" }.to_not change(Audited::Audit, :count)
331
391
  end
332
392
 
333
393
  describe "with no dirty changes" do
334
394
  it "does not create an audit if the record is not changed" do
335
395
  expect {
336
396
  @user.save!
337
- }.to_not change( Audited::Audit, :count )
397
+ }.to_not change(Audited::Audit, :count)
338
398
  end
339
399
 
340
400
  it "creates an audit when an audit comment is present" do
341
401
  expect {
342
402
  @user.audit_comment = "Comment"
343
403
  @user.save!
344
- }.to change( Audited::Audit, :count )
404
+ }.to change(Audited::Audit, :count)
345
405
  end
346
406
  end
347
407
  end
348
408
 
349
409
  describe "on destroy" do
350
410
  before do
351
- @user = create_user
411
+ @user = create_user(status: :active)
352
412
  end
353
413
 
354
414
  it "should save an audit" do
355
415
  expect {
356
416
  @user.destroy
357
- }.to change( Audited::Audit, :count )
417
+ }.to change(Audited::Audit, :count)
358
418
 
359
419
  expect(@user.audits.size).to eq(2)
360
420
  end
@@ -362,7 +422,7 @@ describe Audited::Auditor do
362
422
  it "should set the action to 'destroy'" do
363
423
  @user.destroy
364
424
 
365
- expect(@user.audits.last.action).to eq('destroy')
425
+ expect(@user.audits.last.action).to eq("destroy")
366
426
  expect(Audited::Audit.destroys.order(:id).last).to eq(@user.audits.last)
367
427
  expect(@user.audits.destroys.last).to eq(@user.audits.last)
368
428
  end
@@ -373,6 +433,11 @@ describe Audited::Auditor do
373
433
  expect(@user.audits.last.audited_changes).to eq(@user.audited_attributes)
374
434
  end
375
435
 
436
+ it "should store enum value" do
437
+ @user.destroy
438
+ expect(@user.audits.last.audited_changes["status"]).to eq(0)
439
+ end
440
+
376
441
  it "should be able to reconstruct a destroyed record without history" do
377
442
  @user.audits.delete_all
378
443
  @user.destroy
@@ -382,11 +447,11 @@ describe Audited::Auditor do
382
447
  end
383
448
 
384
449
  it "should not save an audit if only specified on create/update" do
385
- on_create_update = Models::ActiveRecord::OnCreateUpdate.create!( name: 'Bart' )
450
+ on_create_update = Models::ActiveRecord::OnCreateUpdate.create!(name: "Bart")
386
451
 
387
452
  expect {
388
453
  on_create_update.destroy
389
- }.to_not change( Audited::Audit, :count )
454
+ }.to_not change(Audited::Audit, :count)
390
455
  end
391
456
 
392
457
  it "should audit dependent destructions" do
@@ -395,9 +460,9 @@ describe Audited::Auditor do
395
460
 
396
461
  expect {
397
462
  owner.destroy
398
- }.to change( Audited::Audit, :count )
463
+ }.to change(Audited::Audit, :count)
399
464
 
400
- expect(company.audits.map { |a| a.action }).to eq(['create', 'destroy'])
465
+ expect(company.audits.map { |a| a.action }).to eq(["create", "destroy"])
401
466
  end
402
467
  end
403
468
 
@@ -409,20 +474,20 @@ describe Audited::Auditor do
409
474
  user.destroy
410
475
  }.to_not raise_error
411
476
 
412
- expect( user.audits ).to be_empty
477
+ expect(user.audits).to be_empty
413
478
  end
414
479
  end
415
480
 
416
481
  describe "associated with" do
417
- let(:owner) { Models::ActiveRecord::Owner.create(name: 'Models::ActiveRecord::Owner') }
418
- let(:owned_company) { Models::ActiveRecord::OwnedCompany.create!(name: 'The auditors', owner: owner) }
482
+ let(:owner) { Models::ActiveRecord::Owner.create(name: "Models::ActiveRecord::Owner") }
483
+ let(:owned_company) { Models::ActiveRecord::OwnedCompany.create!(name: "The auditors", owner: owner) }
419
484
 
420
485
  it "should record the associated object on create" do
421
486
  expect(owned_company.audits.first.associated).to eq(owner)
422
487
  end
423
488
 
424
489
  it "should store the associated object on update" do
425
- owned_company.update_attribute(:name, 'The Auditors')
490
+ owned_company.update_attribute(:name, "The Auditors")
426
491
  expect(owned_company.audits.last.associated).to eq(owner)
427
492
  end
428
493
 
@@ -433,8 +498,8 @@ describe Audited::Auditor do
433
498
  end
434
499
 
435
500
  describe "has associated audits" do
436
- let!(:owner) { Models::ActiveRecord::Owner.create!(name: 'Models::ActiveRecord::Owner') }
437
- let!(:owned_company) { Models::ActiveRecord::OwnedCompany.create!(name: 'The auditors', owner: owner) }
501
+ let!(:owner) { Models::ActiveRecord::Owner.create!(name: "Models::ActiveRecord::Owner") }
502
+ let!(:owned_company) { Models::ActiveRecord::OwnedCompany.create!(name: "The auditors", owner: owner) }
438
503
 
439
504
  it "should list the associated audits" do
440
505
  expect(owner.associated_audits.length).to eq(1)
@@ -458,7 +523,7 @@ describe Audited::Auditor do
458
523
  it "should delete old audits when keeped amount exceeded" do
459
524
  stub_global_max_audits(2) do
460
525
  user = create_versions(2)
461
- user.update(name: 'John')
526
+ user.update(name: "John")
462
527
  expect(user.audits.pluck(:version)).to eq([2, 3])
463
528
  end
464
529
  end
@@ -466,35 +531,35 @@ describe Audited::Auditor do
466
531
  it "should not delete old audits when keeped amount not exceeded" do
467
532
  stub_global_max_audits(3) do
468
533
  user = create_versions(2)
469
- user.update(name: 'John')
534
+ user.update(name: "John")
470
535
  expect(user.audits.pluck(:version)).to eq([1, 2, 3])
471
536
  end
472
537
  end
473
538
 
474
539
  it "should delete old extra audits after introducing limit" do
475
540
  stub_global_max_audits(nil) do
476
- user = Models::ActiveRecord::User.create!(name: 'Brandon', username: 'brandon')
477
- user.update_attributes(name: 'Foobar')
478
- user.update_attributes(name: 'Awesome', username: 'keepers')
479
- user.update_attributes(activated: true)
541
+ user = Models::ActiveRecord::User.create!(name: "Brandon", username: "brandon")
542
+ user.update!(name: "Foobar")
543
+ user.update!(name: "Awesome", username: "keepers")
544
+ user.update!(activated: true)
480
545
 
481
546
  Audited.max_audits = 3
482
547
  Models::ActiveRecord::User.send(:normalize_audited_options)
483
- user.update_attributes(favourite_device: 'Android Phone')
548
+ user.update!(favourite_device: "Android Phone")
484
549
  audits = user.audits
485
550
 
486
551
  expect(audits.count).to eq(3)
487
- expect(audits[0].audited_changes).to include({'name' => ['Foobar', 'Awesome'], 'username' => ['brandon', 'keepers']})
488
- expect(audits[1].audited_changes).to eq({'activated' => [nil, true]})
489
- expect(audits[2].audited_changes).to eq({'favourite_device' => [nil, 'Android Phone']})
552
+ expect(audits[0].audited_changes).to include({"name" => ["Foobar", "Awesome"], "username" => ["brandon", "keepers"]})
553
+ expect(audits[1].audited_changes).to eq({"activated" => [nil, true]})
554
+ expect(audits[2].audited_changes).to eq({"favourite_device" => [nil, "Android Phone"]})
490
555
  end
491
556
  end
492
557
 
493
558
  it "should add comment line for combined audit" do
494
559
  stub_global_max_audits(2) do
495
- user = Models::ActiveRecord::User.create!(name: 'Foobar 1')
496
- user.update(name: 'Foobar 2', audit_comment: 'First audit comment')
497
- user.update(name: 'Foobar 3', audit_comment: 'Second audit comment')
560
+ user = Models::ActiveRecord::User.create!(name: "Foobar 1")
561
+ user.update(name: "Foobar 2", audit_comment: "First audit comment")
562
+ user.update(name: "Foobar 3", audit_comment: "Second audit comment")
498
563
  expect(user.audits.first.comment).to match(/First audit comment.+is the result of multiple/m)
499
564
  end
500
565
  end
@@ -514,10 +579,10 @@ describe Audited::Auditor do
514
579
  end
515
580
 
516
581
  describe "revisions" do
517
- let( :user ) { create_versions }
582
+ let(:user) { create_versions }
518
583
 
519
584
  it "should return an Array of Users" do
520
- expect(user.revisions).to be_a_kind_of( Array )
585
+ expect(user.revisions).to be_a_kind_of(Array)
521
586
  user.revisions.each { |version| expect(version).to be_a_kind_of Models::ActiveRecord::User }
522
587
  end
523
588
 
@@ -526,38 +591,38 @@ describe Audited::Auditor do
526
591
  end
527
592
 
528
593
  it "should have one revision for each audit" do
529
- expect(user.audits.size).to eql( user.revisions.size )
594
+ expect(user.audits.size).to eql(user.revisions.size)
530
595
  end
531
596
 
532
597
  it "should set the attributes for each revision" do
533
- u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
534
- u.update_attributes name: 'Foobar'
535
- u.update_attributes name: 'Awesome', username: 'keepers'
598
+ u = Models::ActiveRecord::User.create(name: "Brandon", username: "brandon")
599
+ u.update! name: "Foobar"
600
+ u.update! name: "Awesome", username: "keepers"
536
601
 
537
602
  expect(u.revisions.size).to eql(3)
538
603
 
539
- expect(u.revisions[0].name).to eql('Brandon')
540
- expect(u.revisions[0].username).to eql('brandon')
604
+ expect(u.revisions[0].name).to eql("Brandon")
605
+ expect(u.revisions[0].username).to eql("brandon")
541
606
 
542
- expect(u.revisions[1].name).to eql('Foobar')
543
- expect(u.revisions[1].username).to eql('brandon')
607
+ expect(u.revisions[1].name).to eql("Foobar")
608
+ expect(u.revisions[1].username).to eql("brandon")
544
609
 
545
- expect(u.revisions[2].name).to eql('Awesome')
546
- expect(u.revisions[2].username).to eql('keepers')
610
+ expect(u.revisions[2].name).to eql("Awesome")
611
+ expect(u.revisions[2].username).to eql("keepers")
547
612
  end
548
613
 
549
614
  it "access to only recent revisions" do
550
- u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
551
- u.update_attributes name: 'Foobar'
552
- u.update_attributes name: 'Awesome', username: 'keepers'
615
+ u = Models::ActiveRecord::User.create(name: "Brandon", username: "brandon")
616
+ u.update! name: "Foobar"
617
+ u.update! name: "Awesome", username: "keepers"
553
618
 
554
619
  expect(u.revisions(2).size).to eq(2)
555
620
 
556
- expect(u.revisions(2)[0].name).to eq('Foobar')
557
- expect(u.revisions(2)[0].username).to eq('brandon')
621
+ expect(u.revisions(2)[0].name).to eq("Foobar")
622
+ expect(u.revisions(2)[0].username).to eq("brandon")
558
623
 
559
- expect(u.revisions(2)[1].name).to eq('Awesome')
560
- expect(u.revisions(2)[1].username).to eq('keepers')
624
+ expect(u.revisions(2)[1].name).to eq("Awesome")
625
+ expect(u.revisions(2)[1].username).to eq("keepers")
561
626
  end
562
627
 
563
628
  it "should be empty if no audits exist" do
@@ -566,13 +631,13 @@ describe Audited::Auditor do
566
631
  end
567
632
 
568
633
  it "should ignore attributes that have been deleted" do
569
- user.audits.last.update_attributes audited_changes: {old_attribute: 'old value'}
634
+ user.audits.last.update! audited_changes: {old_attribute: "old value"}
570
635
  expect { user.revisions }.to_not raise_error
571
636
  end
572
637
  end
573
638
 
574
639
  describe "revisions" do
575
- let( :user ) { create_versions(5) }
640
+ let(:user) { create_versions(5) }
576
641
 
577
642
  it "should maintain identity" do
578
643
  expect(user.revision(1)).to eq(user)
@@ -580,26 +645,26 @@ describe Audited::Auditor do
580
645
 
581
646
  it "should find the given revision" do
582
647
  revision = user.revision(3)
583
- expect(revision).to be_a_kind_of( Models::ActiveRecord::User )
584
- expect(revision.version).to eq(3)
585
- expect(revision.name).to eq('Foobar 3')
648
+ expect(revision).to be_a_kind_of(Models::ActiveRecord::User)
649
+ expect(revision.audit_version).to eq(3)
650
+ expect(revision.name).to eq("Foobar 3")
586
651
  end
587
652
 
588
653
  it "should find the previous revision with :previous" do
589
654
  revision = user.revision(:previous)
590
- expect(revision.version).to eq(4)
591
- #expect(revision).to eq(user.revision(4))
655
+ expect(revision.audit_version).to eq(4)
656
+ # expect(revision).to eq(user.revision(4))
592
657
  expect(revision.attributes).to eq(user.revision(4).attributes)
593
658
  end
594
659
 
595
660
  it "should be able to get the previous revision repeatedly" do
596
661
  previous = user.revision(:previous)
597
- expect(previous.version).to eq(4)
598
- expect(previous.revision(:previous).version).to eq(3)
662
+ expect(previous.audit_version).to eq(4)
663
+ expect(previous.revision(:previous).audit_version).to eq(3)
599
664
  end
600
665
 
601
666
  it "should be able to set protected attributes" do
602
- u = Models::ActiveRecord::User.create(name: 'Brandon')
667
+ u = Models::ActiveRecord::User.create(name: "Brandon")
603
668
  u.update_attribute :logins, 1
604
669
  u.update_attribute :logins, 2
605
670
 
@@ -609,23 +674,33 @@ describe Audited::Auditor do
609
674
  end
610
675
 
611
676
  it "should set attributes directly" do
612
- u = Models::ActiveRecord::User.create(name: '<Joe>')
613
- expect(u.revision(1).name).to eq('&lt;Joe&gt;')
677
+ u = Models::ActiveRecord::User.create(name: "<Joe>")
678
+ expect(u.revision(1).name).to eq("&lt;Joe&gt;")
614
679
  end
615
680
 
616
681
  it "should set the attributes for each revision" do
617
- u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
618
- u.update_attributes name: 'Foobar'
619
- u.update_attributes name: 'Awesome', username: 'keepers'
682
+ u = Models::ActiveRecord::User.create(name: "Brandon", username: "brandon")
683
+ u.update! name: "Foobar"
684
+ u.update! name: "Awesome", username: "keepers"
620
685
 
621
- expect(u.revision(3).name).to eq('Awesome')
622
- expect(u.revision(3).username).to eq('keepers')
686
+ expect(u.revision(3).name).to eq("Awesome")
687
+ expect(u.revision(3).username).to eq("keepers")
623
688
 
624
- expect(u.revision(2).name).to eq('Foobar')
625
- expect(u.revision(2).username).to eq('brandon')
689
+ expect(u.revision(2).name).to eq("Foobar")
690
+ expect(u.revision(2).username).to eq("brandon")
626
691
 
627
- expect(u.revision(1).name).to eq('Brandon')
628
- expect(u.revision(1).username).to eq('brandon')
692
+ expect(u.revision(1).name).to eq("Brandon")
693
+ expect(u.revision(1).username).to eq("brandon")
694
+ end
695
+
696
+ it "should correctly restore revision with enum" do
697
+ u = Models::ActiveRecord::User.create(status: :active)
698
+ u.update_attribute(:status, :reliable)
699
+ u.update_attribute(:status, :banned)
700
+
701
+ expect(u.revision(3)).to be_banned
702
+ expect(u.revision(2)).to be_reliable
703
+ expect(u.revision(1)).to be_active
629
704
  end
630
705
 
631
706
  it "should be able to get time for first revision" do
@@ -646,141 +721,276 @@ describe Audited::Auditor do
646
721
  it "should record new audit when saving revision" do
647
722
  expect {
648
723
  user.revision(1).save!
649
- }.to change( user.audits, :count ).by(1)
724
+ }.to change(user.audits, :count).by(1)
650
725
  end
651
726
 
652
727
  it "should re-insert destroyed records" do
653
728
  user.destroy
654
729
  expect {
655
730
  user.revision(1).save!
656
- }.to change( Models::ActiveRecord::User, :count ).by(1)
731
+ }.to change(Models::ActiveRecord::User, :count).by(1)
657
732
  end
658
733
 
659
734
  it "should return nil for values greater than the number of revisions" do
660
735
  expect(user.revision(user.revisions.count + 1)).to be_nil
661
736
  end
737
+
738
+ it "should work with array attributes" do
739
+ u = Models::ActiveRecord::User.create!(phone_numbers: ["+1 800-444-4444"])
740
+ u.update!(phone_numbers: ["+1 804-222-1111", "+1 317 222-2222"])
741
+
742
+ expect(u.revision(0).phone_numbers).to eq(["+1 804-222-1111", "+1 317 222-2222"])
743
+ expect(u.revision(1).phone_numbers).to eq(["+1 800-444-4444"])
744
+ end
662
745
  end
663
746
 
664
747
  describe "revision_at" do
665
- let( :user ) { create_user }
748
+ let(:user) { create_user }
666
749
 
667
750
  it "should find the latest revision before the given time" do
668
751
  audit = user.audits.first
669
752
  audit.created_at = 1.hour.ago
670
753
  audit.save!
671
- user.update_attributes name: 'updated'
672
- expect(user.revision_at( 2.minutes.ago ).version).to eq(1)
754
+ user.update! name: "updated"
755
+ expect(user.revision_at(2.minutes.ago).audit_version).to eq(1)
673
756
  end
674
757
 
675
758
  it "should be nil if given a time before audits" do
676
- expect(user.revision_at( 1.week.ago )).to be_nil
759
+ expect(user.revision_at(1.week.ago)).to be_nil
760
+ end
761
+ end
762
+
763
+ describe "own_and_associated_audits" do
764
+ it "should return audits for self and associated audits" do
765
+ owner = Models::ActiveRecord::Owner.create!
766
+ company = owner.companies.create!
767
+ company.update!(name: "Collective Idea")
768
+
769
+ other_owner = Models::ActiveRecord::Owner.create!
770
+ other_owner.companies.create!
771
+
772
+ expect(owner.own_and_associated_audits).to match_array(owner.audits + company.audits)
773
+ end
774
+
775
+ it "should return audits for STI classes" do
776
+ # Where parent is STI
777
+ sti_company = Models::ActiveRecord::Company::STICompany.create!
778
+ sti_company.update!(name: "Collective Idea")
779
+ expect(sti_company.own_and_associated_audits).to match_array(sti_company.audits)
780
+
781
+ # Where associated is STI
782
+ owner = Models::ActiveRecord::Owner.create!
783
+ company = owner.companies.create! type: "Models::ActiveRecord::OwnedCompany::STICompany"
784
+ company.update!(name: "Collective Idea")
785
+ expect(owner.own_and_associated_audits).to match_array(owner.audits + company.audits)
786
+ end
787
+
788
+ it "should order audits by creation time" do
789
+ owner = Models::ActiveRecord::Owner.create!
790
+ first_audit = owner.audits.first
791
+ first_audit.update_column(:created_at, 1.year.ago)
792
+
793
+ company = owner.companies.create!
794
+ second_audit = company.audits.first
795
+ second_audit.update_column(:created_at, 1.month.ago)
796
+
797
+ company.update!(name: "Collective Idea")
798
+ third_audit = company.audits.last
799
+ expect(owner.own_and_associated_audits.to_a).to eq([third_audit, second_audit, first_audit])
677
800
  end
678
801
  end
679
802
 
680
803
  describe "without auditing" do
681
804
  it "should not save an audit when calling #save_without_auditing" do
682
805
  expect {
683
- u = Models::ActiveRecord::User.new(name: 'Brandon')
806
+ u = Models::ActiveRecord::User.new(name: "Brandon")
684
807
  expect(u.save_without_auditing).to eq(true)
685
- }.to_not change( Audited::Audit, :count )
808
+ }.to_not change(Audited::Audit, :count)
686
809
  end
687
810
 
688
811
  it "should not save an audit inside of the #without_auditing block" do
689
812
  expect {
690
- Models::ActiveRecord::User.without_auditing { Models::ActiveRecord::User.create!( name: 'Brandon' ) }
691
- }.to_not change( Audited::Audit, :count )
813
+ Models::ActiveRecord::User.without_auditing { Models::ActiveRecord::User.create!(name: "Brandon") }
814
+ }.to_not change(Audited::Audit, :count)
692
815
  end
693
816
 
694
817
  it "should reset auditing status even it raises an exception" do
695
- Models::ActiveRecord::User.without_auditing { raise } rescue nil
818
+ begin
819
+ Models::ActiveRecord::User.without_auditing { raise }
820
+ rescue
821
+ nil
822
+ end
696
823
  expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
697
824
  end
698
825
 
699
826
  it "should be thread safe using a #without_auditing block" do
827
+ skip if Models::ActiveRecord::User.connection.class.name.include?("SQLite")
828
+
829
+ t1 = Thread.new do
830
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
831
+ Models::ActiveRecord::User.without_auditing do
832
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
833
+ Models::ActiveRecord::User.create!(name: "Bart")
834
+ sleep 1
835
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
836
+ end
837
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
838
+ end
839
+
840
+ t2 = Thread.new do
841
+ sleep 0.5
842
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
843
+ Models::ActiveRecord::User.create!(name: "Lisa")
844
+ end
845
+ t1.join
846
+ t2.join
847
+
848
+ expect(Models::ActiveRecord::User.find_by_name("Bart").audits.count).to eq(0)
849
+ expect(Models::ActiveRecord::User.find_by_name("Lisa").audits.count).to eq(1)
850
+ end
851
+
852
+ it "should not save an audit when auditing is globally disabled" do
853
+ expect(Audited.auditing_enabled).to eq(true)
854
+ Audited.auditing_enabled = false
855
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
856
+
857
+ user = create_user
858
+ expect(user.audits.count).to eq(0)
859
+
860
+ Audited.auditing_enabled = true
861
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
862
+
863
+ user.update!(name: "Test")
864
+ expect(user.audits.count).to eq(1)
865
+ Models::ActiveRecord::User.enable_auditing
866
+ end
867
+ end
868
+
869
+ describe "with auditing" do
870
+ it "should save an audit when calling #save_with_auditing" do
871
+ expect {
872
+ u = Models::ActiveRecord::User.new(name: "Brandon")
873
+ Models::ActiveRecord::User.auditing_enabled = false
874
+ expect(u.save_with_auditing).to eq(true)
875
+ Models::ActiveRecord::User.auditing_enabled = true
876
+ }.to change(Audited::Audit, :count).by(1)
877
+ end
878
+
879
+ it "should save an audit inside of the #with_auditing block" do
880
+ expect {
881
+ Models::ActiveRecord::User.auditing_enabled = false
882
+ Models::ActiveRecord::User.with_auditing { Models::ActiveRecord::User.create!(name: "Brandon") }
883
+ Models::ActiveRecord::User.auditing_enabled = true
884
+ }.to change(Audited::Audit, :count).by(1)
885
+ end
886
+
887
+ it "should reset auditing status even it raises an exception" do
888
+ Models::ActiveRecord::User.disable_auditing
700
889
  begin
701
- t1 = Thread.new do
702
- expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
703
- Models::ActiveRecord::User.without_auditing do
704
- expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
705
- Models::ActiveRecord::User.create!( name: 'Bart' )
706
- sleep 1
707
- expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
708
- end
890
+ Models::ActiveRecord::User.with_auditing { raise }
891
+ rescue
892
+ nil
893
+ end
894
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
895
+ Models::ActiveRecord::User.enable_auditing
896
+ end
897
+
898
+ it "should be thread safe using a #with_auditing block" do
899
+ skip if Models::ActiveRecord::User.connection.class.name.include?("SQLite")
900
+
901
+ t1 = Thread.new do
902
+ Models::ActiveRecord::User.disable_auditing
903
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
904
+ Models::ActiveRecord::User.with_auditing do
709
905
  expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
710
- end
711
906
 
712
- t2 = Thread.new do
713
- sleep 0.5
907
+ Models::ActiveRecord::User.create!(name: "Shaggy")
908
+ sleep 1
714
909
  expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
715
- Models::ActiveRecord::User.create!( name: 'Lisa' )
716
910
  end
717
- t1.join
718
- t2.join
911
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
912
+ Models::ActiveRecord::User.enable_auditing
913
+ end
719
914
 
720
- expect(Models::ActiveRecord::User.find_by_name('Bart').audits.count).to eq(0)
721
- expect(Models::ActiveRecord::User.find_by_name('Lisa').audits.count).to eq(1)
722
- rescue ActiveRecord::StatementInvalid
723
- STDERR.puts "Thread safety tests cannot be run with SQLite"
915
+ t2 = Thread.new do
916
+ sleep 0.5
917
+ Models::ActiveRecord::User.disable_auditing
918
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
919
+ Models::ActiveRecord::User.create!(name: "Scooby")
920
+ Models::ActiveRecord::User.enable_auditing
724
921
  end
922
+ t1.join
923
+ t2.join
924
+
925
+ Models::ActiveRecord::User.enable_auditing
926
+ expect(Models::ActiveRecord::User.find_by_name("Shaggy").audits.count).to eq(1)
927
+ expect(Models::ActiveRecord::User.find_by_name("Scooby").audits.count).to eq(0)
725
928
  end
726
929
  end
727
930
 
728
931
  describe "comment required" do
729
-
730
932
  describe "on create" do
731
933
  it "should not validate when audit_comment is not supplied when initialized" do
732
- expect(Models::ActiveRecord::CommentRequiredUser.new(name: 'Foo')).not_to be_valid
934
+ expect(Models::ActiveRecord::CommentRequiredUser.new(name: "Foo")).not_to be_valid
733
935
  end
734
936
 
735
937
  it "should not validate when audit_comment is not supplied trying to create" do
736
- expect(Models::ActiveRecord::CommentRequiredUser.create(name: 'Foo')).not_to be_valid
938
+ expect(Models::ActiveRecord::CommentRequiredUser.create(name: "Foo")).not_to be_valid
737
939
  end
738
940
 
739
941
  it "should validate when audit_comment is supplied" do
740
- expect(Models::ActiveRecord::CommentRequiredUser.create(name: 'Foo', audit_comment: 'Create')).to be_valid
942
+ expect(Models::ActiveRecord::CommentRequiredUser.create(name: "Foo", audit_comment: "Create")).to be_valid
741
943
  end
742
944
 
743
945
  it "should validate when audit_comment is not supplied, and creating is not being audited" do
744
- expect(Models::ActiveRecord::OnUpdateCommentRequiredUser.create(name: 'Foo')).to be_valid
745
- expect(Models::ActiveRecord::OnDestroyCommentRequiredUser.create(name: 'Foo')).to be_valid
946
+ expect(Models::ActiveRecord::OnUpdateCommentRequiredUser.create(name: "Foo")).to be_valid
947
+ expect(Models::ActiveRecord::OnDestroyCommentRequiredUser.create(name: "Foo")).to be_valid
746
948
  end
747
949
 
748
950
  it "should validate when audit_comment is not supplied, and auditing is disabled" do
749
951
  Models::ActiveRecord::CommentRequiredUser.disable_auditing
750
- expect(Models::ActiveRecord::CommentRequiredUser.create(name: 'Foo')).to be_valid
952
+ expect(Models::ActiveRecord::CommentRequiredUser.create(name: "Foo")).to be_valid
751
953
  Models::ActiveRecord::CommentRequiredUser.enable_auditing
752
954
  end
955
+
956
+ it "should validate when audit_comment is not supplied, and only excluded attributes changed" do
957
+ expect(Models::ActiveRecord::CommentRequiredUser.new(password: "Foo")).to be_valid
958
+ end
753
959
  end
754
960
 
755
961
  describe "on update" do
756
- let( :user ) { Models::ActiveRecord::CommentRequiredUser.create!( audit_comment: 'Create' ) }
757
- let( :on_create_user ) { Models::ActiveRecord::OnDestroyCommentRequiredUser.create }
758
- let( :on_destroy_user ) { Models::ActiveRecord::OnDestroyCommentRequiredUser.create }
962
+ let(:user) { Models::ActiveRecord::CommentRequiredUser.create!(audit_comment: "Create") }
963
+ let(:on_create_user) { Models::ActiveRecord::OnDestroyCommentRequiredUser.create }
964
+ let(:on_destroy_user) { Models::ActiveRecord::OnDestroyCommentRequiredUser.create }
759
965
 
760
966
  it "should not validate when audit_comment is not supplied" do
761
- expect(user.update_attributes(name: 'Test')).to eq(false)
967
+ expect(user.update(name: "Test")).to eq(false)
762
968
  end
763
969
 
764
970
  it "should validate when audit_comment is not supplied, and updating is not being audited" do
765
- expect(on_create_user.update_attributes(name: 'Test')).to eq(true)
766
- expect(on_destroy_user.update_attributes(name: 'Test')).to eq(true)
971
+ expect(on_create_user.update(name: "Test")).to eq(true)
972
+ expect(on_destroy_user.update(name: "Test")).to eq(true)
767
973
  end
768
974
 
769
975
  it "should validate when audit_comment is supplied" do
770
- expect(user.update_attributes(name: 'Test', audit_comment: 'Update')).to eq(true)
976
+ expect(user.update(name: "Test", audit_comment: "Update")).to eq(true)
771
977
  end
772
978
 
773
979
  it "should validate when audit_comment is not supplied, and auditing is disabled" do
774
980
  Models::ActiveRecord::CommentRequiredUser.disable_auditing
775
- expect(user.update_attributes(name: 'Test')).to eq(true)
981
+ expect(user.update(name: "Test")).to eq(true)
776
982
  Models::ActiveRecord::CommentRequiredUser.enable_auditing
777
983
  end
984
+
985
+ it "should validate when audit_comment is not supplied, and only excluded attributes changed" do
986
+ expect(user.update(password: "Test")).to eq(true)
987
+ end
778
988
  end
779
989
 
780
990
  describe "on destroy" do
781
- let( :user ) { Models::ActiveRecord::CommentRequiredUser.create!( audit_comment: 'Create' )}
782
- let( :on_create_user ) { Models::ActiveRecord::OnCreateCommentRequiredUser.create!( audit_comment: 'Create' ) }
783
- let( :on_update_user ) { Models::ActiveRecord::OnUpdateCommentRequiredUser.create }
991
+ let(:user) { Models::ActiveRecord::CommentRequiredUser.create!(audit_comment: "Create") }
992
+ let(:on_create_user) { Models::ActiveRecord::OnCreateCommentRequiredUser.create!(audit_comment: "Create") }
993
+ let(:on_update_user) { Models::ActiveRecord::OnUpdateCommentRequiredUser.create }
784
994
 
785
995
  it "should not validate when audit_comment is not supplied" do
786
996
  expect(user.destroy).to eq(false)
@@ -802,31 +1012,38 @@ describe Audited::Auditor do
802
1012
  Models::ActiveRecord::CommentRequiredUser.enable_auditing
803
1013
  end
804
1014
  end
1015
+ end
1016
+
1017
+ describe "no update with comment only" do
1018
+ let(:user) { Models::ActiveRecord::NoUpdateWithCommentOnlyUser.create }
805
1019
 
1020
+ it "does not create an audit when only an audit_comment is present" do
1021
+ user.audit_comment = "Comment"
1022
+ expect { user.save! }.to_not change(Audited::Audit, :count)
1023
+ end
806
1024
  end
807
1025
 
808
1026
  describe "attr_protected and attr_accessible" do
809
-
810
1027
  it "should not raise error when attr_accessible is set and protected is false" do
811
1028
  expect {
812
- Models::ActiveRecord::AccessibleAfterDeclarationUser.new(name: 'No fail!')
1029
+ Models::ActiveRecord::AccessibleAfterDeclarationUser.new(name: "No fail!")
813
1030
  }.to_not raise_error
814
1031
  end
815
1032
 
816
1033
  it "should not rause an error when attr_accessible is declared before audited" do
817
1034
  expect {
818
- Models::ActiveRecord::AccessibleAfterDeclarationUser.new(name: 'No fail!')
1035
+ Models::ActiveRecord::AccessibleAfterDeclarationUser.new(name: "No fail!")
819
1036
  }.to_not raise_error
820
1037
  end
821
1038
  end
822
1039
 
823
1040
  describe "audit_as" do
824
- let( :user ) { Models::ActiveRecord::User.create name: 'Testing' }
1041
+ let(:user) { Models::ActiveRecord::User.create name: "Testing" }
825
1042
 
826
1043
  it "should record user objects" do
827
- Models::ActiveRecord::Company.audit_as( user ) do
828
- company = Models::ActiveRecord::Company.create name: 'The auditors'
829
- company.update_attributes name: 'The Auditors'
1044
+ Models::ActiveRecord::Company.audit_as(user) do
1045
+ company = Models::ActiveRecord::Company.create name: "The auditors"
1046
+ company.update! name: "The Auditors"
830
1047
 
831
1048
  company.audits.each do |audit|
832
1049
  expect(audit.user).to eq(user)
@@ -835,9 +1052,9 @@ describe Audited::Auditor do
835
1052
  end
836
1053
 
837
1054
  it "should record usernames" do
838
- Models::ActiveRecord::Company.audit_as( user.name ) do
839
- company = Models::ActiveRecord::Company.create name: 'The auditors'
840
- company.update_attributes name: 'The Auditors'
1055
+ Models::ActiveRecord::Company.audit_as(user.name) do
1056
+ company = Models::ActiveRecord::Company.create name: "The auditors"
1057
+ company.update! name: "The Auditors"
841
1058
 
842
1059
  company.audits.each do |audit|
843
1060
  expect(audit.user).to eq(user.name)
@@ -847,7 +1064,7 @@ describe Audited::Auditor do
847
1064
  end
848
1065
 
849
1066
  describe "after_audit" do
850
- let( :user ) { user = Models::ActiveRecord::UserWithAfterAudit.new }
1067
+ let(:user) { Models::ActiveRecord::UserWithAfterAudit.new }
851
1068
 
852
1069
  it "should invoke after_audit callback on create" do
853
1070
  expect(user.bogus_attr).to be_nil
@@ -857,7 +1074,7 @@ describe Audited::Auditor do
857
1074
  end
858
1075
 
859
1076
  describe "around_audit" do
860
- let( :user ) { user = Models::ActiveRecord::UserWithAfterAudit.new }
1077
+ let(:user) { Models::ActiveRecord::UserWithAfterAudit.new }
861
1078
 
862
1079
  it "should invoke around_audit callback on create" do
863
1080
  expect(user.around_attr).to be_nil
@@ -868,13 +1085,13 @@ describe Audited::Auditor do
868
1085
 
869
1086
  describe "STI auditing" do
870
1087
  it "should correctly disable auditing when using STI" do
871
- company = Models::ActiveRecord::Company::STICompany.create name: 'The auditors'
1088
+ company = Models::ActiveRecord::Company::STICompany.create name: "The auditors"
872
1089
  expect(company.type).to eq("Models::ActiveRecord::Company::STICompany")
873
1090
  expect {
874
1091
  Models::ActiveRecord::Company.auditing_enabled = false
875
- company.update_attributes name: 'STI auditors'
1092
+ company.update! name: "STI auditors"
876
1093
  Models::ActiveRecord::Company.auditing_enabled = true
877
- }.to_not change( Audited::Audit, :count )
1094
+ }.to_not change(Audited::Audit, :count)
878
1095
  end
879
1096
  end
880
1097
  end