acts_as_audited 1.1.1 → 2.0.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.yardopts +3 -0
  2. data/Gemfile +8 -0
  3. data/Gemfile.lock +102 -0
  4. data/LICENSE +2 -2
  5. data/README.rdoc +90 -0
  6. data/Rakefile +32 -28
  7. data/acts_as_audited.gemspec +75 -34
  8. data/autotest/discover.rb +1 -0
  9. data/lib/acts_as_audited.rb +18 -212
  10. data/lib/acts_as_audited/audit.rb +58 -40
  11. data/lib/acts_as_audited/audit_sweeper.rb +5 -27
  12. data/lib/acts_as_audited/auditor.rb +263 -0
  13. data/lib/generators/acts_as_audited/install_generator.rb +28 -0
  14. data/lib/generators/acts_as_audited/templates/add_comment_to_audits.rb +9 -0
  15. data/lib/generators/acts_as_audited/templates/add_remote_address_to_audits.rb +10 -0
  16. data/{generators/audited_migration/templates/migration.rb → lib/generators/acts_as_audited/templates/install.rb} +6 -4
  17. data/lib/generators/acts_as_audited/templates/rename_changes_to_audited_changes.rb +9 -0
  18. data/lib/generators/acts_as_audited/upgrade_generator.rb +49 -0
  19. data/spec/acts_as_audited_spec.rb +426 -0
  20. data/spec/audit_spec.rb +190 -0
  21. data/spec/audit_sweeper_spec.rb +74 -0
  22. data/spec/audited_spec_helpers.rb +16 -0
  23. data/{test → spec}/db/schema.rb +8 -5
  24. data/spec/rails_app/config/application.rb +23 -0
  25. data/spec/rails_app/config/boot.rb +13 -0
  26. data/{test/db → spec/rails_app/config}/database.yml +10 -7
  27. data/spec/rails_app/config/environment.rb +5 -0
  28. data/spec/rails_app/config/environments/development.rb +19 -0
  29. data/spec/rails_app/config/environments/production.rb +33 -0
  30. data/spec/rails_app/config/environments/test.rb +33 -0
  31. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  32. data/spec/rails_app/config/initializers/inflections.rb +2 -0
  33. data/spec/rails_app/config/initializers/secret_token.rb +2 -0
  34. data/spec/rails_app/config/routes.rb +6 -0
  35. data/spec/spec_helper.rb +21 -0
  36. data/spec/spec_models.rb +76 -0
  37. data/test/db/version_1.rb +17 -0
  38. data/test/db/version_2.rb +18 -0
  39. data/test/db/version_3.rb +19 -0
  40. data/test/install_generator_test.rb +17 -0
  41. data/test/test_helper.rb +11 -67
  42. data/test/upgrade_generator_test.rb +43 -0
  43. metadata +179 -41
  44. data/.gitignore +0 -4
  45. data/README +0 -70
  46. data/VERSION +0 -1
  47. data/generators/audited_migration/USAGE +0 -7
  48. data/generators/audited_migration/audited_migration_generator.rb +0 -7
  49. data/init.rb +0 -1
  50. data/rails/init.rb +0 -8
  51. data/test/acts_as_audited_test.rb +0 -374
  52. data/test/audit_sweeper_test.rb +0 -31
  53. data/test/audit_test.rb +0 -179
