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