audited 4.6.0 → 4.10.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 (39) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/.rubocop.yml +25 -0
  4. data/.travis.yml +35 -21
  5. data/Appraisals +29 -12
  6. data/CHANGELOG.md +108 -0
  7. data/README.md +125 -39
  8. data/gemfiles/rails42.gemfile +3 -0
  9. data/gemfiles/rails50.gemfile +3 -0
  10. data/gemfiles/rails51.gemfile +3 -0
  11. data/gemfiles/rails52.gemfile +4 -2
  12. data/gemfiles/rails60.gemfile +10 -0
  13. data/gemfiles/rails61.gemfile +10 -0
  14. data/lib/audited.rb +2 -1
  15. data/lib/audited/audit.rb +31 -25
  16. data/lib/audited/auditor.rb +199 -39
  17. data/lib/audited/rspec_matchers.rb +70 -21
  18. data/lib/audited/version.rb +1 -1
  19. data/lib/generators/audited/templates/add_version_to_auditable_index.rb +21 -0
  20. data/lib/generators/audited/templates/install.rb +1 -1
  21. data/lib/generators/audited/upgrade_generator.rb +4 -0
  22. data/spec/audited/audit_spec.rb +88 -21
  23. data/spec/audited/auditor_spec.rb +450 -57
  24. data/spec/audited/rspec_matchers_spec.rb +69 -0
  25. data/spec/audited/sweeper_spec.rb +15 -6
  26. data/spec/audited_spec_helpers.rb +16 -2
  27. data/spec/rails_app/app/assets/config/manifest.js +1 -0
  28. data/spec/rails_app/app/controllers/application_controller.rb +2 -0
  29. data/spec/rails_app/config/application.rb +5 -0
  30. data/spec/rails_app/config/database.yml +1 -0
  31. data/spec/spec_helper.rb +4 -1
  32. data/spec/support/active_record/models.rb +50 -3
  33. data/spec/support/active_record/schema.rb +4 -2
  34. data/test/db/version_6.rb +2 -0
  35. data/test/test_helper.rb +1 -2
  36. data/test/upgrade_generator_test.rb +10 -0
  37. metadata +60 -22
  38. data/gemfiles/rails40.gemfile +0 -9
  39. data/gemfiles/rails41.gemfile +0 -8
@@ -41,12 +41,12 @@ module Audited
41
41
  end
42
42
 
43
43
  def only(*fields)
44
- @options[:only] = fields.flatten
44
+ @options[:only] = fields.flatten.map(&:to_s)
45
45
  self
46
46
  end
47
47
 
48
48
  def except(*fields)
49
- @options[:except] = fields.flatten
49
+ @options[:except] = fields.flatten.map(&:to_s)
50
50
  self
51
51
  end
52
52
 
@@ -56,16 +56,13 @@ module Audited
56
56
  end
57
57
 
58
58
  def on(*actions)
59
- @options[:on] = actions.flatten
59
+ @options[:on] = actions.flatten.map(&:to_sym)
60
60
  self
61
61
  end
62
62
 
63
63
  def matches?(subject)
64
64
  @subject = subject
65
- auditing_enabled? &&
66
- associated_with_model? &&
67
- records_changes_to_specified_fields? &&
68
- comment_required_valid?
65
+ auditing_enabled? && required_checks_for_options_satisfied?
69
66
  end
70
67
 
71
68
  def failure_message
@@ -109,31 +106,83 @@ module Audited
109
106
  end
110
107
 
111
108
  def records_changes_to_specified_fields?
112
- if @options[:only] || @options[:except]
113
- if @options[:only]
114
- except = model_class.column_names - @options[:only].map(&:to_s)
115
- else
116
- except = model_class.default_ignored_attributes + Audited.ignored_attributes
117
- except |= @options[:except].collect(&:to_s) if @options[:except]
118
- end
109
+ ignored_fields = build_ignored_fields_from_options
110
+
111
+ expects "non audited columns (#{model_class.non_audited_columns.inspect}) to match (#{ignored_fields})"
112
+ model_class.non_audited_columns.to_set == ignored_fields.to_set
113
+ end
114
+
115
+ def comment_required_valid?
116
+ expects "to require audit_comment before #{model_class.audited_options[:on]} when comment required"
117
+ validate_callbacks_include_presence_of_comment? && destroy_callbacks_include_comment_required?
118
+ end
119
119
 
120
- expects "non audited columns (#{model_class.non_audited_columns.inspect}) to match (#{except})"
121
- model_class.non_audited_columns =~ except
120
+ def only_audit_on_designated_callbacks?
121
+ {
122
+ create: [:after, :audit_create],
123
+ update: [:before, :audit_update],
124
+ destroy: [:before, :audit_destroy]
125
+ }.map do |(action, kind_callback)|
126
+ kind, callback = kind_callback
127
+ callbacks_for(action, kind: kind).include?(callback) if @options[:on].include?(action)
128
+ end.compact.all?
129
+ end
130
+
131
+ def validate_callbacks_include_presence_of_comment?
132
+ if @options[:comment_required] && audited_on_create_or_update?
133
+ callbacks_for(:validate).include?(:presence_of_audit_comment)
122
134
  else
123
135
  true
124
136
  end
125
137
  end
126
138
 
127
- def comment_required_valid?
128
- if @options[:comment_required]
129
- @subject.audit_comment = nil
139
+ def audited_on_create_or_update?
140
+ model_class.audited_options[:on].include?(:create) || model_class.audited_options[:on].include?(:update)
141
+ end
130
142
 
131
- expects "to be invalid when audit_comment is not specified"
132
- @subject.valid? == false && @subject.errors.key?(:audit_comment)
143
+ def destroy_callbacks_include_comment_required?
144
+ if @options[:comment_required] && model_class.audited_options[:on].include?(:destroy)
145
+ callbacks_for(:destroy).include?(:require_comment)
133
146
  else
134
147
  true
135
148
  end
136
149
  end