data/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- acts_as_audited_plugin.sqlite3.db
2
- test/debug.log
3
- coverage/
4
- pkg
data/README DELETED
@@ -1,70 +0,0 @@
1
- = acts_as_audited
2
-
3
- acts_as_audited is an ActiveRecord extension that logs all changes to your models in an audits table.
4
-
5
- The purpose of this fork is to store both the previous values and the changed value, making each audit record selfcontained.
6
-
7
- == Installation
8
-
9
- * acts_as_audited can be installed as a gem:
10
-
11
- # config/environment.rb
12
- config.gem 'acts_as_audited', :lib => false, :source => 'http://gemcutter.org'
13
-
14
- or a plugin:
15
-
16
- script/plugin install git://github.com/collectiveidea/acts_as_audited.git
17
-
18
- * Generate the migration
19
- script/generate audited_migration add_audits_table
20
- rake db:migrate
21
-
22
- == Usage
23
-
24
- Declare <tt>acts_as_audited</tt> on your models:
25
-
26
- class User < ActiveRecord::Base
27
- acts_as_audited :except => [:password, :mistress]
28
- end
29
-
30
- Within a web request, will automatically record the user that made the change if your controller has a <tt>current_user</tt> method.
31
-
32
- To record a user in the audits outside of a web request, you can use <tt>as_user</tt>:
33
-
34
- Audit.as_user(user) do
35
- # Perform changes on audited models
36
- end
37
-
38
- == Caveats
39
-
40
- If your model declares +attr_accessible+ after +acts_as_audited+, you need to set +:protect+ to false. acts_as_audited uses +attr_protected+ internally to prevent malicious users from unassociating your audits, and Rails does not allow both +attr_protected+ and +attr_accessible+. It will default to false if +attr_accessible+ is called before +acts_as_audited+, but needs to be explicitly set if it is called after.
41
-
42
- class User < ActiveRecord::Base
43
- acts_as_audited :protect => false
44
- attr_accessible :name
45
- end
46
-
47
- == Compatability
48
-
49
- acts_as_audited works with Rails 2.1 or later.
50
-
51
- == Getting Help
52
-
53
- Join the mailing list for getting help or offering suggestions:
54
- http://groups.google.com/group/acts_as_audited
55
-
56
- == Contributing
57
-
58
- Contributions are always welcome. Checkout the latest code on GitHub:
59
- http://github.com/collectiveidea/acts_as_audited
60
-
61
- Please include tests with your patches. There are a few gems required to run the tests:
62
- $ gem install multi_rails
63
- $ gem install thoughtbot-shoulda jnunemaker-matchy --source http://gems.github.com
64
-
65
- Make sure the tests pass against all versions of Rails since 2.1:
66
-
67
- $ rake test:multi_rails:all
68
-
69
- Please report bugs or feature suggestions on GitHub:
70
- http://github.com/collectiveidea/acts_as_audited/issues
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.1.1
@@ -1,7 +0,0 @@
1
- Description:
2
- The audited migration generator creates a migration to add the audits table.
3
-
4
- Example:
5
- ./script/generate audited_migration add_audits_table
6
-
7
- This will create a migration in db/migrate/. Run "rake db:migrate" to update your database.
@@ -1,7 +0,0 @@
1
- class AuditedMigrationGenerator < Rails::Generator::NamedBase
2
- def manifest
3
- record do |m|
4
- m.migration_template 'migration.rb', 'db/migrate'
5
- end
6
- end
7
- end
data/init.rb DELETED
@@ -1 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'rails', 'init')
data/rails/init.rb DELETED
@@ -1,8 +0,0 @@
1
- require 'acts_as_audited/audit'
2
- require 'acts_as_audited'
3
-
4
- ActiveRecord::Base.send :include, CollectiveIdea::Acts::Audited
5
-
6
- if defined?(ActionController) and defined?(ActionController::Base)
7
- require 'acts_as_audited/audit_sweeper'
8
- end
@@ -1,374 +0,0 @@
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.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 }
26
-
27
- should_change 'Audit.count', :by => 1
28
-
29
- should 'create associated audit' do
30
- @user.audits.count.should == 1
31
- end
32
-
33
- should "set the action to 'create'" do
34
- @user.audits.first.action.should == 'create'
35
- end
36
-
37
- should "store all the audited attributes" do
38
- @user.audits.first.changes.should == @user.audited_attributes
39
- end
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.changes.keys.any?{|col| ['name'].include? col}.should be(false)
44
- end
45
-
46
- should "not save an audit if only specified on update and on destroy" do
47
- lambda { on_update_destroy = OnUpdateDestroy.create(:name => 'Bart') }.should_not change { Audit.count }
48
- end
49
- end
50
-
51
- context "on update" do
52
- setup do
53
- @user = create_user(:name => 'Brandon')
54
- end
55
-
56
- should "save an audit" do
57
- lambda { @user.update_attribute(:name, "Someone") }.should change { @user.audits.count }.by(1)
58
- lambda { @user.update_attribute(:name, "Someone else") }.should change { @user.audits.count }.by(1)
59
- end
60
-
61
- should "not save an audit if the record is not changed" do
62
- lambda { @user.save! }.should_not change { Audit.count }
63
- end
64
-
65
- should "set the action to 'update'" do
66
- @user.update_attributes :name => 'Changed'
67
- @user.audits.last.action.should == 'update'
68
- end
69
-
70
- should "store the changed attributes" do
71
- @user.update_attributes :name => 'Changed'
72
- @user.audits.last.changes.should == {'name' => ['Brandon', 'Changed']}
73
- end
74
-
75
- # Dirty tracking in Rails 2.0-2.2 had issues with type casting
76
- if ActiveRecord::VERSION::STRING >= '2.3'
77
- should "not save an audit if the value doesn't change after type casting" do
78
- @user.update_attributes! :logins => 0, :activated => true
79
- lambda { @user.update_attribute :logins, '0' }.should_not change { Audit.count }
80
- lambda { @user.update_attribute :activated, 1 }.should_not change { Audit.count }
81
- lambda { @user.update_attribute :activated, '1' }.should_not change { Audit.count }
82
- end
83
- end
84
-
85
- should "not save an audit if only specified on create and on destroy" do
86
- on_create_destroy = OnCreateDestroy.create(:name => 'Bart')
87
- lambda { on_create_destroy.update_attributes :name => 'Changed' }.should_not change { Audit.count }
88
- end
89
- end
90
-
91
- context "on destroy" do
92
- setup do
93
- @user = create_user
94
- end
95
-
96
- should "save an audit" do
97
- lambda { @user.destroy }.should change { Audit.count }.by(1)
98
- @user.audits.size.should == 2
99
- end
100
-
101
- should "set the action to 'destroy'" do
102
- @user.destroy
103
- @user.audits.last.action.should == 'destroy'
104
- end
105
-
106
- should "store all of the audited attributes" do
107
- @user.destroy
108
- @user.audits.last.changes.should == @user.audited_attributes
109
- end
110
-
111
- should "be able to reconstruct destroyed record without history" do
112
- @user.audits.delete_all
113
- @user.destroy
114
- revision = @user.audits.first.revision
115
- revision.name.should == @user.name
116
- end
117
-
118
- should "not save an audit if only specified on create and on update" do
119
- on_create_update = OnCreateUpdate.create(:name => 'Bart')
120
- lambda { on_create_update.destroy }.should_not change { Audit.count }
121
- end
122
- end
123
-
124
- context "dirty tracking" do
125
- setup do
126
- @user = create_user
127
- end
128
-
129
- should "not be changed when the record is saved" do
130
- u = User.new(:name => 'Brandon')
131
- u.changed?.should be(true)
132
- u.save
133
- u.changed?.should be(false)
134
- end
135
-
136
- should "be changed when an attribute has been changed" do
137
- @user.name = "Bobby"
138
- @user.changed?.should be(true)
139
- @user.name_changed?.should be(true)
140
- @user.username_changed?.should be(false)
141
- end
142
-
143
- # Dirty tracking in Rails 2.0-2.2 had issues with type casting
144
- if ActiveRecord::VERSION::STRING >= '2.3'
145
- should "not be changed if the value doesn't change after type casting" do
146
- @user.update_attributes! :logins => 0, :activated => true
147
- @user.logins = '0'
148
- @user.changed?.should be(false)
149
- end
150
- end
151
-
152
- end
153
-
154
- context "revisions" do
155
- setup do
156
- @user = create_versions
157
- end
158
-
159
- should "be an Array of Users" do
160
- @user.revisions.should be_kind_of(Array)
161
- @user.revisions.each {|version| version.should be_kind_of(User) }
162
- end
163
-
164
- should "have one revision for a new record" do
165
- create_user.revisions.size.should == 1
166
- end
167
-
168
- should "have one revision for each audit" do
169
- @user.revisions.size.should == @user.audits.size
170
- end
171
-
172
- should "set the attributes for each revision" do
173
- u = User.create(:name => 'Brandon', :username => 'brandon')
174
- u.update_attributes :name => 'Foobar'
175
- u.update_attributes :name => 'Awesome', :username => 'keepers'
176
-
177
- u.revisions.size.should == 3
178
-
179
- u.revisions[0].name.should == 'Brandon'
180
- u.revisions[0].username.should == 'brandon'
181
-
182
- u.revisions[1].name.should == 'Foobar'
183
- u.revisions[1].username.should == 'brandon'
184
-
185
- u.revisions[2].name.should == 'Awesome'
186
- u.revisions[2].username.should == 'keepers'
187
- end
188
-
189
- should "access to only recent revisions" do
190
- u = User.create(:name => 'Brandon', :username => 'brandon')
191
- u.update_attributes :name => 'Foobar'
192
- u.update_attributes :name => 'Awesome', :username => 'keepers'
193
-
194
- u.revisions(2).size.should == 2
195
-
196
- u.revisions(2)[0].name.should == 'Foobar'
197
- u.revisions(2)[0].username.should == 'brandon'
198
-
199
- u.revisions(2)[1].name.should == 'Awesome'
200
- u.revisions(2)[1].username.should == 'keepers'
201
- end
202
-
203
- should "be empty if no audits exist" do
204
- @user.audits.delete_all
205
- @user.revisions.empty?.should be(true)
206
- end
207
-
208
- should "ignore attributes that have been deleted" do
209
- @user.audits.last.update_attributes :changes => {:old_attribute => 'old value'}
210
- lambda { @user.revisions }.should_not raise_error
211
- end
212
-
213
- end
214
-
215
- context "revision" do
216
- setup do
217
- @user = create_versions(5)
218
- end
219
-
220
- should "maintain identity" do
221
- @user.revision(1).should == @user
222
- end
223
-
224
- should "find the given revision" do
225
- revision = @user.revision(3)
226
- revision.should be_kind_of(User)
227
- revision.version.should == 3
228
- revision.name.should == 'Foobar 3'
229
- end
230
-
231
- should "find the previous revision with :previous" do
232
- revision = @user.revision(:previous)
233
- revision.version.should == 4
234
- revision.should == @user.revision(4)
235
- end
236
-
237
- should "be able to get the previous revision repeatedly" do
238
- previous = @user.revision(:previous)
239
- previous.version.should == 4
240
- previous.revision(:previous).version.should == 3
241
- end
242
-
243
- should "be able to set protected attributes" do
244
- u = User.create(:name => 'Brandon')
245
- u.update_attribute :logins, 1
246
- u.update_attribute :logins, 2
247
-
248
- u.revision(3).logins.should == 2
249
- u.revision(2).logins.should == 1
250
- u.revision(1).logins.should == 0
251
- end
252
-
253
- should "set attributes directly" do
254
- u = User.create(:name => '<Joe>')
255
- u.revision(1).name.should == '&lt;Joe&gt;'
256
- end
257
-
258
- should "set the attributes for each revision" do
259
- u = User.create(:name => 'Brandon', :username => 'brandon')
260
- u.update_attributes :name => 'Foobar'
261
- u.update_attributes :name => 'Awesome', :username => 'keepers'
262
-
263
- u.revision(3).name.should == 'Awesome'
264
- u.revision(3).username.should == 'keepers'
265
-
266
- u.revision(2).name.should == 'Foobar'
267
- u.revision(2).username.should == 'brandon'
268
-
269
- u.revision(1).name.should == 'Brandon'
270
- u.revision(1).username.should == 'brandon'
271
- end
272
-
273
- should "not raise an error when no previous audits exist" do
274
- @user.audits.destroy_all
275
- lambda{ @user.revision(:previous) }.should_not raise_error
276
- end
277
-
278
- should "mark revision's attributes as changed" do
279
- @user.revision(1).name_changed?.should be(true)
280
- end
281
-
282
- should "record new audit when saving revision" do
283
- lambda { @user.revision(1).save! }.should change { @user.audits.count }.by(1)
284
- end
285
-
286
- end
287
-
288
- context "revision_at" do
289
- should "find the latest revision before the given time" do
290
- u = create_user
291
- Audit.update(u.audits.first.id, :created_at => 1.hour.ago)
292
- u.update_attributes :name => 'updated'
293
- u.revision_at(2.minutes.ago).version.should == 1
294
- end
295
-
296
- should "be nil if given a time before audits" do
297
- create_user.revision_at(1.week.ago).should be(nil)
298
- end
299
-
300
- end
301
-
302
- context "without auditing" do
303
-
304
- should "not save an audit when calling #save_without_auditing" do
305
- lambda {
306
- u = User.new(:name => 'Brandon')
307
- u.save_without_auditing.should be(true)
308
- }.should_not change { Audit.count }
309
- end
310
-
311
- should "not save an audit inside of the #without_auditing block" do
312
- lambda do
313
- User.without_auditing { User.create(:name => 'Brandon') }
314
- end.should_not change { Audit.count }
315
- end
316
- end
317
-
318
- context "attr_protected and attr_accessible" do
319
- class UnprotectedUser < ActiveRecord::Base
320
- set_table_name :users
321
- acts_as_audited :protect => false
322
- attr_accessible :name, :username, :password
323
- end
324
- should "not raise error when attr_accessible is set and protected is false" do
325
- lambda{
326
- UnprotectedUser.new(:name => 'NO FAIL!')
327
- }.should_not raise_error(RuntimeError)
328
- end
329
-
330
- class AccessibleUser < ActiveRecord::Base
331
- set_table_name :users
332
- attr_accessible :name, :username, :password # declare attr_accessible before calling aaa
333
- acts_as_audited
334
- end
335
- should "not raise an error when attr_accessible is declared before acts_as_audited" do
336
- lambda{
337
- AccessibleUser.new(:name => 'NO FAIL!')
338
- }.should_not raise_error
339
- end
340
- end
341
-
342
- context "audit as" do
343
- setup do
344
- @user = User.create :name => 'Testing'
345
- end
346
-
347
- should "record user objects" do
348
- Company.audit_as( @user ) do
349
- company = Company.create :name => 'The auditors'
350
- company.name = 'The Auditors'
351
- company.save
352
-
353
- company.audits.each do |audit|
354
- audit.user.should == @user
355
- end
356
- end
357
- end
358
-
359
- should "record usernames" do
360
- Company.audit_as( @user.name ) do
361
- company = Company.create :name => 'The auditors'
362
- company.name = 'The Auditors, Inc'
363
- company.save
364
-
365
- company.audits.each do |audit|
366
- audit.username.should == @user.name
367
- end
368
- end
369
- end
370
- end
371
-
372
- end
373
- end
374
- end