audited 4.9.0 → 5.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/buildlight.yml +15 -0
  3. data/.github/workflows/ci.yml +145 -0
  4. data/.github/workflows/publish_gem.yml +28 -0
  5. data/.standard.yml +5 -0
  6. data/Appraisals +35 -16
  7. data/CHANGELOG.md +162 -1
  8. data/Gemfile +1 -1
  9. data/README.md +73 -18
  10. data/Rakefile +5 -7
  11. data/gemfiles/rails50.gemfile +2 -0
  12. data/gemfiles/rails51.gemfile +2 -0
  13. data/gemfiles/rails52.gemfile +3 -1
  14. data/gemfiles/rails60.gemfile +1 -1
  15. data/gemfiles/rails61.gemfile +10 -0
  16. data/gemfiles/rails70.gemfile +10 -0
  17. data/gemfiles/rails71.gemfile +10 -0
  18. data/lib/audited/audit.rb +41 -29
  19. data/lib/audited/auditor.rb +134 -56
  20. data/lib/audited/railtie.rb +16 -0
  21. data/lib/audited/rspec_matchers.rb +5 -3
  22. data/lib/audited/sweeper.rb +3 -10
  23. data/lib/audited/version.rb +3 -1
  24. data/lib/audited-rspec.rb +3 -1
  25. data/lib/audited.rb +31 -9
  26. data/lib/generators/audited/install_generator.rb +9 -7
  27. data/lib/generators/audited/migration.rb +12 -2
  28. data/lib/generators/audited/migration_helper.rb +3 -1
  29. data/lib/generators/audited/templates/add_association_to_audits.rb +2 -0
  30. data/lib/generators/audited/templates/add_comment_to_audits.rb +2 -0
  31. data/lib/generators/audited/templates/add_remote_address_to_audits.rb +2 -0
  32. data/lib/generators/audited/templates/add_request_uuid_to_audits.rb +2 -0
  33. data/lib/generators/audited/templates/add_version_to_auditable_index.rb +2 -0
  34. data/lib/generators/audited/templates/install.rb +2 -0
  35. data/lib/generators/audited/templates/rename_association_to_associated.rb +2 -0
  36. data/lib/generators/audited/templates/rename_changes_to_audited_changes.rb +2 -0
  37. data/lib/generators/audited/templates/rename_parent_to_association.rb +2 -0
  38. data/lib/generators/audited/templates/revert_polymorphic_indexes_order.rb +2 -0
  39. data/lib/generators/audited/upgrade_generator.rb +16 -14
  40. data/spec/audited/audit_spec.rb +70 -48
  41. data/spec/audited/auditor_spec.rb +477 -246
  42. data/spec/audited/sweeper_spec.rb +19 -18
  43. data/spec/audited_spec.rb +14 -0
  44. data/spec/audited_spec_helpers.rb +11 -7
  45. data/spec/rails_app/app/assets/config/manifest.js +2 -0
  46. data/spec/rails_app/config/application.rb +32 -3
  47. data/spec/rails_app/config/database.yml +3 -2
  48. data/spec/rails_app/config/environment.rb +1 -1
  49. data/spec/rails_app/config/environments/test.rb +10 -5
  50. data/spec/rails_app/config/initializers/secret_token.rb +2 -2
  51. data/spec/spec_helper.rb +14 -14
  52. data/spec/support/active_record/models.rb +62 -13
  53. data/spec/support/active_record/postgres/1_change_audited_changes_type_to_json.rb +1 -2
  54. data/spec/support/active_record/postgres/2_change_audited_changes_type_to_jsonb.rb +1 -2
  55. data/spec/support/active_record/schema.rb +26 -19
  56. data/test/db/version_1.rb +2 -2
  57. data/test/db/version_2.rb +2 -2
  58. data/test/db/version_3.rb +2 -3
  59. data/test/db/version_4.rb +2 -3
  60. data/test/db/version_5.rb +0 -1
  61. data/test/db/version_6.rb +1 -1
  62. data/test/install_generator_test.rb +18 -19
  63. data/test/test_helper.rb +5 -5
  64. data/test/upgrade_generator_test.rb +13 -18
  65. metadata +49 -31
  66. data/.rubocop.yml +0 -25
  67. data/.travis.yml +0 -58
  68. data/gemfiles/rails42.gemfile +0 -11
  69. data/spec/rails_app/app/controllers/application_controller.rb +0 -2
  70. data/spec/rails_app/config/environments/development.rb +0 -21
  71. data/spec/rails_app/config/environments/production.rb +0 -35