150
+
151
+ def requires_comment_before_callbacks?
152
+ [:create, :update, :destroy].map do |action|
153
+ if @options[:comment_required] && model_class.audited_options[:on].include?(action)
154
+ callbacks_for(action).include?(:require_comment)
155
+ end
156
+ end.compact.all?
157
+ end
158
+
159
+ def callbacks_for(action, kind: :before)
160
+ model_class.send("_#{action}_callbacks").select { |cb| cb.kind == kind }.map(&:filter)
161
+ end
162
+
163
+ def build_ignored_fields_from_options
164
+ default_ignored_attributes = model_class.default_ignored_attributes
165
+
166
+ if @options[:only].present?
167
+ (default_ignored_attributes | model_class.column_names) - @options[:only]
168
+ elsif @options[:except].present?
169
+ default_ignored_attributes | @options[:except]
170
+ else
171
+ default_ignored_attributes
172
+ end
173
+ end
174
+
175
+ def required_checks_for_options_satisfied?
176
+ {
177
+ only: :records_changes_to_specified_fields?,
178
+ except: :records_changes_to_specified_fields?,
179
+ comment_required: :comment_required_valid?,
180
+ associated_with: :associated_with_model?,
181
+ on: :only_audit_on_designated_callbacks?
182
+ }.map do |(option, check)|
183
+ send(check) if @options[option].present?
184
+ end.compact.all?
185
+ end
137
186
  end
138
187
 
139
188
  class AssociatedAuditMatcher # :nodoc:
@@ -1,3 +1,3 @@
1
1
  module Audited
2
- VERSION = "4.6.0"
2
+ VERSION = "4.10.0"
3
3
  end
@@ -0,0 +1,21 @@
1
+ class <%= migration_class_name %> < <%= migration_parent %>
2
+ def self.up
3
+ if index_exists?(:audits, [:auditable_type, :auditable_id], name: index_name)
4
+ remove_index :audits, name: index_name
5
+ add_index :audits, [:auditable_type, :auditable_id, :version], name: index_name
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ if index_exists?(:audits, [:auditable_type, :auditable_id, :version], name: index_name)
11
+ remove_index :audits, name: index_name
12
+ add_index :audits, [:auditable_type, :auditable_id], name: index_name
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def index_name
19
+ 'auditable_index'
20
+ end
21
+ end
@@ -17,7 +17,7 @@ class <%= migration_class_name %> < <%= migration_parent %>
17
17
  t.column :created_at, :datetime
18
18
  end
19
19
 
20
- add_index :audits, [:auditable_type, :auditable_id], :name => 'auditable_index'
20
+ add_index :audits, [:auditable_type, :auditable_id, :version], :name => 'auditable_index'
21
21
  add_index :audits, [:associated_type, :associated_id], :name => 'associated_index'
22
22
  add_index :audits, [:user_id, :user_type], :name => 'user_index'
23
23
  add_index :audits, :request_uuid
@@ -58,6 +58,10 @@ module Audited
58
58
  if indexes.any? { |i| i.columns == %w[associated_id associated_type] }
59
59
  yield :revert_polymorphic_indexes_order
60
60
  end
61
+
62
+ if indexes.any? { |i| i.columns == %w[auditable_type auditable_id] }
63
+ yield :add_version_to_auditable_index
64
+ end
61
65
  end
62
66
  end
63
67
  end
@@ -1,5 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
+ SingleCov.covered! uncovered: 1 # Rails version check
4
+
3
5
  describe Audited::Audit do
4
6
  let(:user) { Models::ActiveRecord::User.new name: "Testing" }
5
7
 
@@ -38,43 +40,64 @@ describe Audited::Audit do
38
40
  end
39
41
  end
40
42
 
41
- it "should undo changes" do
42
- user = Models::ActiveRecord::User.create(name: "John")
43
+ context "when a custom audit class is not configured" do
44
+ it "should default to #{described_class}" do
45
+ TempModel.audited
46
+
47
+ record = TempModel.create
48
+
49
+ audit = record.audits.first
50
+ expect(audit).to be_a Audited::Audit
51
+ expect(audit.respond_to?(:custom_method)).to be false
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "#audited_changes" do
57
+ let(:audit) { Audited.audit_class.new }
58
+
59
+ it "can unserialize yaml from text columns" do
60
+ audit.audited_changes = {foo: "bar"}
61
+ expect(audit.audited_changes).to eq foo: "bar"
62
+ end
63
+
64
+ it "does not unserialize from binary columns" do
65
+ allow(Audited::YAMLIfTextColumnType).to receive(:text_column?).and_return(false)
66
+ audit.audited_changes = {foo: "bar"}
67
+ expect(audit.audited_changes).to eq "{:foo=>\"bar\"}"
68
+ end
69
+ end
70
+
71
+ describe "#undo" do
72
+ let(:user) { Models::ActiveRecord::User.create(name: "John") }
73
+
74
+ it "undos changes" do
43
75
  user.update_attribute(:name, 'Joe')
44
76
  user.audits.last.undo
45
77
  user.reload
46
-
47
78
  expect(user.name).to eq("John")
48
79
  end
49
80
 
50
- it "should undo destroyed model" do
51
- user = Models::ActiveRecord::User.create(name: "John")
81
+ it "undos destroy" do
52
82
  user.destroy
53
83
  user.audits.last.undo
54
84
  user = Models::ActiveRecord::User.find_by(name: "John")
55
85
  expect(user.name).to eq("John")
56
86
  end
57
87
 
58
- it "should undo created model" do
59
- user = Models::ActiveRecord::User.create(name: "John")
88
+ it "undos creation" do
89
+ user # trigger create
60
90
  expect {user.audits.last.undo}.to change(Models::ActiveRecord::User, :count).by(-1)
61
91
  end
62
92
 
63
- context "when a custom audit class is not configured" do
64
- it "should default to #{described_class}" do
65
- TempModel.audited
66
-
67
- record = TempModel.create
68
-
69
- audit = record.audits.first
70
- expect(audit).to be_a Audited::Audit
71
- expect(audit.respond_to?(:custom_method)).to be false
72
- end
93
+ it "fails when trying to undo unknown" do
94
+ audit = user.audits.last
95
+ audit.action = 'oops'
96
+ expect { audit.undo }.to raise_error("invalid action given oops")
73
97
  end
74
98
  end
75
99
 
76
100
  describe "user=" do
77
-
78
101
  it "should be able to set the user to a model object" do
79
102
  subject.user = user
80
103
  expect(subject.user).to eq(user)
@@ -110,11 +133,9 @@ describe Audited::Audit do
110
133
  subject.user = user
111
134
  expect(subject.username).to be_nil
