audited 4.8.0 → 4.9.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.
- checksums.yaml +5 -5
- data/.gitignore +0 -1
- data/.rubocop.yml +25 -0
- data/.travis.yml +27 -27
- data/Appraisals +21 -11
- data/CHANGELOG.md +34 -3
- data/README.md +52 -17
- data/gemfiles/rails42.gemfile +3 -0
- data/gemfiles/rails50.gemfile +3 -0
- data/gemfiles/rails51.gemfile +3 -0
- data/gemfiles/rails52.gemfile +3 -1
- data/gemfiles/rails60.gemfile +10 -0
- data/lib/audited/audit.rb +8 -10
- data/lib/audited/auditor.rb +60 -23
- data/lib/audited/version.rb +1 -1
- data/spec/audited/audit_spec.rb +69 -21
- data/spec/audited/auditor_spec.rb +127 -32
- data/spec/audited/sweeper_spec.rb +13 -5
- data/spec/rails_app/app/controllers/application_controller.rb +2 -0
- data/spec/rails_app/config/database.yml +1 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/support/active_record/models.rb +6 -0
- data/spec/support/active_record/schema.rb +3 -2
- metadata +53 -19
- data/gemfiles/rails40.gemfile +0 -9
- data/gemfiles/rails41.gemfile +0 -8
data/lib/audited/audit.rb
CHANGED
@@ -97,7 +97,7 @@ module Audited
|
|
97
97
|
auditable_type.constantize.create!(audited_changes)
|
98
98
|
when 'update'
|
99
99
|
# changes back attributes
|
100
|
-
auditable.
|
100
|
+
auditable.update!(audited_changes.transform_values(&:first))
|
101
101
|
else
|
102
102
|
raise StandardError, "invalid action given #{action}"
|
103
103
|
end
|
@@ -130,7 +130,7 @@ module Audited
|
|
130
130
|
# All audits made during the block called will be recorded as made
|
131
131
|
# by +user+. This method is hopefully threadsafe, making it ideal
|
132
132
|
# for background operations that require audit information.
|
133
|
-
def self.as_user(user
|
133
|
+
def self.as_user(user)
|
134
134
|
last_audited_user = ::Audited.store[:audited_user]
|
135
135
|
::Audited.store[:audited_user] = user
|
136
136
|
yield
|
@@ -140,13 +140,11 @@ module Audited
|
|
140
140
|
|
141
141
|
# @private
|
142
142
|
def self.reconstruct_attributes(audits)
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
block_given? ? result : attributes
|
149
|
-
end
|
143
|
+
audits.each_with_object({}) do |audit, all|
|
144
|
+
all.merge!(audit.new_attributes)
|
145
|
+
all[:audit_version] = audit.version
|
146
|
+
end
|
147
|
+
end
|
150
148
|
|
151
149
|
# @private
|
152
150
|
def self.assign_revision_attributes(record, attributes)
|
@@ -163,7 +161,7 @@ module Audited
|
|
163
161
|
end
|
164
162
|
|
165
163
|
# use created_at as timestamp cache key
|
166
|
-
def self.collection_cache_key(collection = all,
|
164
|
+
def self.collection_cache_key(collection = all, *)
|
167
165
|
super(collection, :created_at)
|
168
166
|
end
|
169
167
|
|
data/lib/audited/auditor.rb
CHANGED
@@ -115,6 +115,21 @@ module Audited
|
|
115
115
|
self.class.without_auditing(&block)
|
116
116
|
end
|
117
117
|
|
118
|
+
# Temporarily turns on auditing while saving.
|
119
|
+
def save_with_auditing
|
120
|
+
with_auditing { save }
|
121
|
+
end
|
122
|
+
|
123
|
+
# Executes the block with the auditing callbacks enabled.
|
124
|
+
#
|
125
|
+
# @foo.with_auditing do
|
126
|
+
# @foo.save
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
def with_auditing(&block)
|
130
|
+
self.class.with_auditing(&block)
|
131
|
+
end
|
132
|
+
|
118
133
|
# Gets an array of the revisions available
|
119
134
|
#
|
120
135
|
# user.revisions.each do |revision|
|
@@ -152,7 +167,8 @@ module Audited
|
|
152
167
|
|
153
168
|
# List of attributes that are audited.
|
154
169
|
def audited_attributes
|
155
|
-
attributes.except(*non_audited_columns)
|
170
|
+
audited_attributes = attributes.except(*self.class.non_audited_columns)
|
171
|
+
normalize_enum_changes(audited_attributes)
|
156
172
|
end
|
157
173
|
|
158
174
|
# Returns a list combined of record audits and associated audits.
|
@@ -177,18 +193,9 @@ module Audited
|
|
177
193
|
|
178
194
|
protected
|
179
195
|
|
180
|
-
def non_audited_columns
|
181
|
-
self.class.non_audited_columns
|
182
|
-
end
|
183
|
-
|
184
|
-
def audited_columns
|
185
|
-
self.class.audited_columns
|
186
|
-
end
|
187
|
-
|
188
196
|
def revision_with(attributes)
|
189
197
|
dup.tap do |revision|
|
190
198
|
revision.id = id
|
191
|
-
revision.send :instance_variable_set, '@attributes', self.attributes if rails_below?('4.2.0')
|
192
199
|
revision.send :instance_variable_set, '@new_record', destroyed?
|
193
200
|
revision.send :instance_variable_set, '@persisted', !destroyed?
|
194
201
|
revision.send :instance_variable_set, '@readonly', false
|
@@ -211,19 +218,39 @@ module Audited
|
|
211
218
|
end
|
212
219
|
end
|
213
220
|
|
214
|
-
def rails_below?(rails_version)
|
215
|
-
Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new(rails_version)
|
216
|
-
end
|
217
|
-
|
218
221
|
private
|
219
222
|
|
220
223
|
def audited_changes
|
221
224
|
all_changes = respond_to?(:changes_to_save) ? changes_to_save : changes
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
225
|
+
filtered_changes = \
|
226
|
+
if audited_options[:only].present?
|
227
|
+
all_changes.slice(*self.class.audited_columns)
|
228
|
+
else
|
229
|
+
all_changes.except(*self.class.non_audited_columns)
|
230
|
+
end
|
231
|
+
|
232
|
+
filtered_changes = normalize_enum_changes(filtered_changes)
|
233
|
+
filtered_changes.to_hash
|
234
|
+
end
|
235
|
+
|
236
|
+
def normalize_enum_changes(changes)
|
237
|
+
self.class.defined_enums.each do |name, values|
|
238
|
+
if changes.has_key?(name)
|
239
|
+
changes[name] = \
|
240
|
+
if changes[name].is_a?(Array)
|
241
|
+
changes[name].map { |v| values[v] }
|
242
|
+
elsif rails_below?('5.0')
|
243
|
+
changes[name]
|
244
|
+
else
|
245
|
+
values[changes[name]]
|
246
|
+
end
|
247
|
+
end
|
226
248
|
end
|
249
|
+
changes
|
250
|
+
end
|
251
|
+
|
252
|
+
def rails_below?(rails_version)
|
253
|
+
Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new(rails_version)
|
227
254
|
end
|
228
255
|
|
229
256
|
def audits_to(version = nil)
|
@@ -244,7 +271,7 @@ module Audited
|
|
244
271
|
end
|
245
272
|
|
246
273
|
def audit_update
|
247
|
-
unless (changes = audited_changes).empty? && audit_comment.blank?
|
274
|
+
unless (changes = audited_changes).empty? && (audit_comment.blank? || audited_options[:update_with_comment_only] == false)
|
248
275
|
write_audit(action: 'update', audited_changes: changes,
|
249
276
|
comment: audit_comment)
|
250
277
|
end
|
@@ -314,10 +341,6 @@ module Audited
|
|
314
341
|
true
|
315
342
|
end
|
316
343
|
|
317
|
-
def auditing_enabled=(val)
|
318
|
-
self.class.auditing_enabled = val
|
319
|
-
end
|
320
|
-
|
321
344
|
def reconstruct_attributes(audits)
|
322
345
|
attributes = {}
|
323
346
|
audits.each { |audit| attributes.merge!(audit.new_attributes) }
|
@@ -355,6 +378,20 @@ module Audited
|
|
355
378
|
enable_auditing if auditing_was_enabled
|
356
379
|
end
|
357
380
|
|
381
|
+
# Executes the block with auditing enabled.
|
382
|
+
#
|
383
|
+
# Foo.with_auditing do
|
384
|
+
# @foo.save
|
385
|
+
# end
|
386
|
+
#
|
387
|
+
def with_auditing
|
388
|
+
auditing_was_enabled = auditing_enabled
|
389
|
+
enable_auditing
|
390
|
+
yield
|
391
|
+
ensure
|
392
|
+
disable_auditing unless auditing_was_enabled
|
393
|
+
end
|
394
|
+
|
358
395
|
def disable_auditing
|
359
396
|
self.auditing_enabled = false
|
360
397
|
end
|
data/lib/audited/version.rb
CHANGED
data/spec/audited/audit_spec.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
+
SingleCov.covered!
|
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
|
-
|
42
|
-
|
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.audit_class.columns_hash["audited_changes"]).to receive(:type).and_return("foo")
|
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 "
|
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 "
|
59
|
-
user
|
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
|
-
|
64
|
-
|
65
|
-
|
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.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)
|
@@ -282,6 +331,5 @@ describe Audited::Audit do
|
|
282
331
|
}.to raise_exception('expected')
|
283
332
|
expect(Audited.store[:audited_user]).to be_nil
|
284
333
|
end
|
285
|
-
|
286
334
|
end
|
287
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
|
@@ -210,7 +212,7 @@ describe Audited::Auditor do
|
|
210
212
|
expect(user.audits.last.audited_changes.keys).to eq(%w{non_column_attr})
|
211
213
|
end
|
212
214
|
|
213
|
-
if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
215
|
+
if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
214
216
|
describe "'json' and 'jsonb' audited_changes column type" do
|
215
217
|
let(:migrations_path) { SPEC_ROOT.join("support/active_record/postgres") }
|
216
218
|
|
@@ -264,7 +266,7 @@ describe Audited::Auditor do
|
|
264
266
|
end
|
265
267
|
|
266
268
|
describe "on create" do
|
267
|
-
let( :user ) { create_user audit_comment: "Create" }
|
269
|
+
let( :user ) { create_user status: :reliable, audit_comment: "Create" }
|
268
270
|
|
269
271
|
it "should change the audit count" do
|
270
272
|
expect {
|
@@ -288,6 +290,10 @@ describe Audited::Auditor do
|
|
288
290
|
expect(user.audits.first.audited_changes).to eq(user.audited_attributes)
|
289
291
|
end
|
290
292
|
|
293
|
+
it "should store enum value" do
|
294
|
+
expect(user.audits.first.audited_changes["status"]).to eq(1)
|
295
|
+
end
|
296
|
+
|
291
297
|
it "should store comment" do
|
292
298
|
expect(user.audits.first.comment).to eq('Create')
|
293
299
|
end
|
@@ -306,7 +312,7 @@ describe Audited::Auditor do
|
|
306
312
|
|
307
313
|
describe "on update" do
|
308
314
|
before do
|
309
|
-
@user = create_user( name: 'Brandon', audit_comment: 'Update' )
|
315
|
+
@user = create_user( name: 'Brandon', status: :active, audit_comment: 'Update' )
|
310
316
|
end
|
311
317
|
|
312
318
|
it "should save an audit" do
|
@@ -319,17 +325,22 @@ describe Audited::Auditor do
|
|
319
325
|
end
|
320
326
|
|
321
327
|
it "should set the action to 'update'" do
|
322
|
-
@user.
|
328
|
+
@user.update! name: 'Changed'
|
323
329
|
expect(@user.audits.last.action).to eq('update')
|
324
330
|
expect(Audited::Audit.updates.order(:id).last).to eq(@user.audits.last)
|
325
331
|
expect(@user.audits.updates.last).to eq(@user.audits.last)
|
326
332
|
end
|
327
333
|
|
328
334
|
it "should store the changed attributes" do
|
329
|
-
@user.
|
335
|
+
@user.update! name: 'Changed'
|
330
336
|
expect(@user.audits.last.audited_changes).to eq({ 'name' => ['Brandon', 'Changed'] })
|
331
337
|
end
|
332
338
|
|
339
|
+
it "should store changed enum values" do
|
340
|
+
@user.update! status: 1
|
341
|
+
expect(@user.audits.last.audited_changes["status"]).to eq([0, 1])
|
342
|
+
end
|
343
|
+
|
333
344
|
it "should store audit comment" do
|
334
345
|
expect(@user.audits.last.comment).to eq('Update')
|
335
346
|
end
|
@@ -337,12 +348,12 @@ describe Audited::Auditor do
|
|
337
348
|
it "should not save an audit if only specified on create/destroy" do
|
338
349
|
on_create_destroy = Models::ActiveRecord::OnCreateDestroy.create( name: 'Bart' )
|
339
350
|
expect {
|
340
|
-
on_create_destroy.
|
351
|
+
on_create_destroy.update! name: 'Changed'
|
341
352
|
}.to_not change( Audited::Audit, :count )
|
342
353
|
end
|
343
354
|
|
344
355
|
it "should not save an audit if the value doesn't change after type casting" do
|
345
|
-
@user.
|
356
|
+
@user.update! logins: 0, activated: true
|
346
357
|
expect { @user.update_attribute :logins, '0' }.to_not change( Audited::Audit, :count )
|
347
358
|
expect { @user.update_attribute :activated, 1 }.to_not change( Audited::Audit, :count )
|
348
359
|
expect { @user.update_attribute :activated, '1' }.to_not change( Audited::Audit, :count )
|
@@ -366,7 +377,7 @@ describe Audited::Auditor do
|
|
366
377
|
|
367
378
|
describe "on destroy" do
|
368
379
|
before do
|
369
|
-
@user = create_user
|
380
|
+
@user = create_user(status: :active)
|
370
381
|
end
|
371
382
|
|
372
383
|
it "should save an audit" do
|
@@ -391,6 +402,11 @@ describe Audited::Auditor do
|
|
391
402
|
expect(@user.audits.last.audited_changes).to eq(@user.audited_attributes)
|
392
403
|
end
|
393
404
|
|
405
|
+
it "should store enum value" do
|
406
|
+
@user.destroy
|
407
|
+
expect(@user.audits.last.audited_changes["status"]).to eq(0)
|
408
|
+
end
|
409
|
+
|
394
410
|
it "should be able to reconstruct a destroyed record without history" do
|
395
411
|
@user.audits.delete_all
|
396
412
|
@user.destroy
|
@@ -492,13 +508,13 @@ describe Audited::Auditor do
|
|
492
508
|
it "should delete old extra audits after introducing limit" do
|
493
509
|
stub_global_max_audits(nil) do
|
494
510
|
user = Models::ActiveRecord::User.create!(name: 'Brandon', username: 'brandon')
|
495
|
-
user.
|
496
|
-
user.
|
497
|
-
user.
|
511
|
+
user.update!(name: 'Foobar')
|
512
|
+
user.update!(name: 'Awesome', username: 'keepers')
|
513
|
+
user.update!(activated: true)
|
498
514
|
|
499
515
|
Audited.max_audits = 3
|
500
516
|
Models::ActiveRecord::User.send(:normalize_audited_options)
|
501
|
-
user.
|
517
|
+
user.update!(favourite_device: 'Android Phone')
|
502
518
|
audits = user.audits
|
503
519
|
|
504
520
|
expect(audits.count).to eq(3)
|
@@ -549,8 +565,8 @@ describe Audited::Auditor do
|
|
549
565
|
|
550
566
|
it "should set the attributes for each revision" do
|
551
567
|
u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
|
552
|
-
u.
|
553
|
-
u.
|
568
|
+
u.update! name: 'Foobar'
|
569
|
+
u.update! name: 'Awesome', username: 'keepers'
|
554
570
|
|
555
571
|
expect(u.revisions.size).to eql(3)
|
556
572
|
|
@@ -566,8 +582,8 @@ describe Audited::Auditor do
|
|
566
582
|
|
567
583
|
it "access to only recent revisions" do
|
568
584
|
u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
|
569
|
-
u.
|
570
|
-
u.
|
585
|
+
u.update! name: 'Foobar'
|
586
|
+
u.update! name: 'Awesome', username: 'keepers'
|
571
587
|
|
572
588
|
expect(u.revisions(2).size).to eq(2)
|
573
589
|
|
@@ -584,7 +600,7 @@ describe Audited::Auditor do
|
|
584
600
|
end
|
585
601
|
|
586
602
|
it "should ignore attributes that have been deleted" do
|
587
|
-
user.audits.last.
|
603
|
+
user.audits.last.update! audited_changes: {old_attribute: 'old value'}
|
588
604
|
expect { user.revisions }.to_not raise_error
|
589
605
|
end
|
590
606
|
end
|
@@ -633,8 +649,8 @@ describe Audited::Auditor do
|
|
633
649
|
|
634
650
|
it "should set the attributes for each revision" do
|
635
651
|
u = Models::ActiveRecord::User.create(name: 'Brandon', username: 'brandon')
|
636
|
-
u.
|
637
|
-
u.
|
652
|
+
u.update! name: 'Foobar'
|
653
|
+
u.update! name: 'Awesome', username: 'keepers'
|
638
654
|
|
639
655
|
expect(u.revision(3).name).to eq('Awesome')
|
640
656
|
expect(u.revision(3).username).to eq('keepers')
|
@@ -646,6 +662,16 @@ describe Audited::Auditor do
|
|
646
662
|
expect(u.revision(1).username).to eq('brandon')
|
647
663
|
end
|
648
664
|
|
665
|
+
it "should correctly restore revision with enum" do
|
666
|
+
u = Models::ActiveRecord::User.create(status: :active)
|
667
|
+
u.update_attribute(:status, :reliable)
|
668
|
+
u.update_attribute(:status, :banned)
|
669
|
+
|
670
|
+
expect(u.revision(3)).to be_banned
|
671
|
+
expect(u.revision(2)).to be_reliable
|
672
|
+
expect(u.revision(1)).to be_active
|
673
|
+
end
|
674
|
+
|
649
675
|
it "should be able to get time for first revision" do
|
650
676
|
suspended_at = Time.zone.now
|
651
677
|
u = Models::ActiveRecord::User.create(suspended_at: suspended_at)
|
@@ -686,7 +712,7 @@ describe Audited::Auditor do
|
|
686
712
|
audit = user.audits.first
|
687
713
|
audit.created_at = 1.hour.ago
|
688
714
|
audit.save!
|
689
|
-
user.
|
715
|
+
user.update! name: 'updated'
|
690
716
|
expect(user.revision_at( 2.minutes.ago ).audit_version).to eq(1)
|
691
717
|
end
|
692
718
|
|
@@ -702,7 +728,7 @@ describe Audited::Auditor do
|
|
702
728
|
company.update!(name: "Collective Idea")
|
703
729
|
|
704
730
|
other_owner = Models::ActiveRecord::Owner.create!
|
705
|
-
|
731
|
+
other_owner.companies.create!
|
706
732
|
|
707
733
|
expect(owner.own_and_associated_audits).to match_array(owner.audits + company.audits)
|
708
734
|
end
|
@@ -778,8 +804,67 @@ describe Audited::Auditor do
|
|
778
804
|
Audited.auditing_enabled = true
|
779
805
|
expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
|
780
806
|
|
781
|
-
user.
|
807
|
+
user.update!(name: 'Test')
|
782
808
|
expect(user.audits.count).to eq(1)
|
809
|
+
Models::ActiveRecord::User.enable_auditing
|
810
|
+
end
|
811
|
+
end
|
812
|
+
|
813
|
+
describe "with auditing" do
|
814
|
+
it "should save an audit when calling #save_with_auditing" do
|
815
|
+
expect {
|
816
|
+
u = Models::ActiveRecord::User.new(name: 'Brandon')
|
817
|
+
Models::ActiveRecord::User.auditing_enabled = false
|
818
|
+
expect(u.save_with_auditing).to eq(true)
|
819
|
+
Models::ActiveRecord::User.auditing_enabled = true
|
820
|
+
}.to change( Audited::Audit, :count ).by(1)
|
821
|
+
end
|
822
|
+
|
823
|
+
it "should save an audit inside of the #with_auditing block" do
|
824
|
+
expect {
|
825
|
+
Models::ActiveRecord::User.auditing_enabled = false
|
826
|
+
Models::ActiveRecord::User.with_auditing { Models::ActiveRecord::User.create!( name: 'Brandon' ) }
|
827
|
+
Models::ActiveRecord::User.auditing_enabled = true
|
828
|
+
}.to change( Audited::Audit, :count ).by(1)
|
829
|
+
end
|
830
|
+
|
831
|
+
it "should reset auditing status even it raises an exception" do
|
832
|
+
Models::ActiveRecord::User.disable_auditing
|
833
|
+
Models::ActiveRecord::User.with_auditing { raise } rescue nil
|
834
|
+
expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
|
835
|
+
Models::ActiveRecord::User.enable_auditing
|
836
|
+
end
|
837
|
+
|
838
|
+
it "should be thread safe using a #with_auditing block" do
|
839
|
+
skip if Models::ActiveRecord::User.connection.class.name.include?("SQLite")
|
840
|
+
|
841
|
+
t1 = Thread.new do
|
842
|
+
Models::ActiveRecord::User.disable_auditing
|
843
|
+
expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
|
844
|
+
Models::ActiveRecord::User.with_auditing do
|
845
|
+
expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
|
846
|
+
|
847
|
+
Models::ActiveRecord::User.create!( name: 'Shaggy' )
|
848
|
+
sleep 1
|
849
|
+
expect(Models::ActiveRecord::User.auditing_enabled).to eq(true)
|
850
|
+
end
|
851
|
+
expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
|
852
|
+
Models::ActiveRecord::User.enable_auditing
|
853
|
+
end
|
854
|
+
|
855
|
+
t2 = Thread.new do
|
856
|
+
sleep 0.5
|
857
|
+
Models::ActiveRecord::User.disable_auditing
|
858
|
+
expect(Models::ActiveRecord::User.auditing_enabled).to eq(false)
|
859
|
+
Models::ActiveRecord::User.create!( name: 'Scooby' )
|
860
|
+
Models::ActiveRecord::User.enable_auditing
|
861
|
+
end
|
862
|
+
t1.join
|
863
|
+
t2.join
|
864
|
+
|
865
|
+
Models::ActiveRecord::User.enable_auditing
|
866
|
+
expect(Models::ActiveRecord::User.find_by_name('Shaggy').audits.count).to eq(1)
|
867
|
+
expect(Models::ActiveRecord::User.find_by_name('Scooby').audits.count).to eq(0)
|
783
868
|
end
|
784
869
|
end
|
785
870
|
|
@@ -816,21 +901,21 @@ describe Audited::Auditor do
|
|
816
901
|
let( :on_destroy_user ) { Models::ActiveRecord::OnDestroyCommentRequiredUser.create }
|
817
902
|
|
818
903
|
it "should not validate when audit_comment is not supplied" do
|
819
|
-
expect(user.
|
904
|
+
expect(user.update(name: 'Test')).to eq(false)
|
820
905
|
end
|
821
906
|
|
822
907
|
it "should validate when audit_comment is not supplied, and updating is not being audited" do
|
823
|
-
expect(on_create_user.
|
824
|
-
expect(on_destroy_user.
|
908
|
+
expect(on_create_user.update(name: 'Test')).to eq(true)
|
909
|
+
expect(on_destroy_user.update(name: 'Test')).to eq(true)
|
825
910
|
end
|
826
911
|
|
827
912
|
it "should validate when audit_comment is supplied" do
|
828
|
-
expect(user.
|
913
|
+
expect(user.update(name: 'Test', audit_comment: 'Update')).to eq(true)
|
829
914
|
end
|
830
915
|
|
831
916
|
it "should validate when audit_comment is not supplied, and auditing is disabled" do
|
832
917
|
Models::ActiveRecord::CommentRequiredUser.disable_auditing
|
833
|
-
expect(user.
|
918
|
+
expect(user.update(name: 'Test')).to eq(true)
|
834
919
|
Models::ActiveRecord::CommentRequiredUser.enable_auditing
|
835
920
|
end
|
836
921
|
end
|
@@ -863,6 +948,16 @@ describe Audited::Auditor do
|
|
863
948
|
|
864
949
|
end
|
865
950
|
|
951
|
+
describe "no update with comment only" do
|
952
|
+
let( :user ) { Models::ActiveRecord::NoUpdateWithCommentOnlyUser.create }
|
953
|
+
|
954
|
+
it "does not create an audit when only an audit_comment is present" do
|
955
|
+
user.audit_comment = "Comment"
|
956
|
+
expect { user.save! }.to_not change( Audited::Audit, :count )
|
957
|
+
end
|
958
|
+
|
959
|
+
end
|
960
|
+
|
866
961
|
describe "attr_protected and attr_accessible" do
|
867
962
|
|
868
963
|
it "should not raise error when attr_accessible is set and protected is false" do
|
@@ -884,7 +979,7 @@ describe Audited::Auditor do
|
|
884
979
|
it "should record user objects" do
|
885
980
|
Models::ActiveRecord::Company.audit_as( user ) do
|
886
981
|
company = Models::ActiveRecord::Company.create name: 'The auditors'
|
887
|
-
company.
|
982
|
+
company.update! name: 'The Auditors'
|
888
983
|
|
889
984
|
company.audits.each do |audit|
|
890
985
|
expect(audit.user).to eq(user)
|
@@ -895,7 +990,7 @@ describe Audited::Auditor do
|
|
895
990
|
it "should record usernames" do
|
896
991
|
Models::ActiveRecord::Company.audit_as( user.name ) do
|
897
992
|
company = Models::ActiveRecord::Company.create name: 'The auditors'
|
898
|
-
company.
|
993
|
+
company.update! name: 'The Auditors'
|
899
994
|
|
900
995
|
company.audits.each do |audit|
|
901
996
|
expect(audit.user).to eq(user.name)
|
@@ -905,7 +1000,7 @@ describe Audited::Auditor do
|
|
905
1000
|
end
|
906
1001
|
|
907
1002
|
describe "after_audit" do
|
908
|
-
let( :user ) {
|
1003
|
+
let( :user ) { Models::ActiveRecord::UserWithAfterAudit.new }
|
909
1004
|
|
910
1005
|
it "should invoke after_audit callback on create" do
|
911
1006
|
expect(user.bogus_attr).to be_nil
|
@@ -915,7 +1010,7 @@ describe Audited::Auditor do
|
|
915
1010
|
end
|
916
1011
|
|
917
1012
|
describe "around_audit" do
|
918
|
-
let( :user ) {
|
1013
|
+
let( :user ) { Models::ActiveRecord::UserWithAfterAudit.new }
|
919
1014
|
|
920
1015
|
it "should invoke around_audit callback on create" do
|
921
1016
|
expect(user.around_attr).to be_nil
|
@@ -930,7 +1025,7 @@ describe Audited::Auditor do
|
|
930
1025
|
expect(company.type).to eq("Models::ActiveRecord::Company::STICompany")
|
931
1026
|
expect {
|
932
1027
|
Models::ActiveRecord::Company.auditing_enabled = false
|
933
|
-
company.
|
1028
|
+
company.update! name: 'STI auditors'
|
934
1029
|
Models::ActiveRecord::Company.auditing_enabled = true
|
935
1030
|
}.to_not change( Audited::Audit, :count )
|
936
1031
|
end
|