data/lib/audited-rspec.rb CHANGED
@@ -1,4 +1,6 @@
1
- require 'audited/rspec_matchers'
1
+ # frozen_string_literal: true
2
+
3
+ require "audited/rspec_matchers"
2
4
  module RSpec::Matchers
3
5
  include Audited::RspecMatchers
4
6
  end
data/lib/audited.rb CHANGED
@@ -1,16 +1,33 @@
1
- require 'active_record'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+ require "request_store"
2
5
 
3
6
  module Audited
4
7
  class << self
5
- attr_accessor :ignored_attributes, :current_user_method, :max_audits, :auditing_enabled
8
+ attr_accessor \
9
+ :auditing_enabled,
10
+ :current_user_method,
11
+ :ignored_attributes,
12
+ :ignored_default_callbacks,
13
+ :max_audits,
14
+ :store_synthesized_enums
6
15
  attr_writer :audit_class
7
16
 
8
17
  def audit_class
9
- @audit_class ||= Audit
18
+ # The audit_class is set as String in the initializer. It can not be constantized during initialization and must
19
+ # be constantized at runtime. See https://github.com/collectiveidea/audited/issues/608
20
+ @audit_class = @audit_class.safe_constantize if @audit_class.is_a?(String)
21
+ @audit_class ||= Audited::Audit
10
22
  end
11
23
 
24
+ # remove audit_model in next major version it was only shortly present in 5.1.0
25
+ alias_method :audit_model, :audit_class
26
+ deprecate audit_model: "use Audited.audit_class instead of Audited.audit_model. This method will be removed.",
27
+ deprecator: ActiveSupport::Deprecation.new('6.0.0', 'Audited')
28
+
12
29
  def store
13
- Thread.current[:audited_store] ||= {}
30
+ RequestStore.store[:audited_store] ||= {}
14
31
  end
15
32
 
16
33
  def config
@@ -18,15 +35,20 @@ module Audited
18
35
  end
19
36
  end
20
37
 
21
- @ignored_attributes = %w(lock_version created_at updated_at created_on updated_on)
38
+ @ignored_attributes = %w[lock_version created_at updated_at created_on updated_on]
39
+ @ignored_default_callbacks = []
22
40
 
23
41
  @current_user_method = :current_user
24
42
  @auditing_enabled = true
43
+ @store_synthesized_enums = false
25
44
  end
26
45
 
27
- require 'audited/auditor'
28
- require 'audited/audit'
46
+ require "audited/auditor"
29
47
 
30
- ::ActiveRecord::Base.send :include, Audited::Auditor
48
+ ActiveSupport.on_load :active_record do
49
+ require "audited/audit"
50
+ include Audited::Auditor
51
+ end
31
52
 
32
- require 'audited/sweeper'
53
+ require "audited/sweeper"
54
+ require "audited/railtie" if Audited.const_defined?(:Rails)
@@ -1,9 +1,11 @@
1
- require 'rails/generators'
2
- require 'rails/generators/migration'
3
- require 'active_record'
4
- require 'rails/generators/active_record'
5
- require 'generators/audited/migration'
6
- require 'generators/audited/migration_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "rails/generators/migration"
5
+ require "active_record"
6
+ require "rails/generators/active_record"
7
+ require "generators/audited/migration"
8
+ require "generators/audited/migration_helper"
7
9
 
8
10
  module Audited
9
11
  module Generators
@@ -18,7 +20,7 @@ module Audited
18
20
  source_root File.expand_path("../templates", __FILE__)
19
21
 
20
22
  def copy_migration
21
- migration_template 'install.rb', 'db/migrate/install_audited.rb'
23
+ migration_template "install.rb", "db/migrate/install_audited.rb"
22
24
  end
23
25
  end
24
26
  end
@@ -1,15 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Audited
2
4
  module Generators
3
5
  module Migration
4
6
  # Implement the required interface for Rails::Generators::Migration.
5
- def next_migration_number(dirname) #:nodoc:
7
+ def next_migration_number(dirname) # :nodoc:
6
8
  next_migration_number = current_migration_number(dirname) + 1