112
135
  end
113
-
114
136
  end
115
137
 
116
138
  describe "revision" do
117
-
118
139
  it "should recreate attributes" do
119
140
  user = Models::ActiveRecord::User.create name: "1"
120
141
  5.times {|i| user.update_attribute :name, (i + 2).to_s }
@@ -148,6 +169,34 @@ describe Audited::Audit do
148
169
  end
149
170
  end
150
171
 
172
+ describe ".collection_cache_key" do
173
+ if ActiveRecord::VERSION::MAJOR >= 5
174
+ it "uses created at" do
175
+ Audited::Audit.delete_all
176
+ audit = Models::ActiveRecord::User.create(name: "John").audits.last
177
+ audit.update_columns(created_at: Time.zone.parse('2018-01-01'))
178
+ expect(Audited::Audit.collection_cache_key).to match(/-20180101\d+$/)
179
+ end
180
+ else
181
+ it "is not defined" do
182
+ expect { Audited::Audit.collection_cache_key }.to raise_error(NoMethodError)
183
+ end
184
+ end
185
+ end
186
+
187
+ describe ".assign_revision_attributes" do
188
+ it "dups when frozen" do
189
+ user.freeze
190
+ assigned = Audited::Audit.assign_revision_attributes(user, name: "Bar")
191
+ expect(assigned.name).to eq "Bar"
192
+ end
193
+
194
+ it "ignores unassignable attributes" do
195
+ assigned = Audited::Audit.assign_revision_attributes(user, oops: "Bar")
196
+ expect(assigned.name).to eq "Testing"
197
+ end
198
+ end
199
+
151
200
  it "should set the version number on create" do
152
201
  user = Models::ActiveRecord::User.create! name: "Set Version Number"
153
202
  expect(user.audits.first.version).to eq(1)
@@ -213,6 +262,25 @@ describe Audited::Audit do
213
262
  end
214
263
  end
215
264
 
265
+ it "should support nested as_user" do
266
+ Audited::Audit.as_user("sidekiq") do
267
+ company = Models::ActiveRecord::Company.create name: "The auditors"
268
+ company.name = "The Auditors, Inc"
269
+ company.save
270
+ expect(company.audits[-1].user).to eq("sidekiq")
271
+
272
+ Audited::Audit.as_user(user) do
273
+ company.name = "NEW Auditors, Inc"
274
+ company.save
275
+ expect(company.audits[-1].user).to eq(user)
276
+ end
277
+
278
+ company.name = "LAST Auditors, Inc"
279
+ company.save
280
+ expect(company.audits[-1].user).to eq("sidekiq")
281
+ end
282
+ end
283
+
216
284
  it "should record usernames" do
217
285
  Audited::Audit.as_user(user.name) do
218
286
  company = Models::ActiveRecord::Company.create name: "The auditors"
@@ -263,6 +331,5 @@ describe Audited::Audit do
263
331
  }.to raise_exception('expected')
264
332
  expect(Audited.store[:audited_user]).to be_nil
265
333
  end
266
-
267
334
  end
268
335
  end
@@ -1,5 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
+ SingleCov.covered! uncovered: 13 # not testing proxy_respond_to? hack / 2 methods / deprecation of `version`
4
+
3
5
  describe Audited::Auditor do
4
6
 
5
7
  describe "configuration" do
@@ -17,6 +19,132 @@ describe Audited::Auditor do
17
19
  end
18
20
  end
19
21
 
22
+ context "should be configurable which conditions are audited" do
23
+ subject { ConditionalCompany.new.send(:auditing_enabled) }
24
+
25
+ context "when condition method is private" do
26
+ subject { ConditionalPrivateCompany.new.send(:auditing_enabled) }
27
+
28
+ before do
29
+ class ConditionalPrivateCompany < ::ActiveRecord::Base
30
+ self.table_name = 'companies'
31
+
32
+ audited if: :foo?
33
+
34
+ private def foo?
35
+ true
36
+ end
37
+ end
38
+ end
39
+
40
+ it { is_expected.to be_truthy }
41
+ end
42
+
43
+ context "when passing a method name" do
44
+ before do
45
+ class ConditionalCompany < ::ActiveRecord::Base
46
+ self.table_name = 'companies'
47
+
48
+ audited if: :public?
49
+
50
+ def public?; end
51
+ end
52
+ end
53
+
54
+ context "when conditions are true" do
55
+ before { allow_any_instance_of(ConditionalCompany).to receive(:public?).and_return(true) }
56
+ it { is_expected.to be_truthy }
57
+ end
58
+
59
+ context "when conditions are false" do
60
+ before { allow_any_instance_of(ConditionalCompany).to receive(:public?).and_return(false) }
61
+ it { is_expected.to be_falsey }
62
+ end
63
+ end
64
+
65
+ context "when passing a Proc" do
66
+ context "when conditions are true" do
67
+ before do
68
+ class InclusiveCompany < ::ActiveRecord::Base
69
+ self.table_name = 'companies'
70
+ audited if: Proc.new { true }
71
+ end
72
+ end
73
+
74
+ subject { InclusiveCompany.new.send(:auditing_enabled) }
75
+
76
+ it { is_expected.to be_truthy }
77
+ end
78
+
79
+ context "when conditions are false" do
80
+ before do
81
+ class ExclusiveCompany < ::ActiveRecord::Base
82
+ self.table_name = 'companies'
83
+ audited if: Proc.new { false }
84
+ end
85
+ end
86
+ subject { ExclusiveCompany.new.send(:auditing_enabled) }
87
+ it { is_expected.to be_falsey }
88
+ end
89
+ end
90
+ end
91
+
92
+ context "should be configurable which conditions aren't audited" do
93
+ context "when using a method name" do
94
+ before do
95
+ class ExclusionaryCompany < ::ActiveRecord::Base
96
+ self.table_name = 'companies'
97
+
98
+ audited unless: :non_profit?
99
+
100
+ def non_profit?; end
101
+ end
102
+ end
103
+
104
+ subject { ExclusionaryCompany.new.send(:auditing_enabled) }
105
+
106
+ context "when conditions are true" do
107
+ before { allow_any_instance_of(ExclusionaryCompany).to receive(:non_profit?).and_return(true) }
108
+ it { is_expected.to be_falsey }
109
+ end
110
+
111
+ context "when conditions are false" do
112
+ before { allow_any_instance_of(ExclusionaryCompany).to receive(:non_profit?).and_return(false) }
113
+ it { is_expected.to be_truthy }
114
+ end
115
+ end
116
+
117
+ context "when using a proc" do
118
+ context "when conditions are true" do
119
+ before do
120
+ class ExclusionaryCompany < ::ActiveRecord::Base
121
+ self.table_name = 'companies'
122
+ audited unless: Proc.new { |c| c.exclusive? }
123
+
124
+ def exclusive?
125
+ true
126
+ end
127
+ end
128
+ end
129
+
130
+ subject { ExclusionaryCompany.new.send(:auditing_enabled) }
131
+ it { is_expected.to be_falsey }
132
+ end
133
+
134
+ context "when conditions are false" do
135
+ before do
136
+ class InclusiveCompany < ::ActiveRecord::Base
137
+ self.table_name = 'companies'
138
+ audited unless: Proc.new { false }
139
+ end
140
+ end
141
+
142
+ subject { InclusiveCompany.new.send(:auditing_enabled) }
143
+ it { is_expected.to be_truthy }
144
+ end
145
+ end
146
+ end
147
+
20
148
  it "should be configurable which attributes are not audited via ignored_attributes" do
