acts_as_audited_rails3 1.1.1.4
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.
- data/.gitignore +4 -0
- data/CHANGELOG +25 -0
- data/LICENSE +19 -0
- data/README +76 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/acts_as_audited.gemspec +90 -0
- data/acts_as_audited_rails3.gemspec +90 -0
- data/doc/classes/Audit.html +407 -0
- data/doc/classes/CollectiveIdea/Acts/Audited/ClassMethods.html +226 -0
- data/doc/classes/CollectiveIdea/Acts/Audited/InstanceMethods.html +330 -0
- data/doc/classes/CollectiveIdea/Acts/Audited/SingletonMethods.html +254 -0
- data/doc/created.rid +1 -0
- data/doc/files/README.html +226 -0
- data/doc/files/lib/acts_as_audited/audit_rb.html +108 -0
- data/doc/files/lib/acts_as_audited/audit_sweeper_rb.html +101 -0
- data/doc/files/lib/acts_as_audited_rb.html +129 -0
- data/doc/fr_class_index.html +30 -0
- data/doc/fr_file_index.html +30 -0
- data/doc/fr_method_index.html +47 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/acts_as_audited/audit.rb +119 -0
- data/lib/acts_as_audited/audit_sweeper.rb +37 -0
- data/lib/acts_as_audited/base.rb +316 -0
- data/lib/acts_as_audited.rb +9 -0
- data/lib/generators/audited_migration/USAGE +7 -0
- data/lib/generators/audited_migration/audited_migration_generator.rb +24 -0
- data/lib/generators/audited_migration/templates/migration.rb +29 -0
- data/lib/generators/audited_migration_update/USAGE +7 -0
- data/lib/generators/audited_migration_update/audited_migration_update_generator.rb +24 -0
- data/lib/generators/audited_migration_update/templates/migration.rb +9 -0
- data/test/acts_as_audited_test.rb +437 -0
- data/test/audit_sweeper_test.rb +31 -0
- data/test/audit_test.rb +179 -0
- data/test/db/database.yml +21 -0
- data/test/db/schema.rb +33 -0
- data/test/test_helper.rb +75 -0
- metadata +152 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'acts_as_audited/base'
|
2
|
+
require 'acts_as_audited/audit'
|
3
|
+
require 'acts_as_audited'
|
4
|
+
|
5
|
+
ActiveRecord::Base.send :include, CollectiveIdea::Acts::Audited
|
6
|
+
|
7
|
+
if defined?(ActionController) and defined?(ActionController::Base)
|
8
|
+
require 'acts_as_audited/audit_sweeper'
|
9
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
class AuditedMigrationGenerator < Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
def self.source_root
|
8
|
+
File.join(File.dirname(__FILE__), 'templates')
|
9
|
+
end
|
10
|
+
|
11
|
+
# Implement the required interface for Rails::Generators::Migration.
|
12
|
+
# taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
|
13
|
+
def self.next_migration_number(dirname) #:nodoc:
|
14
|
+
if ActiveRecord::Base.timestamped_migrations
|
15
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
16
|
+
else
|
17
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_acts_as_audited_migration
|
22
|
+
migration_template 'migration.rb', 'db/migrate/acts_as_audited_migration.rb'
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class ActsAsAuditedMigration < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :audits, :force => true do |t|
|
4
|
+
t.column :created_at, :datetime
|
5
|
+
t.column :updated_at, :datetime
|
6
|
+
t.column :auditable_id, :integer
|
7
|
+
t.column :auditable_type, :string
|
8
|
+
t.column :user_id, :integer
|
9
|
+
t.column :user_type, :string
|
10
|
+
t.column :username, :string
|
11
|
+
t.column :action, :string
|
12
|
+
t.column :audit_changes, :text
|
13
|
+
t.column :version, :integer, :default => 0
|
14
|
+
t.column :comment, :string
|
15
|
+
end
|
16
|
+
if connection.adapter_name =~ /mysql/i
|
17
|
+
execute 'ALTER TABLE audits ADD COLUMN full_model longtext collate utf8_unicode_ci'
|
18
|
+
else
|
19
|
+
add_column :audits, :full_model, :text
|
20
|
+
end
|
21
|
+
add_index :audits, [:auditable_id, :auditable_type], :name => 'auditable_index'
|
22
|
+
add_index :audits, [:user_id, :user_type], :name => 'user_index'
|
23
|
+
add_index :audits, :created_at
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.down
|
27
|
+
drop_table :audits
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Description:
|
2
|
+
The audited migration generator creates a migration to update the audits table to allow for audit comments. It should only be used if upgrading acts_as_audited from a versino which does not permit audit comments
|
3
|
+
|
4
|
+
Example:
|
5
|
+
./script/generate audited_migration_upgrade update_audits_table
|
6
|
+
|
7
|
+
This will create a migration in db/migrate/. Run "rake db:migrate" to update your database.
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
class AuditedMigrationUpdateGenerator < Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
def self.source_root
|
8
|
+
File.join(File.dirname(__FILE__), 'templates')
|
9
|
+
end
|
10
|
+
|
11
|
+
# Implement the required interface for Rails::Generators::Migration.
|
12
|
+
# taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
|
13
|
+
def self.next_migration_number(dirname) #:nodoc:
|
14
|
+
if ActiveRecord::Base.timestamped_migrations
|
15
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
16
|
+
else
|
17
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_acts_as_audited_update_migration
|
22
|
+
migration_template 'migration.rb', 'db/migrate/acts_as_audited_update_migration.rb'
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,437 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
module CollectiveIdea
|
4
|
+
module Acts
|
5
|
+
class AuditedTest < Test::Unit::TestCase
|
6
|
+
should "include instance methods" do
|
7
|
+
User.new.should be_kind_of(CollectiveIdea::Acts::Audited::InstanceMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
should "extend singleton methods" do
|
11
|
+
User.should be_kind_of(CollectiveIdea::Acts::Audited::SingletonMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
['created_at', 'updated_at', 'created_on', 'updated_on', 'lock_version', 'id', 'password'].each do |column|
|
15
|
+
should "not audit #{column}" do
|
16
|
+
User.non_audited_columns.should include(column)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
should "not save non-audited columns" do
|
21
|
+
create_user.audits.first.audit_changes.keys.any?{|col| ['created_at', 'updated_at', 'password'].include? col}.should be(false)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "on create" do
|
25
|
+
setup { @user = create_user :audit_comment => "Create" }
|
26
|
+
|
27
|
+
should_change 'Audit.count', :by => 1
|
28
|
+
|
29
|
+
should 'create associated audit' do
|
30
|
+
@user.audits.count.should == 1
|
31
|
+
end
|
32
|
+
should "set the action to 'create'" do
|
33
|
+
@user.audits.first.action.should == 'create'
|
34
|
+
end
|
35
|
+
|
36
|
+
should "store all the audited attributes" do
|
37
|
+
@user.audits.first.audit_changes.should == @user.audited_attributes
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
should "not audit an attribute which is excepted if specified on create and on destroy" do
|
42
|
+
on_create_destroy_except_name = OnCreateDestroyExceptName.create(:name => 'Bart')
|
43
|
+
on_create_destroy_except_name.audits.first.audit_changes.keys.any?{|col| ['name'].include? col}.should be(false)
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
should "store comment" do
|
48
|
+
@user.audits.first.comment.should == "Create"
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
should "not save an audit if only specified on update and on destroy" do
|
53
|
+
lambda { on_update_destroy = OnUpdateDestroy.create(:name => 'Bart') }.should_not change { Audit.count }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "on update" do
|
58
|
+
setup do
|
59
|
+
@user = create_user(:name => 'Brandon', :audit_comment => "Update")
|
60
|
+
end
|
61
|
+
|
62
|
+
should "save an audit" do
|
63
|
+
lambda { @user.update_attribute(:name, "Someone") }.should change { @user.audits.count }.by(1)
|
64
|
+
lambda { @user.update_attribute(:name, "Someone else") }.should change { @user.audits.count }.by(1)
|
65
|
+
end
|
66
|
+
|
67
|
+
should "not save an audit if the record is not changed" do
|
68
|
+
lambda { @user.save! }.should_not change { Audit.count }
|
69
|
+
end
|
70
|
+
|
71
|
+
should "set the action to 'update'" do
|
72
|
+
@user.update_attributes :name => 'Changed'
|
73
|
+
@user.audits.last.action.should == 'update'
|
74
|
+
end
|
75
|
+
|
76
|
+
should "store the changed attributes" do
|
77
|
+
@user.update_attributes :name => 'Changed'
|
78
|
+
@user.audits.last.audit_changes.should == {'name' => ['Brandon', 'Changed']}
|
79
|
+
end
|
80
|
+
|
81
|
+
should "store audit comment" do
|
82
|
+
@user.audits.last.comment.should == "Update"
|
83
|
+
end
|
84
|
+
|
85
|
+
# Dirty tracking in Rails 2.0-2.2 had issues with type casting
|
86
|
+
if ActiveRecord::VERSION::STRING >= '2.3'
|
87
|
+
should "not save an audit if the value doesn't change after type casting" do
|
88
|
+
@user.update_attributes! :logins => 0, :activated => true
|
89
|
+
lambda { @user.update_attribute :logins, '0' }.should_not change { Audit.count }
|
90
|
+
lambda { @user.update_attribute :activated, 1 }.should_not change { Audit.count }
|
91
|
+
lambda { @user.update_attribute :activated, '1' }.should_not change { Audit.count }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
should "not save an audit if only specified on create and on destroy" do
|
96
|
+
on_create_destroy = OnCreateDestroy.create(:name => 'Bart')
|
97
|
+
lambda { on_create_destroy.update_attributes :name => 'Changed' }.should_not change { Audit.count }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "on destroy" do
|
102
|
+
setup do
|
103
|
+
@user = create_user
|
104
|
+
end
|
105
|
+
|
106
|
+
should "save an audit" do
|
107
|
+
lambda { @user.destroy }.should change { Audit.count }.by(1)
|
108
|
+
@user.audits.size.should == 2
|
109
|
+
end
|
110
|
+
|
111
|
+
should "set the action to 'destroy'" do
|
112
|
+
@user.destroy
|
113
|
+
@user.audits.last.action.should == 'destroy'
|
114
|
+
end
|
115
|
+
|
116
|
+
should "store all of the audited attributes" do
|
117
|
+
@user.destroy
|
118
|
+
@user.audits.last.audit_changes.should == @user.audited_attributes
|
119
|
+
end
|
120
|
+
|
121
|
+
should "be able to reconstruct destroyed record without history" do
|
122
|
+
@user.audits.delete_all
|
123
|
+
@user.destroy
|
124
|
+
revision = @user.audits.first.revision
|
125
|
+
revision.name.should == @user.name
|
126
|
+
end
|
127
|
+
|
128
|
+
should "not save an audit if only specified on create and on update" do
|
129
|
+
on_create_update = OnCreateUpdate.create(:name => 'Bart')
|
130
|
+
lambda { on_create_update.destroy }.should_not change { Audit.count }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "dirty tracking" do
|
135
|
+
setup do
|
136
|
+
@user = create_user
|
137
|
+
end
|
138
|
+
|
139
|
+
should "not be changed when the record is saved" do
|
140
|
+
u = User.new(:name => 'Brandon')
|
141
|
+
u.changed?.should be(true)
|
142
|
+
u.save
|
143
|
+
u.changed?.should be(false)
|
144
|
+
end
|
145
|
+
|
146
|
+
should "be changed when an attribute has been changed" do
|
147
|
+
@user.name = "Bobby"
|
148
|
+
@user.changed?.should be(true)
|
149
|
+
@user.name_changed?.should be(true)
|
150
|
+
@user.username_changed?.should be(false)
|
151
|
+
end
|
152
|
+
|
153
|
+
# Dirty tracking in Rails 2.0-2.2 had issues with type casting
|
154
|
+
if ActiveRecord::VERSION::STRING >= '2.3'
|
155
|
+
should "not be changed if the value doesn't change after type casting" do
|
156
|
+
@user.update_attributes! :logins => 0, :activated => true
|
157
|
+
@user.logins = '0'
|
158
|
+
@user.changed?.should be(false)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
context "revisions" do
|
165
|
+
setup do
|
166
|
+
@user = create_versions
|
167
|
+
end
|
168
|
+
|
169
|
+
should "be an Array of Users" do
|
170
|
+
@user.revisions.should be_kind_of(Array)
|
171
|
+
@user.revisions.each {|version| version.should be_kind_of(User) }
|
172
|
+
end
|
173
|
+
|
174
|
+
should "have one revision for a new record" do
|
175
|
+
create_user.revisions.size.should == 1
|
176
|
+
end
|
177
|
+
|
178
|
+
should "have one revision for each audit" do
|
179
|
+
@user.revisions.size.should == @user.audits.size
|
180
|
+
end
|
181
|
+
|
182
|
+
should "set the attributes for each revision" do
|
183
|
+
u = User.create(:name => 'Brandon', :username => 'brandon')
|
184
|
+
u.update_attributes :name => 'Foobar'
|
185
|
+
u.update_attributes :name => 'Awesome', :username => 'keepers'
|
186
|
+
|
187
|
+
u.revisions.size.should == 3
|
188
|
+
|
189
|
+
u.revisions[0].name.should == 'Brandon'
|
190
|
+
u.revisions[0].username.should == 'brandon'
|
191
|
+
|
192
|
+
u.revisions[1].name.should == 'Foobar'
|
193
|
+
u.revisions[1].username.should == 'brandon'
|
194
|
+
|
195
|
+
u.revisions[2].name.should == 'Awesome'
|
196
|
+
u.revisions[2].username.should == 'keepers'
|
197
|
+
end
|
198
|
+
|
199
|
+
should "access to only recent revisions" do
|
200
|
+
u = User.create(:name => 'Brandon', :username => 'brandon')
|
201
|
+
u.update_attributes :name => 'Foobar'
|
202
|
+
u.update_attributes :name => 'Awesome', :username => 'keepers'
|
203
|
+
|
204
|
+
u.revisions(2).size.should == 2
|
205
|
+
|
206
|
+
u.revisions(2)[0].name.should == 'Foobar'
|
207
|
+
u.revisions(2)[0].username.should == 'brandon'
|
208
|
+
|
209
|
+
u.revisions(2)[1].name.should == 'Awesome'
|
210
|
+
u.revisions(2)[1].username.should == 'keepers'
|
211
|
+
end
|
212
|
+
|
213
|
+
should "be empty if no audits exist" do
|
214
|
+
@user.audits.delete_all
|
215
|
+
@user.revisions.empty?.should be(true)
|
216
|
+
end
|
217
|
+
|
218
|
+
should "ignore attributes that have been deleted" do
|
219
|
+
@user.audits.last.update_attributes :audit_changes => {:old_attribute => 'old value'}
|
220
|
+
lambda { @user.revisions }.should_not raise_error
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
|
225
|
+
context "revision" do
|
226
|
+
setup do
|
227
|
+
@user = create_versions(5)
|
228
|
+
end
|
229
|
+
|
230
|
+
should "maintain identity" do
|
231
|
+
@user.revision(1).should == @user
|
232
|
+
end
|
233
|
+
|
234
|
+
should "find the given revision" do
|
235
|
+
revision = @user.revision(3)
|
236
|
+
revision.should be_kind_of(User)
|
237
|
+
revision.version.should == 3
|
238
|
+
revision.name.should == 'Foobar 3'
|
239
|
+
end
|
240
|
+
|
241
|
+
should "find the previous revision with :previous" do
|
242
|
+
revision = @user.revision(:previous)
|
243
|
+
revision.version.should == 4
|
244
|
+
revision.should == @user.revision(4)
|
245
|
+
end
|
246
|
+
|
247
|
+
should "be able to get the previous revision repeatedly" do
|
248
|
+
previous = @user.revision(:previous)
|
249
|
+
previous.version.should == 4
|
250
|
+
previous.revision(:previous).version.should == 3
|
251
|
+
end
|
252
|
+
|
253
|
+
should "be able to set protected attributes" do
|
254
|
+
u = User.create(:name => 'Brandon')
|
255
|
+
u.update_attribute :logins, 1
|
256
|
+
u.update_attribute :logins, 2
|
257
|
+
|
258
|
+
u.revision(3).logins.should == 2
|
259
|
+
u.revision(2).logins.should == 1
|
260
|
+
u.revision(1).logins.should == 0
|
261
|
+
end
|
262
|
+
|
263
|
+
should "set attributes directly" do
|
264
|
+
u = User.create(:name => '<Joe>')
|
265
|
+
u.revision(1).name.should == '<Joe>'
|
266
|
+
end
|
267
|
+
|
268
|
+
should "set the attributes for each revision" do
|
269
|
+
u = User.create(:name => 'Brandon', :username => 'brandon')
|
270
|
+
u.update_attributes :name => 'Foobar'
|
271
|
+
u.update_attributes :name => 'Awesome', :username => 'keepers'
|
272
|
+
|
273
|
+
u.revision(3).name.should == 'Awesome'
|
274
|
+
u.revision(3).username.should == 'keepers'
|
275
|
+
|
276
|
+
u.revision(2).name.should == 'Foobar'
|
277
|
+
u.revision(2).username.should == 'brandon'
|
278
|
+
|
279
|
+
u.revision(1).name.should == 'Brandon'
|
280
|
+
u.revision(1).username.should == 'brandon'
|
281
|
+
end
|
282
|
+
|
283
|
+
should "be able to get time for first revision" do
|
284
|
+
suspended_at = Time.now
|
285
|
+
u = User.create(:suspended_at => suspended_at)
|
286
|
+
u.revision(1).suspended_at.should == suspended_at
|
287
|
+
end
|
288
|
+
|
289
|
+
should "not raise an error when no previous audits exist" do
|
290
|
+
@user.audits.destroy_all
|
291
|
+
lambda{ @user.revision(:previous) }.should_not raise_error
|
292
|
+
end
|
293
|
+
|
294
|
+
should "mark revision's attributes as changed" do
|
295
|
+
@user.revision(1).name_changed?.should be(true)
|
296
|
+
end
|
297
|
+
|
298
|
+
should "record new audit when saving revision" do
|
299
|
+
lambda { @user.revision(1).save! }.should change { @user.audits.count }.by(1)
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
context "revision_at" do
|
305
|
+
should "find the latest revision before the given time" do
|
306
|
+
u = create_user
|
307
|
+
Audit.update(u.audits.first.id, :created_at => 1.hour.ago)
|
308
|
+
u.update_attributes :name => 'updated'
|
309
|
+
u.revision_at(2.minutes.ago).version.should == 1
|
310
|
+
end
|
311
|
+
|
312
|
+
should "be nil if given a time before audits" do
|
313
|
+
create_user.revision_at(1.week.ago).should be(nil)
|
314
|
+
end
|
315
|
+
|
316
|
+
end
|
317
|
+
|
318
|
+
context "without auditing" do
|
319
|
+
|
320
|
+
should "not save an audit when calling #save_without_auditing" do
|
321
|
+
lambda {
|
322
|
+
u = User.new(:name => 'Brandon')
|
323
|
+
u.save_without_auditing.should be(true)
|
324
|
+
}.should_not change { Audit.count }
|
325
|
+
end
|
326
|
+
|
327
|
+
should "not save an audit inside of the #without_auditing block" do
|
328
|
+
lambda do
|
329
|
+
User.without_auditing { User.create(:name => 'Brandon') }
|
330
|
+
end.should_not change { Audit.count }
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
context "comment required" do
|
335
|
+
class CommentRequiredUser < ActiveRecord::Base
|
336
|
+
set_table_name :users
|
337
|
+
acts_as_audited :comment_required => true
|
338
|
+
end
|
339
|
+
|
340
|
+
context "on create" do
|
341
|
+
should "not validate when audit_comment is not supplied" do
|
342
|
+
CommentRequiredUser.new.valid?.should == false
|
343
|
+
end
|
344
|
+
|
345
|
+
should "validate when audit_comment is supplied" do
|
346
|
+
CommentRequiredUser.new(:audit_comment => "Create").valid?.should == true
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
context "on update" do
|
351
|
+
setup do
|
352
|
+
@user = CommentRequiredUser.create(:audit_comment => "Create")
|
353
|
+
end
|
354
|
+
should "not validate when audit_comment is not supplied" do
|
355
|
+
@user.update_attributes(:name => "Test").should == false
|
356
|
+
end
|
357
|
+
|
358
|
+
should "validate when audit_comment is supplied" do
|
359
|
+
@user.update_attributes(:name => "foo", :audit_comment => "Update").should == true
|
360
|
+
end
|
361
|
+
|
362
|
+
end
|
363
|
+
|
364
|
+
context "on destroy" do
|
365
|
+
setup do
|
366
|
+
@user = CommentRequiredUser.create(:audit_comment => "Create")
|
367
|
+
end
|
368
|
+
|
369
|
+
should "not validate when audit_comment is unset" do
|
370
|
+
@user.destroy.should == false
|
371
|
+
end
|
372
|
+
|
373
|
+
should "validate when audit_comment is supplied" do
|
374
|
+
@user.audit_comment = "Destroy"
|
375
|
+
@user.destroy.should == @user
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
end
|
380
|
+
|
381
|
+
context "attr_protected and attr_accessible" do
|
382
|
+
class UnprotectedUser < ActiveRecord::Base
|
383
|
+
set_table_name :users
|
384
|
+
acts_as_audited :protect => false
|
385
|
+
attr_accessible :name, :username, :password
|
386
|
+
end
|
387
|
+
should "not raise error when attr_accessible is set and protected is false" do
|
388
|
+
lambda{
|
389
|
+
UnprotectedUser.new(:name => 'NO FAIL!')
|
390
|
+
}.should_not raise_error(RuntimeError)
|
391
|
+
end
|
392
|
+
|
393
|
+
class AccessibleUser < ActiveRecord::Base
|
394
|
+
set_table_name :users
|
395
|
+
attr_accessible :name, :username, :password # declare attr_accessible before calling aaa
|
396
|
+
acts_as_audited
|
397
|
+
end
|
398
|
+
should "not raise an error when attr_accessible is declared before acts_as_audited" do
|
399
|
+
lambda{
|
400
|
+
AccessibleUser.new(:name => 'NO FAIL!')
|
401
|
+
}.should_not raise_error
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
context "audit as" do
|
406
|
+
setup do
|
407
|
+
@user = User.create :name => 'Testing'
|
408
|
+
end
|
409
|
+
|
410
|
+
should "record user objects" do
|
411
|
+
Company.audit_as( @user ) do
|
412
|
+
company = Company.create :name => 'The auditors'
|
413
|
+
company.name = 'The Auditors'
|
414
|
+
company.save
|
415
|
+
|
416
|
+
company.audits.each do |audit|
|
417
|
+
audit.user.should == @user
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
should "record usernames" do
|
423
|
+
Company.audit_as( @user.name ) do
|
424
|
+
company = Company.create :name => 'The auditors'
|
425
|
+
company.name = 'The Auditors, Inc'
|
426
|
+
company.save
|
427
|
+
|
428
|
+
company.audits.each do |audit|
|
429
|
+
audit.username.should == @user.name
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
class AuditsController < ActionController::Base
|
4
|
+
def audit
|
5
|
+
@company = Company.create
|
6
|
+
render :nothing => true
|
7
|
+
end
|
8
|
+
|
9
|
+
def update_user
|
10
|
+
current_user.update_attributes({:password => 'foo'})
|
11
|
+
render :nothing => true
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
attr_accessor :current_user
|
16
|
+
end
|
17
|
+
AuditsController.view_paths = [File.dirname(__FILE__)]
|
18
|
+
ActionController::Routing::Routes.draw {|m| m.connect ':controller/:action/:id' }
|
19
|
+
|
20
|
+
class AuditsControllerTest < ActionController::TestCase
|
21
|
+
should "audit user" do
|
22
|
+
user = @controller.send(:current_user=, create_user)
|
23
|
+
lambda { post :audit }.should change { Audit.count }
|
24
|
+
assigns(:company).audits.last.user.should == user
|
25
|
+
end
|
26
|
+
|
27
|
+
should "not save blank audits" do
|
28
|
+
user = @controller.send(:current_user=, create_user)
|
29
|
+
lambda { post :update_user }.should_not change { Audit.count }
|
30
|
+
end
|
31
|
+
end
|