7
- if ::ActiveRecord::Base.timestamped_migrations
9
+ if timestamped_migrations?
8
10
  [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
9
11
  else
10
12
  "%.3d" % next_migration_number
11
13
  end
12
14
  end
15
+
16
+ private
17
+
18
+ def timestamped_migrations?
19
+ (Rails.gem_version >= Gem::Version.new("7.0")) ?
20
+ ::ActiveRecord.timestamped_migrations :
21
+ ::ActiveRecord::Base.timestamped_migrations
22
+ end
13
23
  end
14
24
  end
15
25
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Audited
2
4
  module Generators
3
5
  module MigrationHelper
4
6
  def migration_parent
5
- Rails::VERSION::MAJOR == 4 ? 'ActiveRecord::Migration' : "ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
7
+ "ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]"
6
8
  end
7
9
  end
8
10
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  add_column :audits, :association_id, :integer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  add_column :audits, :comment, :string
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  add_column :audits, :remote_address, :string
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  add_column :audits, :request_uuid, :string
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  if index_exists?(:audits, [:auditable_type, :auditable_id], name: index_name)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  create_table :audits, :force => true do |t|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  if index_exists? :audits, [:association_id, :association_type], :name => 'association_index'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  rename_column :audits, :changes, :audited_changes
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  rename_column :audits, :auditable_parent_id, :association_id
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class <%= migration_class_name %> < <%= migration_parent %>
2
4
  def self.up
3
5
  fix_index_order_for [:associated_id, :associated_type], 'associated_index'
@@ -1,9 +1,11 @@
1
- require 'rails/generators'
2
- require 'rails/generators/migration'
3
- require 'active_record'
4
- require 'rails/generators/active_record'
5
- require 'generators/audited/migration'
6
- require 'generators/audited/migration_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "rails/generators/migration"
5
+ require "active_record"
6
+ require "rails/generators/active_record"
7
+ require "generators/audited/migration"
8
+ require "generators/audited/migration_helper"
7
9
 
8
10
  module Audited
9
11
  module Generators
@@ -27,31 +29,31 @@ module Audited
27
29
  columns = Audited::Audit.columns.map(&:name)
28
30
  indexes = Audited::Audit.connection.indexes(Audited::Audit.table_name)
29
31
 
30
- yield :add_comment_to_audits unless columns.include?('comment')
32
+ yield :add_comment_to_audits unless columns.include?("comment")
31
33
 
32
- if columns.include?('changes')
34
+ if columns.include?("changes")
33
35
  yield :rename_changes_to_audited_changes
34
36
  end
35
37
 
36
- unless columns.include?('remote_address')
38
+ unless columns.include?("remote_address")
37
39
  yield :add_remote_address_to_audits
38
40
  end
39
41
 
40
- unless columns.include?('request_uuid')
42
+ unless columns.include?("request_uuid")
41
43
  yield :add_request_uuid_to_audits
42
44
  end
43
45
 
44
- unless columns.include?('association_id')
45
- if columns.include?('auditable_parent_id')
46
+ unless columns.include?("association_id")
47
+ if columns.include?("auditable_parent_id")
46
48
  yield :rename_parent_to_association
47
49
  else
48
- unless columns.include?('associated_id')
50
+ unless columns.include?("associated_id")
49
51
  yield :add_association_to_audits
50
52
  end
51
53
  end
52
54
  end
53
55
 
54
- if columns.include?('association_id')
56
+ if columns.include?("association_id")
55
57
  yield :rename_association_to_associated
56
58
  end
57
59
 
@@ -1,6 +1,27 @@
1
1
  require "spec_helper"
2
2
 
3
- SingleCov.covered!
3
+ SingleCov.covered! uncovered: 2 # Rails version check
4
+
5
+ class CustomAudit < Audited::Audit
6
+ def custom_method
7
+ "I'm custom!"
8
+ end
9
+ end
10
+
11
+ class TempModel1 < ::ActiveRecord::Base
12
+ self.table_name = :companies
13
+ end
14
+
15
+ class TempModel2 < ::ActiveRecord::Base
16
+ self.table_name = :companies
17
+ end
18
+
19
+ class Models::ActiveRecord::CustomUser < ::ActiveRecord::Base
20
+ end
21
+
22
+ class Models::ActiveRecord::CustomUserSubclass < Models::ActiveRecord::CustomUser
23
+ audited
24
+ end
4
25
 
5
26
  describe Audited::Audit do
6
27
  let(:user) { Models::ActiveRecord::User.new name: "Testing" }
@@ -9,30 +30,17 @@ describe Audited::Audit do
9
30
  around(:example) do |example|
10
31
  original_audit_class = Audited.audit_class
11
32
 
12
- class CustomAudit < Audited::Audit
13
- def custom_method
14
- "I'm custom!"
15
- end
16
- end
17
-
18
- class TempModel < ::ActiveRecord::Base
19
- self.table_name = :companies
20
- end
21
-
22
33
  example.run
23
34
 
24
35
  Audited.config { |config| config.audit_class = original_audit_class }
25
- Audited::Audit.audited_class_names.delete("TempModel")
26
- Object.send(:remove_const, :TempModel)
27
- Object.send(:remove_const, :CustomAudit)
28
36
  end
29
37
 
30
38
  context "when a custom audit class is configured" do
31
39
  it "should be used in place of #{described_class}" do
32
- Audited.config { |config| config.audit_class = CustomAudit }
33
- TempModel.audited
40
+ Audited.config { |config| config.audit_class = "CustomAudit" }
41
+ TempModel1.audited
34
42
 
35
- record = TempModel.create
43
+ record = TempModel1.create
36
44
 
37
45
  audit = record.audits.first
38
46
  expect(audit).to be_a CustomAudit
@@ -42,9 +50,9 @@ describe Audited::Audit do
42
50
 
43
51
  context "when a custom audit class is not configured" do
44
52
  it "should default to #{described_class}" do
45
- TempModel.audited
53
+ TempModel2.audited
46
54
 
47
- record = TempModel.create
55
+ record = TempModel2.create
48
56
 
49
57
  audit = record.audits.first
50
58
  expect(audit).to be_a Audited::Audit
@@ -62,7 +70,7 @@ describe Audited::Audit do
62
70
  end
63
71
 
64
72
  it "does not unserialize from binary columns" do
65
- allow(Audited.audit_class.columns_hash["audited_changes"]).to receive(:type).and_return("foo")
73
+ allow(Audited::YAMLIfTextColumnType).to receive(:text_column?).and_return(false)
66
74
  audit.audited_changes = {foo: "bar"}
67
75
  expect(audit.audited_changes).to eq "{:foo=>\"bar\"}"
68
76
  end
@@ -72,7 +80,7 @@ describe Audited::Audit do
72
80
  let(:user) { Models::ActiveRecord::User.create(name: "John") }
73
81
 
74
82
  it "undos changes" do
75
- user.update_attribute(:name, 'Joe')
83
+ user.update_attribute(:name, "Joe")
76
84
  user.audits.last.undo
77
85
  user.reload
78
86
  expect(user.name).to eq("John")
@@ -87,12 +95,12 @@ describe Audited::Audit do
87
95
 
88
96
  it "undos creation" do
89
97
  user # trigger create
90
- expect {user.audits.last.undo}.to change(Models::ActiveRecord::User, :count).by(-1)
98
+ expect { user.audits.last.undo }.to change(Models::ActiveRecord::User, :count).by(-1)
91
99
  end
92
100
 
93
101
  it "fails when trying to undo unknown" do
94
102
  audit = user.audits.last
95
- audit.action = 'oops'
103
+ audit.action = "oops"
96
104
  expect { audit.undo }.to raise_error("invalid action given oops")
97
105
  end
98
106
  end
@@ -105,8 +113,8 @@ describe Audited::Audit do
105
113
 
106
114
  it "should be able to set the user to nil" do
107
115
  subject.user_id = 1
108
- subject.user_type = 'Models::ActiveRecord::User'
109
- subject.username = 'joe'
116
+ subject.user_type = "Models::ActiveRecord::User"
117
+ subject.username = "joe"
110
118
 
111
119
  subject.user = nil
112
120
 
@@ -117,19 +125,19 @@ describe Audited::Audit do
117
125
  end
118
126
 
119
127
  it "should be able to set the user to a string" do
120
- subject.user = 'test'
121
- expect(subject.user).to eq('test')
128
+ subject.user = "test"
129
+ expect(subject.user).to eq("test")
122
130
  end
123
131
 
124
132
  it "should clear model when setting to a string" do
125
133
  subject.user = user
126
- subject.user = 'testing'
134
+ subject.user = "testing"
127
135
  expect(subject.user_id).to be_nil
128
136
  expect(subject.user_type).to be_nil
129
137
  end
130
138
 
131
139
  it "should clear the username when setting to a model" do
132
- subject.username = 'test'
140
+ subject.username = "test"
133
141
  subject.user = user
134
142
  expect(subject.username).to be_nil
135
143
  end
@@ -138,7 +146,7 @@ describe Audited::Audit do
138
146
  describe "revision" do
139
147
  it "should recreate attributes" do
140
148
  user = Models::ActiveRecord::User.create name: "1"
141
- 5.times {|i| user.update_attribute :name, (i + 2).to_s }
149
+ 5.times { |i| user.update_attribute :name, (i + 2).to_s }
142
150
 
143
151
  user.audits.each do |audit|
144
152
  expect(audit.revision.name).to eq(audit.version.to_s)
@@ -174,7 +182,7 @@ describe Audited::Audit do
174
182
  it "uses created at" do
175
183
  Audited::Audit.delete_all
176
184
  audit = Models::ActiveRecord::User.create(name: "John").audits.last
177
- audit.update_columns(created_at: Time.parse('2018-01-01'))
185
+ audit.update_columns(created_at: Time.zone.parse("2018-01-01"))
178
186
  expect(Audited::Audit.collection_cache_key).to match(/-20180101\d+$/)
179
187
  end
180
188
  else
@@ -220,12 +228,6 @@ describe Audited::Audit do
220
228
  end
221
229
 
222
230
  describe "audited_classes" do
223
- class Models::ActiveRecord::CustomUser < ::ActiveRecord::Base
224
- end
225
- class Models::ActiveRecord::CustomUserSubclass < Models::ActiveRecord::CustomUser
226
- audited
227
- end
228
-
229
231
  it "should include audited classes" do
230
232
  expect(Audited::Audit.audited_classes).to include(Models::ActiveRecord::User)
231
233
  end
@@ -236,17 +238,37 @@ describe Audited::Audit do
236
238
  end
237
239
 
238
240
  describe "new_attributes" do
239
- it "should return a hash of the new values" do
240
- new_attributes = Audited::Audit.new(audited_changes: {a: [1, 2], b: [3, 4]}).new_attributes
241
+ it "should return the audited_changes without modification for create" do
242
+ new_attributes = Audited::Audit.new(audited_changes: {int: 1, array: [1]}, action: :create).new_attributes
243
+ expect(new_attributes).to eq({"int" => 1, "array" => [1]})
244
+ end
245
+
246
+ it "should return a hash that contains the after values of each attribute" do
247
+ new_attributes = Audited::Audit.new(audited_changes: {a: [1, 2], b: [3, 4]}, action: :update).new_attributes
241
248
  expect(new_attributes).to eq({"a" => 2, "b" => 4})
242
249
  end
250
+
251
+ it "should return the audited_changes without modification for destroy" do
252
+ new_attributes = Audited::Audit.new(audited_changes: {int: 1, array: [1]}, action: :destroy).new_attributes
253
+ expect(new_attributes).to eq({"int" => 1, "array" => [1]})
254
+ end
243
255
  end
244
256
 
245
257
  describe "old_attributes" do
246
- it "should return a hash of the old values" do
247
- old_attributes = Audited::Audit.new(audited_changes: {a: [1, 2], b: [3, 4]}).old_attributes
258
+ it "should return the audited_changes without modification for create" do
259
+ old_attributes = Audited::Audit.new(audited_changes: {int: 1, array: [1]}, action: :create).new_attributes
260
+ expect(old_attributes).to eq({"int" => 1, "array" => [1]})
261
+ end
262
+
263
+ it "should return a hash that contains the before values of each attribute" do
264
+ old_attributes = Audited::Audit.new(audited_changes: {a: [1, 2], b: [3, 4]}, action: :update).old_attributes
248
265
  expect(old_attributes).to eq({"a" => 1, "b" => 3})
249
266
  end
267
+
268
+ it "should return the audited_changes without modification for destroy" do
269
+ old_attributes = Audited::Audit.new(audited_changes: {int: 1, array: [1]}, action: :destroy).old_attributes
270
+ expect(old_attributes).to eq({"int" => 1, "array" => [1]})
271
+ end
250
272
  end
251
273
 
252
274
  describe "as_user" do
@@ -293,8 +315,8 @@ describe Audited::Audit do
293
315
  end
294
316
  end
295
317
 
296
- it "should be thread safe" do
297
- begin
318
+ if ActiveRecord::Base.connection.adapter_name != "SQLite"
319
+ it "should be thread safe" do
298
320
  expect(user.save).to eq(true)
299
321
 
300
322
  t1 = Thread.new do
@@ -314,10 +336,10 @@ describe Audited::Audit do
314
336
  t1.join
315
337
  t2.join
316
338
  end
317
- end if ActiveRecord::Base.connection.adapter_name != 'SQLite'
339
+ end
318
340
 
319
341
  it "should return the value from the yield block" do
320
- result = Audited::Audit.as_user('foo') do
342
+ result = Audited::Audit.as_user("foo") do
321
343
  42
322
344
  end
323
345
  expect(result).to eq(42)
@@ -325,10 +347,10 @@ describe Audited::Audit do
325
347
 
326
348
  it "should reset audited_user when the yield block raises an exception" do
327
349
  expect {
328
- Audited::Audit.as_user('foo') do
329
- raise StandardError.new('expected')
350
+ Audited::Audit.as_user("foo") do
351
+ raise StandardError.new("expected")
330
352
  end
331
- }.to raise_exception('expected')
353
+ }.to raise_exception("expected")
332
354
  expect(Audited.store[:audited_user]).to be_nil
333
355
  end
334
356
  end