21
149
  Audited.ignored_attributes = ['delta', 'top_secret', 'created_at']
22
150
  class Secret < ::ActiveRecord::Base
@@ -36,9 +164,14 @@ describe Audited::Auditor do
36
164
  end
37
165
 
38
166
  it "should not save non-audited columns" do
39
- Models::ActiveRecord::User.non_audited_columns = (Models::ActiveRecord::User.non_audited_columns << :favourite_device)
167
+ previous = Models::ActiveRecord::User.non_audited_columns
168
+ begin
169
+ Models::ActiveRecord::User.non_audited_columns += [:favourite_device]
40
170
 
41
- expect(create_user.audits.first.audited_changes.keys.any? { |col| ['favourite_device', 'created_at', 'updated_at', 'password'].include?( col ) }).to eq(false)
171
+ expect(create_user.audits.first.audited_changes.keys.any? { |col| ['favourite_device', 'created_at', 'updated_at', 'password'].include?( col ) }).to eq(false)
172
+ ensure
173
+ Models::ActiveRecord::User.non_audited_columns = previous
174
+ end
42
175
  end
43
176
 
44
177
  it "should not save other columns than specified in 'only' option" do
@@ -79,16 +212,49 @@ describe Audited::Auditor do
79
212
  expect(user.audits.last.audited_changes.keys).to eq(%w{non_column_attr})
80
213
  end
81
214
 
82
- if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' && Rails.version >= "4.2.0.0" # Postgres json and jsonb support was added in Rails 4.2
215
+ it "should redact columns specified in 'redacted' option" do
216
+ redacted = Audited::Auditor::AuditedInstanceMethods::REDACTED
217
+ user = Models::ActiveRecord::UserRedactedPassword.create(password: "password")
218
+ user.save!
219
+ expect(user.audits.last.audited_changes['password']).to eq(redacted)
220
+ user.password = "new_password"
221
+ user.save!
222
+ expect(user.audits.last.audited_changes['password']).to eq([redacted, redacted])
223
+ end
224
+
225
+ it "should redact columns specified in 'redacted' option when there are multiple specified" do
226
+ redacted = Audited::Auditor::AuditedInstanceMethods::REDACTED
227
+ user =
228
+ Models::ActiveRecord::UserMultipleRedactedAttributes.create(
229
+ password: "password",
230
+ ssn: 123456789
231
+ )
232
+ user.save!
233
+ expect(user.audits.last.audited_changes['password']).to eq(redacted)
234
+ expect(user.audits.last.audited_changes['ssn']).to eq(redacted)
235
+ user.password = "new_password"
236
+ user.ssn = 987654321
237
+ user.save!
238
+ expect(user.audits.last.audited_changes['password']).to eq([redacted, redacted])
239
+ expect(user.audits.last.audited_changes['ssn']).to eq([redacted, redacted])
240
+ end
241
+
242
+ it "should redact columns in 'redacted' column with custom option" do
243
+ user = Models::ActiveRecord::UserRedactedPasswordCustomRedaction.create(password: "password")
244
+ user.save!
245
+ expect(user.audits.last.audited_changes['password']).to eq(["My", "Custom", "Value", 7])
246
+ end
247
+
248
+ if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
83
249
  describe "'json' and 'jsonb' audited_changes column type" do
84
250
  let(:migrations_path) { SPEC_ROOT.join("support/active_record/postgres") }
85
251
 
86
252
  after do
87
- ActiveRecord::Migrator.rollback([migrations_path])
253
+ run_migrations(:down, migrations_path)
88
254
  end
89
255
 
90
256
  it "should work if column type is 'json'" do
91
- ActiveRecord::Migrator.up([migrations_path], 1)
257
+ run_migrations(:up, migrations_path, 1)
92
258
  Audited::Audit.reset_column_information
93
259
  expect(Audited::Audit.columns_hash["audited_changes"].sql_type).to eq("json")
94
260
 
@@ -99,7 +265,7 @@ describe Audited::Auditor do
99
265
  end
100
266
 
101
267
  it "should work if column type is 'jsonb'" do
102
- ActiveRecord::Migrator.up([migrations_path], 2)
268
+ run_migrations(:up, migrations_path, 2)
103
269
  Audited::Audit.reset_column_information
104
270
  expect(Audited::Audit.columns_hash["audited_changes"].sql_type).to eq("jsonb")
105
271
 
@@ -133,7 +299,7 @@ describe Audited::Auditor do
133
299
  end
134
300
 
135
301
  describe "on create" do
136
- let( :user ) { create_user audit_comment: "Create" }
302
+ let( :user ) { create_user status: :reliable, audit_comment: "Create" }
137
303
 
138
304
  it "should change the audit count" do
