acts_as_audited 1.0.1
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 +84 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/acts_as_audited.gemspec +72 -0
- data/generators/audited_migration/USAGE +7 -0
- data/generators/audited_migration/audited_migration_generator.rb +7 -0
- data/generators/audited_migration/templates/migration.rb +23 -0
- data/init.rb +1 -0
- data/lib/acts_as_audited/audit.rb +122 -0
- data/lib/acts_as_audited/audit_sweeper.rb +79 -0
- data/lib/acts_as_audited.rb +265 -0
- data/rails/init.rb +9 -0
- data/test/acts_as_audited_test.rb +365 -0
- data/test/audit_sweeper_test.rb +29 -0
- data/test/audit_test.rb +179 -0
- data/test/db/database.yml +21 -0
- data/test/db/schema.rb +31 -0
- data/test/test_helper.rb +53 -0
- metadata +109 -0
data/test/audit_test.rb
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
|
3
|
+
class AuditTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@user = User.new :name => "testing"
|
6
|
+
@audit = Audit.new
|
7
|
+
end
|
8
|
+
|
9
|
+
context "user=" do
|
10
|
+
should "be able to set the user to a model object" do
|
11
|
+
@audit.user = @user
|
12
|
+
@audit.user.should == @user
|
13
|
+
end
|
14
|
+
|
15
|
+
should "be able to set the user to nil" do
|
16
|
+
@audit.user_id = 1
|
17
|
+
@audit.user_type = 'User'
|
18
|
+
@audit.username = 'joe'
|
19
|
+
|
20
|
+
@audit.user = nil
|
21
|
+
|
22
|
+
@audit.user.should == nil
|
23
|
+
@audit.user_id.should == nil
|
24
|
+
@audit.user_type.should == nil
|
25
|
+
@audit.username.should == nil
|
26
|
+
end
|
27
|
+
|
28
|
+
should "be able to set the user to a string" do
|
29
|
+
@audit.user = 'testing'
|
30
|
+
@audit.user.should == 'testing'
|
31
|
+
end
|
32
|
+
|
33
|
+
should "clear model when setting to a string" do
|
34
|
+
@audit.user = @user
|
35
|
+
@audit.user = 'testing'
|
36
|
+
@audit.user_id.should be(nil)
|
37
|
+
@audit.user_type.should be(nil)
|
38
|
+
end
|
39
|
+
|
40
|
+
should "clear the username when setting to a model" do
|
41
|
+
@audit.username = 'testing'
|
42
|
+
@audit.user = @user
|
43
|
+
@audit.username.should be(nil)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
context "revision" do
|
49
|
+
should "recreate attributes" do
|
50
|
+
user = User.create :name => "1"
|
51
|
+
5.times {|i| user.update_attribute :name, (i + 2).to_s }
|
52
|
+
user.audits.each do |audit|
|
53
|
+
audit.revision.name.should == audit.version.to_s
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
should "set protected attributes" do
|
58
|
+
u = User.create(:name => 'Brandon')
|
59
|
+
u.update_attribute :logins, 1
|
60
|
+
u.update_attribute :logins, 2
|
61
|
+
|
62
|
+
u.audits[2].revision.logins.should == 2
|
63
|
+
u.audits[1].revision.logins.should == 1
|
64
|
+
u.audits[0].revision.logins.should == 0
|
65
|
+
end
|
66
|
+
|
67
|
+
should "bypass attribute assignment wrappers" do
|
68
|
+
u = User.create(:name => '<Joe>')
|
69
|
+
u.audits.first.revision.name.should == '<Joe>'
|
70
|
+
end
|
71
|
+
|
72
|
+
should "work for deleted records" do
|
73
|
+
user = User.create :name => "1"
|
74
|
+
user.destroy
|
75
|
+
revision = user.audits.last.revision
|
76
|
+
revision.name.should == user.name
|
77
|
+
revision.new_record?.should be(true)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
should "set the version number on create" do
|
82
|
+
user = User.create! :name => "Set Version Number"
|
83
|
+
user.audits.first.version.should == 1
|
84
|
+
user.update_attribute :name, "Set to 2"
|
85
|
+
user.audits(true).first.version.should == 1
|
86
|
+
user.audits(true).last.version.should == 2
|
87
|
+
user.destroy
|
88
|
+
user.audits(true).last.version.should == 3
|
89
|
+
end
|
90
|
+
|
91
|
+
context "reconstruct_attributes" do
|
92
|
+
should "work with with old way of storing just the new value" do
|
93
|
+
audits = Audit.reconstruct_attributes([Audit.new(:changes => {'attribute' => 'value'})])
|
94
|
+
audits['attribute'].should == 'value'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "audited_classes" do
|
99
|
+
class CustomUser < ActiveRecord::Base
|
100
|
+
end
|
101
|
+
class CustomUserSubclass < CustomUser
|
102
|
+
acts_as_audited
|
103
|
+
end
|
104
|
+
|
105
|
+
should "include audited classes" do
|
106
|
+
Audit.audited_classes.should include(User)
|
107
|
+
end
|
108
|
+
|
109
|
+
should "include subclasses" do
|
110
|
+
Audit.audited_classes.should include(CustomUserSubclass)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "new_attributes" do
|
115
|
+
should "return a hash of the new values" do
|
116
|
+
Audit.new(:changes => {:a => [1, 2], :b => [3, 4]}).new_attributes.should == {'a' => 2, 'b' => 4}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "old_attributes" do
|
121
|
+
should "return a hash of the old values" do
|
122
|
+
Audit.new(:changes => {:a => [1, 2], :b => [3, 4]}).old_attributes.should == {'a' => 1, 'b' => 3}
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "as_user" do
|
127
|
+
setup do
|
128
|
+
@user = User.create :name => 'testing'
|
129
|
+
end
|
130
|
+
|
131
|
+
should "record user objects" do
|
132
|
+
Audit.as_user(@user) do
|
133
|
+
company = Company.create :name => 'The auditors'
|
134
|
+
company.name = 'The Auditors, Inc'
|
135
|
+
company.save
|
136
|
+
|
137
|
+
company.audits.each do |audit|
|
138
|
+
audit.user.should == @user
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
should "record usernames" do
|
144
|
+
Audit.as_user(@user.name) do
|
145
|
+
company = Company.create :name => 'The auditors'
|
146
|
+
company.name = 'The Auditors, Inc'
|
147
|
+
company.save
|
148
|
+
|
149
|
+
company.audits.each do |audit|
|
150
|
+
audit.username.should == @user.name
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
should "be thread safe" do
|
156
|
+
begin
|
157
|
+
t1 = Thread.new do
|
158
|
+
Audit.as_user(@user) do
|
159
|
+
sleep 1
|
160
|
+
Company.create(:name => 'The Auditors, Inc').audits.first.user.should == @user
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
t2 = Thread.new do
|
165
|
+
Audit.as_user(@user.name) do
|
166
|
+
Company.create(:name => 'The Competing Auditors, LLC').audits.first.username.should == @user.name
|
167
|
+
sleep 0.5
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
t1.join
|
172
|
+
t2.join
|
173
|
+
rescue ActiveRecord::StatementInvalid
|
174
|
+
STDERR.puts "Thread safety tests cannot be run with SQLite"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
sqlite:
|
2
|
+
adapter: sqlite
|
3
|
+
database: acts_as_audited_plugin.sqlite.db
|
4
|
+
sqlite3mem:
|
5
|
+
adapter: sqlite3
|
6
|
+
database: ":memory:"
|
7
|
+
sqlite3:
|
8
|
+
adapter: sqlite3
|
9
|
+
database: acts_as_audited_plugin.sqlite3.db
|
10
|
+
postgresql:
|
11
|
+
adapter: postgresql
|
12
|
+
username: postgres
|
13
|
+
password: postgres
|
14
|
+
database: acts_as_audited_plugin_test
|
15
|
+
min_messages: ERROR
|
16
|
+
mysql:
|
17
|
+
adapter: mysql
|
18
|
+
host: localhost
|
19
|
+
username: root
|
20
|
+
password:
|
21
|
+
database: acts_as_audited_plugin_test
|
data/test/db/schema.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
ActiveRecord::Schema.define(:version => 0) do
|
2
|
+
create_table :users, :force => true do |t|
|
3
|
+
t.column :name, :string
|
4
|
+
t.column :username, :string
|
5
|
+
t.column :password, :string
|
6
|
+
t.column :activated, :boolean
|
7
|
+
t.column :logins, :integer, :default => 0
|
8
|
+
t.column :created_at, :datetime
|
9
|
+
t.column :updated_at, :datetime
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table :companies, :force => true do |t|
|
13
|
+
t.column :name, :string
|
14
|
+
end
|
15
|
+
|
16
|
+
create_table :audits, :force => true do |t|
|
17
|
+
t.column :auditable_id, :integer
|
18
|
+
t.column :auditable_type, :string
|
19
|
+
t.column :user_id, :integer
|
20
|
+
t.column :user_type, :string
|
21
|
+
t.column :username, :string
|
22
|
+
t.column :action, :string
|
23
|
+
t.column :changes, :text
|
24
|
+
t.column :version, :integer, :default => 0
|
25
|
+
t.column :created_at, :datetime
|
26
|
+
end
|
27
|
+
|
28
|
+
add_index :audits, [:auditable_id, :auditable_type], :name => 'auditable_index'
|
29
|
+
add_index :audits, [:user_id, :user_type], :name => 'user_index'
|
30
|
+
add_index :audits, :created_at
|
31
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
3
|
+
require 'rubygems'
|
4
|
+
require 'multi_rails_init'
|
5
|
+
require 'active_record'
|
6
|
+
require 'active_record/version'
|
7
|
+
require 'active_record/fixtures'
|
8
|
+
require 'action_controller'
|
9
|
+
require 'action_controller/test_process'
|
10
|
+
require 'action_view'
|
11
|
+
require 'test/unit'
|
12
|
+
require 'shoulda'
|
13
|
+
|
14
|
+
gem 'jnunemaker-matchy'
|
15
|
+
require 'matchy'
|
16
|
+
require File.dirname(__FILE__) + '/../init.rb'
|
17
|
+
|
18
|
+
config = YAML::load(IO.read(File.dirname(__FILE__) + '/db/database.yml'))
|
19
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
20
|
+
ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite3mem'])
|
21
|
+
ActiveRecord::Migration.verbose = false
|
22
|
+
load(File.dirname(__FILE__) + "/db/schema.rb")
|
23
|
+
|
24
|
+
class User < ActiveRecord::Base
|
25
|
+
acts_as_audited :except => :password
|
26
|
+
|
27
|
+
attr_protected :logins
|
28
|
+
|
29
|
+
def name=(val)
|
30
|
+
write_attribute(:name, CGI.escapeHTML(val))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
class Company < ActiveRecord::Base
|
34
|
+
end
|
35
|
+
|
36
|
+
class Test::Unit::TestCase
|
37
|
+
# def change(receiver=nil, message=nil, &block)
|
38
|
+
# ChangeExpectation.new(self, receiver, message, &block)
|
39
|
+
# end
|
40
|
+
|
41
|
+
def create_user(attrs = {})
|
42
|
+
User.create({:name => 'Brandon', :username => 'brandon', :password => 'password'}.merge(attrs))
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_versions(n = 2)
|
46
|
+
returning User.create(:name => 'Foobar 1') do |u|
|
47
|
+
(n - 1).times do |i|
|
48
|
+
u.update_attribute :name, "Foobar #{i + 2}"
|
49
|
+
end
|
50
|
+
u.reload
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acts_as_audited
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brandon Keepers
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-28 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activerecord
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "2.1"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: thoughtbot-shoulda
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: jnunemaker-matchy
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
description:
|
46
|
+
email: brandon@opensoul.org
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files:
|
52
|
+
- LICENSE
|
53
|
+
- README
|
54
|
+
files:
|
55
|
+
- .gitignore
|
56
|
+
- CHANGELOG
|
57
|
+
- LICENSE
|
58
|
+
- README
|
59
|
+
- Rakefile
|
60
|
+
- VERSION
|
61
|
+
- acts_as_audited.gemspec
|
62
|
+
- generators/audited_migration/USAGE
|
63
|
+
- generators/audited_migration/audited_migration_generator.rb
|
64
|
+
- generators/audited_migration/templates/migration.rb
|
65
|
+
- init.rb
|
66
|
+
- lib/acts_as_audited.rb
|
67
|
+
- lib/acts_as_audited/audit.rb
|
68
|
+
- lib/acts_as_audited/audit_sweeper.rb
|
69
|
+
- rails/init.rb
|
70
|
+
- test/acts_as_audited_test.rb
|
71
|
+
- test/audit_sweeper_test.rb
|
72
|
+
- test/audit_test.rb
|
73
|
+
- test/db/database.yml
|
74
|
+
- test/db/schema.rb
|
75
|
+
- test/test_helper.rb
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: http://github.com/collectiveidea/acts_as_audited
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options:
|
82
|
+
- --charset=UTF-8
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: "0"
|
90
|
+
version:
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: "0"
|
96
|
+
version:
|
97
|
+
requirements: []
|
98
|
+
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 1.3.5
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: ActiveRecord extension that logs all changes to your models in an audits table
|
104
|
+
test_files:
|
105
|
+
- test/acts_as_audited_test.rb
|
106
|
+
- test/audit_sweeper_test.rb
|
107
|
+
- test/audit_test.rb
|
108
|
+
- test/db/schema.rb
|
109
|
+
- test/test_helper.rb
|