139
305
  expect {
@@ -157,6 +323,10 @@ describe Audited::Auditor do
157
323
  expect(user.audits.first.audited_changes).to eq(user.audited_attributes)
158
324
  end
159
325
 
326
+ it "should store enum value" do
327
+ expect(user.audits.first.audited_changes["status"]).to eq(1)
328
+ end
329
+
160
330
  it "should store comment" do
161
331
  expect(user.audits.first.comment).to eq('Create')
162
332
  end
@@ -175,7 +345,7 @@ describe Audited::Auditor do
175
345
 
176
346
  describe "on update" do
177
347
  before do
178
- @user = create_user( name: 'Brandon', audit_comment: 'Update' )
348
+ @user = create_user( name: 'Brandon', status: :active, audit_comment: 'Update' )
179
349
  end
180
350
 
181
351
  it "should save an audit" do
@@ -188,17 +358,22 @@ describe Audited::Auditor do
188
358
  end
189
359
 
190
360
  it "should set the action to 'update'" do
191
- @user.update_attributes name: 'Changed'
361
+ @user.update! name: 'Changed'
192
362
  expect(@user.audits.last.action).to eq('update')
193
363
  expect(Audited::Audit.updates.order(:id).last).to eq(@user.audits.last)
194
364
  expect(@user.audits.updates.last).to eq(@user.audits.last)
195
365
  end
196
366
 
197
367
  it "should store the changed attributes" do
198
- @user.update_attributes name: 'Changed'
368
+ @user.update! name: 'Changed'
199
369
  expect(@user.audits.last.audited_changes).to eq({ 'name' => ['Brandon', 'Changed'] })
200
370
  end
201
371
 
372
+ it "should store changed enum values" do
373
+ @user.update! status: 1
374
+ expect(@user.audits.last.audited_changes["status"]).to eq([0, 1])
375
+ end
376
+
202
377
  it "should store audit comment" do
203
378
  expect(@user.audits.last.comment).to eq('Update')
204
379
  end
@@ -206,12 +381,12 @@ describe Audited::Auditor do
206
381
  it "should not save an audit if only specified on create/destroy" do
207
382
  on_create_destroy = Models::ActiveRecord::OnCreateDestroy.create( name: 'Bart' )
208
383
  expect {
209
- on_create_destroy.update_attributes name: 'Changed'
384
+ on_create_destroy.update! name: 'Changed'
210
385
  }.to_not change( Audited::Audit, :count )
211
386
  end
212
387
 
213
388
  it "should not save an audit if the value doesn't change after type casting" do
214
- @user.update_attributes! logins: 0, activated: true
389
+ @user.update! logins: 0, activated: true
215
390
  expect { @user.update_attribute :logins, '0' }.to_not change( Audited::Audit, :count )
216
391
  expect { @user.update_attribute :activated, 1 }.to_not change( Audited::Audit, :count )
217
392
  expect { @user.update_attribute :activated, '1' }.to_not change( Audited::Audit, :count )
@@ -235,7 +410,7 @@ describe Audited::Auditor do
235
410
 
236
411
  describe "on destroy" do
237
412
  before do
238
- @user = create_user
413
+ @user = create_user(status: :active)
239
414
  end
240
415
 
241
416
  it "should save an audit" do
@@ -260,6 +435,11 @@ describe Audited::Auditor do
260
435
  expect(@user.audits.last.audited_changes).to eq(@user.audited_attributes)
261
436
  end
262
437
 
438
+ it "should store enum value" do
439
+ @user.destroy
440
+ expect(@user.audits.last.audited_changes["status"]).to eq(0)
441
+ end
442
+
263
443
  it "should be able to reconstruct a destroyed record without history" do
264
444
  @user.audits.delete_all
265
445
  @user.destroy
@@ -329,6 +509,77 @@ describe Audited::Auditor do
329
509
  end
330
510
  end
331
511
 
512
+ describe "max_audits" do
513
+ it "should respect global setting" do
514
+ stub_global_max_audits(10) do
515
+ expect(Models::ActiveRecord::User.audited_options[:max_audits]).to eq(10)
516
+ end
517
+ end
518
+
519
+ it "should respect per model setting" do
520
+ stub_global_max_audits(10) do
521
+ expect(Models::ActiveRecord::MaxAuditsUser.audited_options[:max_audits]).to eq(5)
522
+ end
523
+ end
524
+
525
+ it "should delete old audits when keeped amount exceeded" do
526
+ stub_global_max_audits(2) do
527
+ user = create_versions(2)
528
+ user.update(name: 'John')
529
+ expect(user.audits.pluck(:version)).to eq([2, 3])
530
+ end
531
+ end
532
+
533
+ it "should not delete old audits when keeped amount not exceeded" do
534
+ stub_global_max_audits(3) do
535
+ user = create_versions(2)
536
+ user.update(name: 'John')
537
+ expect(user.audits.pluck(:version)).to eq([1, 2, 3])
538
+ end
539
+ end
540
+
541
+ it "should delete old extra audits after introducing limit" do
542
+ stub_global_max_audits(nil) do
543
+ user = Models::ActiveRecord::User.create!(name: 'Brandon', username: 'brandon')
544
+ user.update!(name: 'Foobar')
545
+ user.update!(name: 'Awesome', username: 'keepers')
546
+ user.update!(activated: true)
547
+
548
+ Audited.max_audits = 3
549
+ Models::ActiveRecord::User.send(:normalize_audited_options)
550
+ user.update!(favourite_device: 'Android Phone')
551
+ audits = user.audits
552
+
553
+ expect(audits.count).to eq(3)
554
+ expect(audits[0].audited_changes).to include({'name' => ['Foobar', 'Awesome'], 'username' => ['brandon', 'keepers']})
555
+ expect(audits[1].audited_changes).to eq({'activated' => [nil, true]})
556
+ expect(audits[2].audited_changes).to eq({'favourite_device' => [nil, 'Android Phone']})
557
+ end
558
+ end
559
+
560
+ it "should add comment line for combined audit" do
561
+ stub_global_max_audits(2) do
562
+ user = Models::ActiveRecord::User.create!(name: 'Foobar 1')
563
+ user.update(name: 'Foobar 2', audit_comment: 'First audit comment')
564
+ user.update(name: 'Foobar 3', audit_comment: 'Second audit comment')
565
+ expect(user.audits.first.comment).to match(/First audit comment.+is the result of multiple/m)
566
+ end
567
+ end
568
+
569
+ def stub_global_max_audits(max_audits)
570
+ previous_max_audits = Audited.max_audits
571
+ previous_user_audited_options = Models::ActiveRecord::User.audited_options.dup
572
+ begin
573
+ Audited.max_audits = max_audits
574
+ Models::ActiveRecord::User.send(:normalize_audited_options) # reloads audited_options
575
+ yield
576
+ ensure
577
+ Audited.max_audits = previous_max_audits
578
+ Models::ActiveRecord::User.audited_options = previous_user_audited_options
579
+ end
580
+ end
581
+ end
582
+
332
583
  describe "revisions" do
333
584
  let( :user ) { create_versions }
334
585
 
@@ -347,8 +598,8 @@ describe Audited::Auditor do
347
598
 
348
599
  it "should set the attributes for each revision" do
349
600
  u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
350
- u.update_attributes name: 'Foobar'
351
- u.update_attributes name: 'Awesome', username: 'keepers'
601
+ u.update! name: 'Foobar'
602
+ u.update! name: 'Awesome', username: 'keepers'
352
603
 
353
604
  expect(u.revisions.size).to eql(3)
354
605
 
@@ -364,8 +615,8 @@ describe Audited::Auditor do
364
615
 
365
616
  it "access to only recent revisions" do
366
617
  u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
367
- u.update_attributes name: 'Foobar'
368
- u.update_attributes name: 'Awesome', username: 'keepers'
618
+ u.update! name: 'Foobar'
619
+ u.update! name: 'Awesome', username: 'keepers'
369
620
 
370
621
  expect(u.revisions(2).size).to eq(2)
371
622
 
@@ -382,7 +633,7 @@ describe Audited::Auditor do
382
633
  end
383
634
 
384
635
  it "should ignore attributes that have been deleted" do
385
- user.audits.last.update_attributes audited_changes: {old_attribute: 'old value'}
636
+ user.audits.last.update! audited_changes: {old_attribute: 'old value'}
386
637
  expect { user.revisions }.to_not raise_error
387
638
  end
388
639
  end
@@ -397,21 +648,21 @@ describe Audited::Auditor do
397
648
  it "should find the given revision" do
398
649
  revision = user.revision(3)
399
650
  expect(revision).to be_a_kind_of( Models::ActiveRecord::User )
400
- expect(revision.version).to eq(3)
651
+ expect(revision.audit_version).to eq(3)
401
652
  expect(revision.name).to eq('Foobar 3')
402
653
  end
403
654
 
404
655
  it "should find the previous revision with :previous" do
405
656
  revision = user.revision(:previous)
406
- expect(revision.version).to eq(4)
657
+ expect(revision.audit_version).to eq(4)
407
658
  #expect(revision).to eq(user.revision(4))
408
659
  expect(revision.attributes).to eq(user.revision(4).attributes)
409
660
  end
410
661
 
411
662
  it "should be able to get the previous revision repeatedly" do
412
663
  previous = user.revision(:previous)
413
- expect(previous.version).to eq(4)
414
- expect(previous.revision(:previous).version).to eq(3)
664
+ expect(previous.audit_version).to eq(4)
665
+ expect(previous.revision(:previous).audit_version).to eq(3)
415
666
  end
416
667
 
417
668
  it "should be able to set protected attributes" do
@@ -431,8 +682,8 @@ describe Audited::Auditor do
431
682
 
432
683
  it "should set the attributes for each revision" do
433
684
  u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
434
- u.update_attributes name: 'Foobar'
435
- u.update_attributes name: 'Awesome', username: 'keepers'
685
+ u.update! name: 'Foobar'
686
+ u.update! name: 'Awesome', username: 'keepers'
436
687
 
437
688
  expect(u.revision(3).name).to eq('Awesome')
438
689
  expect(u.revision(3).username).to eq('keepers')
@@ -444,6 +695,16 @@ describe Audited::Auditor do
444
695
  expect(u.revision(1).username).to eq('brandon')
445
696
  end
446
697
 
698
+ it "should correctly restore revision with enum" do
699
+ u = Models::ActiveRecord::User.create(status: :active)
700
+ u.update_attribute(:status, :reliable)
701
+ u.update_attribute(:status, :banned)
702
+
703
+ expect(u.revision(3)).to be_banned
704
+ expect(u.revision(2)).to be_reliable
705
+ expect(u.revision(1)).to be_active
706
+ end
707
+
447
708
  it "should be able to get time for first revision" do
448
709
  suspended_at = Time.zone.now
449
710
  u = Models::ActiveRecord::User.create(suspended_at: suspended_at)
@@ -484,8 +745,8 @@ describe Audited::Auditor do
484
745
  audit = user.audits.first
485
746
  audit.created_at = 1.hour.ago
486
747
  audit.save!
487
- user.update_attributes name: 'updated'
488
- expect(user.revision_at( 2.minutes.ago ).version).to eq(1)
748
+ user.update! name: 'updated'
749
+ expect(user.revision_at( 2.minutes.ago ).audit_version).to eq(1)
489
750
  end
490
751
 
491
752
  it "should be nil if given a time before audits" do
@@ -493,6 +754,33 @@ describe Audited::Auditor do
493
754
  end
494
755
  end
495
756
 
757
+ describe "own_and_associated_audits" do
758
+ it "should return audits for self and associated audits" do
759
+ owner = Models::ActiveRecord::Owner.create!
760
+ company = owner.companies.create!
761
+ company.update!(name: "Collective Idea")
762
+
763
+ other_owner = Models::ActiveRecord::Owner.create!
764
+ other_owner.companies.create!
765
+
766
+ expect(owner.own_and_associated_audits).to match_array(owner.audits + company.audits)
767
+ end
768
+
769
+ it "should order audits by creation time" do
770
+ owner = Models::ActiveRecord::Owner.create!
771
+ first_audit = owner.audits.first
772
+ first_audit.update_column(:created_at, 1.year.ago)
773
+
774
+ company = owner.companies.create!
775
+ second_audit = company.audits.first
776
+ second_audit.update_column(:created_at, 1.month.ago)
777
+
778
+ company.update!(name: "Collective Idea")
779
+ third_audit = company.audits.last
780
+ expect(owner.own_and_associated_audits.to_a).to eq([third_audit, second_audit, first_audit])
781
+ end
782
+ end
783
+
496
784
  describe "without auditing" do
497
785
  it "should not save an audit when calling #save_without_auditing" do
498
786
  expect {
@@ -513,72 +801,162 @@ describe Audited::Auditor do
513
801
  end
514
802
 
515
803
  it "should be thread safe using a #without_auditing block" do
516
- begin
517
- t1 = Thread.new do
518
- expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
519
- Models::ActiveRecord::User.without_auditing do
520
- expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
521
- Models::ActiveRecord::User.create!( name: 'Bart' )
522
- sleep 1
523
- expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
524
- end
525
- expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
804
+ skip if Models::ActiveRecord::User.connection.class.name.include?("SQLite")
805
+
806
+ t1 = Thread.new do
807
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
808
+ Models::ActiveRecord::User.without_auditing do
809
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
810
+ Models::ActiveRecord::User.create!( name: 'Bart' )
811
+ sleep 1
812
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
526
813
  end
814
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
815
+ end
816
+
817
+ t2 = Thread.new do
818
+ sleep 0.5
819
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
820
+ Models::ActiveRecord::User.create!( name: 'Lisa' )
821
+ end
822
+ t1.join
823
+ t2.join
824
+
825
+ expect(Models::ActiveRecord::User.find_by_name('Bart').audits.count).to eq(0)
826
+ expect(Models::ActiveRecord::User.find_by_name('Lisa').audits.count).to eq(1)
827
+ end
828
+
829
+ it "should not save an audit when auditing is globally disabled" do
830
+ expect(Audited.auditing_enabled).to eq(true)
831
+ Audited.auditing_enabled = false
832
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
833
+
834
+ user = create_user
835
+ expect(user.audits.count).to eq(0)
836
+
837
+ Audited.auditing_enabled = true
838
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
839
+
840
+ user.update!(name: 'Test')
841
+ expect(user.audits.count).to eq(1)
842
+ Models::ActiveRecord::User.enable_auditing
843
+ end
844
+ end
845
+
846
+ describe "with auditing" do
847
+ it "should save an audit when calling #save_with_auditing" do
848
+ expect {
849
+ u = Models::ActiveRecord::User.new(name: 'Brandon')
850
+ Models::ActiveRecord::User.auditing_enabled = false
851
+ expect(u.save_with_auditing).to eq(true)
852
+ Models::ActiveRecord::User.auditing_enabled = true
853
+ }.to change( Audited::Audit, :count ).by(1)
854
+ end
855
+
856
+ it "should save an audit inside of the #with_auditing block" do
857
+ expect {
858
+ Models::ActiveRecord::User.auditing_enabled = false
859
+ Models::ActiveRecord::User.with_auditing { Models::ActiveRecord::User.create!( name: 'Brandon' ) }
860
+ Models::ActiveRecord::User.auditing_enabled = true
861
+ }.to change( Audited::Audit, :count ).by(1)
862
+ end
863
+
864
+ it "should reset auditing status even it raises an exception" do
865
+ Models::ActiveRecord::User.disable_auditing
866
+ Models::ActiveRecord::User.with_auditing { raise } rescue nil
867
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
868
+ Models::ActiveRecord::User.enable_auditing
869
+ end
870
+
871
+ it "should be thread safe using a #with_auditing block" do
872
+ skip if Models::ActiveRecord::User.connection.class.name.include?("SQLite")
527
873
 
528
- t2 = Thread.new do
529
- sleep 0.5
874
+ t1 = Thread.new do
875
+ Models::ActiveRecord::User.disable_auditing
876
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
877
+ Models::ActiveRecord::User.with_auditing do
878
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
879
+
880
+ Models::ActiveRecord::User.create!( name: 'Shaggy' )
881
+ sleep 1
530
882
  expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
531
- Models::ActiveRecord::User.create!( name: 'Lisa' )
532
883
  end
533
- t1.join
534
- t2.join
884
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
885
+ Models::ActiveRecord::User.enable_auditing
886
+ end
535
887
 
536
- expect(Models::ActiveRecord::User.find_by_name('Bart').audits.count).to eq(0)
537
- expect(Models::ActiveRecord::User.find_by_name('Lisa').audits.count).to eq(1)
538
- rescue ActiveRecord::StatementInvalid
539
- STDERR.puts "Thread safety tests cannot be run with SQLite"
888
+ t2 = Thread.new do
889
+ sleep 0.5
890
+ Models::ActiveRecord::User.disable_auditing
891
+ expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
892
+ Models::ActiveRecord::User.create!( name: 'Scooby' )
893
+ Models::ActiveRecord::User.enable_auditing
540
894
  end
895
+ t1.join
896
+ t2.join
897
+
898
+ Models::ActiveRecord::User.enable_auditing
899
+ expect(Models::ActiveRecord::User.find_by_name('Shaggy').audits.count).to eq(1)
900
+ expect(Models::ActiveRecord::User.find_by_name('Scooby').audits.count).to eq(0)
541
901
  end
542
902
  end
543
903
 
544
904
  describe "comment required" do
545
905
 
546
906
  describe "on create" do
547
- it "should not validate when audit_comment is not supplied" do
548
- expect(Models::ActiveRecord::CommentRequiredUser.new).not_to be_valid
907
+ it "should not validate when audit_comment is not supplied when initialized" do
908
+ expect(Models::ActiveRecord::CommentRequiredUser.new(name: 'Foo')).not_to be_valid
909
+ end
910
+
911
+ it "should not validate when audit_comment is not supplied trying to create" do
912
+ expect(Models::ActiveRecord::CommentRequiredUser.create(name: 'Foo')).not_to be_valid
549
913
  end
550
914
 
551
915
  it "should validate when audit_comment is supplied" do
552
- expect(Models::ActiveRecord::CommentRequiredUser.new( audit_comment: 'Create')).to be_valid
916
+ expect(Models::ActiveRecord::CommentRequiredUser.create(name: 'Foo', audit_comment: 'Create')).to be_valid
917
+ end
918
+
919
+ it "should validate when audit_comment is not supplied, and creating is not being audited" do
920
+ expect(Models::ActiveRecord::OnUpdateCommentRequiredUser.create(name: 'Foo')).to be_valid
921
+ expect(Models::ActiveRecord::OnDestroyCommentRequiredUser.create(name: 'Foo')).to be_valid
553
922
  end
554
923
 
555
924
  it "should validate when audit_comment is not supplied, and auditing is disabled" do
556
925
  Models::ActiveRecord::CommentRequiredUser.disable_auditing
557
- expect(Models::ActiveRecord::CommentRequiredUser.new).to be_valid
926
+ expect(Models::ActiveRecord::CommentRequiredUser.create(name: 'Foo')).to be_valid
558
927
  Models::ActiveRecord::CommentRequiredUser.enable_auditing
559
928
  end
560
929
  end
561
930
 
562
931
  describe "on update" do
563
932
  let( :user ) { Models::ActiveRecord::CommentRequiredUser.create!( audit_comment: 'Create' ) }
933
+ let( :on_create_user ) { Models::ActiveRecord::OnDestroyCommentRequiredUser.create }
934
+ let( :on_destroy_user ) { Models::ActiveRecord::OnDestroyCommentRequiredUser.create }
564
935
 
565
936
  it "should not validate when audit_comment is not supplied" do
566
- expect(user.update_attributes(name: 'Test')).to eq(false)
937
+ expect(user.update(name: 'Test')).to eq(false)
938
+ end
939
+
940
+ it "should validate when audit_comment is not supplied, and updating is not being audited" do
941
+ expect(on_create_user.update(name: 'Test')).to eq(true)
942
+ expect(on_destroy_user.update(name: 'Test')).to eq(true)
567
943
  end
568
944
 
569
945
  it "should validate when audit_comment is supplied" do
570
- expect(user.update_attributes(name: 'Test', audit_comment: 'Update')).to eq(true)
946
+ expect(user.update(name: 'Test', audit_comment: 'Update')).to eq(true)
571
947
  end
572
948
 
573
949
  it "should validate when audit_comment is not supplied, and auditing is disabled" do
574
950
  Models::ActiveRecord::CommentRequiredUser.disable_auditing
575
- expect(user.update_attributes(name: 'Test')).to eq(true)
951
+ expect(user.update(name: 'Test')).to eq(true)
576
952
  Models::ActiveRecord::CommentRequiredUser.enable_auditing
577
953
  end
578
954
  end
579
955
 
580
956
  describe "on destroy" do
581
957
  let( :user ) { Models::ActiveRecord::CommentRequiredUser.create!( audit_comment: 'Create' )}
958
+ let( :on_create_user ) { Models::ActiveRecord::OnCreateCommentRequiredUser.create!( audit_comment: 'Create' ) }
959
+ let( :on_update_user ) { Models::ActiveRecord::OnUpdateCommentRequiredUser.create }
582
960
 
583
961
  it "should not validate when audit_comment is not supplied" do
584
962
  expect(user.destroy).to eq(false)
@@ -589,6 +967,11 @@ describe Audited::Auditor do
589
967
  expect(user.destroy).to eq(user)
590
968
  end
591
969
 
970
+ it "should validate when audit_comment is not supplied, and destroying is not being audited" do
971
+ expect(on_create_user.destroy).to eq(on_create_user)
972
+ expect(on_update_user.destroy).to eq(on_update_user)
973
+ end
974
+
592
975
  it "should validate when audit_comment is not supplied, and auditing is disabled" do
593
976
  Models::ActiveRecord::CommentRequiredUser.disable_auditing
594
977
  expect(user.destroy).to eq(user)
@@ -598,6 +981,16 @@ describe Audited::Auditor do
598
981
 
599
982
  end
600
983
 
984
+ describe "no update with comment only" do
985
+ let( :user ) { Models::ActiveRecord::NoUpdateWithCommentOnlyUser.create }
986
+
987
+ it "does not create an audit when only an audit_comment is present" do
988
+ user.audit_comment = "Comment"
989
+ expect { user.save! }.to_not change( Audited::Audit, :count )
990
+ end
991
+
992
+ end
993
+
601
994
  describe "attr_protected and attr_accessible" do
602
995
 
603
996
  it "should not raise error when attr_accessible is set and protected is false" do
@@ -619,7 +1012,7 @@ describe Audited::Auditor do
619
1012
  it "should record user objects" do
620
1013
  Models::ActiveRecord::Company.audit_as( user ) do
621
1014
  company = Models::ActiveRecord::Company.create name: 'The auditors'
622
- company.update_attributes name: 'The Auditors'
1015
+ company.update! name: 'The Auditors'
623
1016
 
624
1017
  company.audits.each do |audit|
625
1018
  expect(audit.user).to eq(user)
@@ -630,7 +1023,7 @@ describe Audited::Auditor do
630
1023
  it "should record usernames" do
631
1024
  Models::ActiveRecord::Company.audit_as( user.name ) do
632
1025
  company = Models::ActiveRecord::Company.create name: 'The auditors'
633
- company.update_attributes name: 'The Auditors'
1026
+ company.update! name: 'The Auditors'
634
1027
 
635
1028
  company.audits.each do |audit|
636
1029
  expect(audit.user).to eq(user.name)
@@ -640,7 +1033,7 @@ describe Audited::Auditor do
640
1033
  end
641
1034
 
642
1035
  describe "after_audit" do
643
- let( :user ) { user = Models::ActiveRecord::UserWithAfterAudit.new }
1036
+ let( :user ) { Models::ActiveRecord::UserWithAfterAudit.new }
644
1037
 
645
1038
  it "should invoke after_audit callback on create" do
646
1039
  expect(user.bogus_attr).to be_nil
@@ -650,7 +1043,7 @@ describe Audited::Auditor do
650
1043
  end
651
1044
 
652
1045
  describe "around_audit" do
653
- let( :user ) { user = Models::ActiveRecord::UserWithAfterAudit.new }
1046
+ let( :user ) { Models::ActiveRecord::UserWithAfterAudit.new }
654
1047
 
655
1048
  it "should invoke around_audit callback on create" do
656
1049
  expect(user.around_attr).to be_nil
@@ -665,7 +1058,7 @@ describe Audited::Auditor do
665
1058
  expect(company.type).to eq("Models::ActiveRecord::Company::STICompany")
666
1059
  expect {
667
1060
  Models::ActiveRecord::Company.auditing_enabled = false
668
- company.update_attributes name: 'STI auditors'
1061
+ company.update! name: 'STI auditors'
669
1062
  Models::ActiveRecord::Company.auditing_enabled = true
670
1063
  }.to_not change( Audited::Audit, :count )
671
1064
  end