cia 0.3.7 → 0.4.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.
- data/Appraisals +1 -0
- data/Gemfile.lock +22 -22
- data/gemfiles/rails2.gemfile +2 -0
- data/gemfiles/rails2.gemfile.lock +6 -1
- data/gemfiles/rails3.gemfile +1 -0
- data/gemfiles/rails3.gemfile.lock +16 -14
- data/lib/cia/auditable.rb +22 -8
- data/lib/cia/version.rb +1 -1
- data/spec/cia_spec.rb +81 -0
- data/spec/spec_helper.rb +28 -2
- metadata +6 -6
data/Appraisals
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,42 +1,42 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cia (0.
|
4
|
+
cia (0.4.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
8
8
|
specs:
|
9
|
-
activemodel (3.2.
|
10
|
-
activesupport (= 3.2.
|
9
|
+
activemodel (3.2.11)
|
10
|
+
activesupport (= 3.2.11)
|
11
11
|
builder (~> 3.0.0)
|
12
|
-
activerecord (3.2.
|
13
|
-
activemodel (= 3.2.
|
14
|
-
activesupport (= 3.2.
|
12
|
+
activerecord (3.2.11)
|
13
|
+
activemodel (= 3.2.11)
|
14
|
+
activesupport (= 3.2.11)
|
15
15
|
arel (~> 3.0.2)
|
16
16
|
tzinfo (~> 0.3.29)
|
17
|
-
activesupport (3.2.
|
17
|
+
activesupport (3.2.11)
|
18
18
|
i18n (~> 0.6)
|
19
19
|
multi_json (~> 1.0)
|
20
|
-
appraisal (0.
|
20
|
+
appraisal (0.5.1)
|
21
21
|
bundler
|
22
22
|
rake
|
23
23
|
arel (3.0.2)
|
24
|
-
builder (3.0.
|
25
|
-
bump (0.3.
|
24
|
+
builder (3.0.4)
|
25
|
+
bump (0.3.9)
|
26
26
|
diff-lcs (1.1.3)
|
27
|
-
i18n (0.6.
|
28
|
-
multi_json (1.
|
29
|
-
rake (0.
|
30
|
-
rspec (2.
|
31
|
-
rspec-core (~> 2.
|
32
|
-
rspec-expectations (~> 2.
|
33
|
-
rspec-mocks (~> 2.
|
34
|
-
rspec-core (2.
|
35
|
-
rspec-expectations (2.
|
36
|
-
diff-lcs (~> 1.1.
|
37
|
-
rspec-mocks (2.
|
27
|
+
i18n (0.6.1)
|
28
|
+
multi_json (1.5.0)
|
29
|
+
rake (10.0.3)
|
30
|
+
rspec (2.12.0)
|
31
|
+
rspec-core (~> 2.12.0)
|
32
|
+
rspec-expectations (~> 2.12.0)
|
33
|
+
rspec-mocks (~> 2.12.0)
|
34
|
+
rspec-core (2.12.2)
|
35
|
+
rspec-expectations (2.12.1)
|
36
|
+
diff-lcs (~> 1.1.3)
|
37
|
+
rspec-mocks (2.12.1)
|
38
38
|
sqlite3 (1.3.6)
|
39
|
-
tzinfo (0.3.
|
39
|
+
tzinfo (0.3.35)
|
40
40
|
|
41
41
|
PLATFORMS
|
42
42
|
ruby
|
data/gemfiles/rails2.gemfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: /Users/mgrosser/code/tools/cia
|
3
3
|
specs:
|
4
|
-
cia (0.3.
|
4
|
+
cia (0.3.7)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
@@ -9,9 +9,12 @@ GEM
|
|
9
9
|
activerecord (2.3.14)
|
10
10
|
activesupport (= 2.3.14)
|
11
11
|
activesupport (2.3.14)
|
12
|
+
after_commit (1.0.10)
|
13
|
+
activerecord (>= 1.15.6, < 3.0.0)
|
12
14
|
appraisal (0.4.1)
|
13
15
|
bundler
|
14
16
|
rake
|
17
|
+
bump (0.3.9)
|
15
18
|
diff-lcs (1.1.3)
|
16
19
|
rake (0.9.2.2)
|
17
20
|
rspec (2.10.0)
|
@@ -29,7 +32,9 @@ PLATFORMS
|
|
29
32
|
|
30
33
|
DEPENDENCIES
|
31
34
|
activerecord (= 2.3.14)
|
35
|
+
after_commit
|
32
36
|
appraisal
|
37
|
+
bump
|
33
38
|
cia!
|
34
39
|
rake
|
35
40
|
rspec (~> 2)
|
data/gemfiles/rails3.gemfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: /Users/mgrosser/code/tools/cia
|
3
3
|
specs:
|
4
|
-
cia (0.3.
|
4
|
+
cia (0.3.7)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
@@ -17,25 +17,26 @@ GEM
|
|
17
17
|
activesupport (3.2.3)
|
18
18
|
i18n (~> 0.6)
|
19
19
|
multi_json (~> 1.0)
|
20
|
-
appraisal (0.
|
20
|
+
appraisal (0.5.1)
|
21
21
|
bundler
|
22
22
|
rake
|
23
23
|
arel (3.0.2)
|
24
|
-
builder (3.0.
|
24
|
+
builder (3.0.4)
|
25
|
+
bump (0.3.9)
|
25
26
|
diff-lcs (1.1.3)
|
26
|
-
i18n (0.6.
|
27
|
-
multi_json (1.
|
28
|
-
rake (0.
|
29
|
-
rspec (2.
|
30
|
-
rspec-core (~> 2.
|
31
|
-
rspec-expectations (~> 2.
|
32
|
-
rspec-mocks (~> 2.
|
33
|
-
rspec-core (2.
|
34
|
-
rspec-expectations (2.
|
27
|
+
i18n (0.6.1)
|
28
|
+
multi_json (1.5.0)
|
29
|
+
rake (10.0.3)
|
30
|
+
rspec (2.12.0)
|
31
|
+
rspec-core (~> 2.12.0)
|
32
|
+
rspec-expectations (~> 2.12.0)
|
33
|
+
rspec-mocks (~> 2.12.0)
|
34
|
+
rspec-core (2.12.2)
|
35
|
+
rspec-expectations (2.12.1)
|
35
36
|
diff-lcs (~> 1.1.3)
|
36
|
-
rspec-mocks (2.
|
37
|
+
rspec-mocks (2.12.1)
|
37
38
|
sqlite3 (1.3.6)
|
38
|
-
tzinfo (0.3.
|
39
|
+
tzinfo (0.3.35)
|
39
40
|
|
40
41
|
PLATFORMS
|
41
42
|
ruby
|
@@ -43,6 +44,7 @@ PLATFORMS
|
|
43
44
|
DEPENDENCIES
|
44
45
|
activerecord (= 3.2.3)
|
45
46
|
appraisal
|
47
|
+
bump
|
46
48
|
cia!
|
47
49
|
rake
|
48
50
|
rspec (~> 2)
|
data/lib/cia/auditable.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
module CIA
|
2
2
|
module Auditable
|
3
3
|
def self.included(base)
|
4
|
-
base.class_attribute :audited_attributes, :audited_attribute_options
|
4
|
+
base.class_attribute :audited_attributes, :audited_attribute_options, :audited_attributes_callbacks_added
|
5
5
|
base.send :extend, ClassMethods
|
6
|
-
base.after_create {|record| CIA.record(:create, record) }
|
7
|
-
base.after_update {|record| CIA.record(:update, record) }
|
8
|
-
base.after_destroy {|record| CIA.record(:destroy, record) }
|
9
6
|
end
|
10
7
|
|
11
8
|
def cia_changes
|
@@ -15,17 +12,34 @@ module CIA
|
|
15
12
|
module ClassMethods
|
16
13
|
def audit_attribute(*attributes)
|
17
14
|
options = (attributes.last.is_a?(Hash) ? attributes.pop : {})
|
15
|
+
setup_auditing_callbacks(options)
|
18
16
|
|
19
|
-
self.audited_attributes =
|
20
|
-
self.audited_attributes += attributes.map(&:to_s)
|
17
|
+
self.audited_attributes = attributes.map(&:to_s)
|
21
18
|
|
22
19
|
raise "cannot have :if and :unless" if options[:if] && options[:unless]
|
23
|
-
self.audited_attribute_options
|
24
|
-
self.audited_attribute_options.merge!(options)
|
20
|
+
self.audited_attribute_options = options
|
25
21
|
|
26
22
|
has_many :cia_events, :class_name => "CIA::Event", :as => :source
|
27
23
|
has_many :cia_attribute_changes, :class_name => "CIA::AttributeChange", :as => :source
|
28
24
|
end
|
25
|
+
|
26
|
+
def setup_auditing_callbacks(options)
|
27
|
+
return if audited_attributes_callbacks_added
|
28
|
+
self.audited_attributes_callbacks_added = true
|
29
|
+
|
30
|
+
[:create, :update, :destroy].each do |callback|
|
31
|
+
method, args = if options[:callback] == :after_commit
|
32
|
+
if ActiveRecord::VERSION::MAJOR == 2
|
33
|
+
["after_commit_on_#{callback}"]
|
34
|
+
else # rails 3+
|
35
|
+
[:after_commit, [{:on => callback}]]
|
36
|
+
end
|
37
|
+
else
|
38
|
+
["after_#{callback}", []]
|
39
|
+
end
|
40
|
+
send(method, *args) { |record| CIA.record(callback, record) }
|
41
|
+
end
|
42
|
+
end
|
29
43
|
end
|
30
44
|
end
|
31
45
|
end
|
data/lib/cia/version.rb
CHANGED
data/spec/cia_spec.rb
CHANGED
@@ -84,6 +84,65 @@ describe CIA do
|
|
84
84
|
CIA::Event.last.action.should == "update"
|
85
85
|
end
|
86
86
|
|
87
|
+
it "does not track failed changes" do
|
88
|
+
car = Car.create!(:wheels => 1).id
|
89
|
+
expect{
|
90
|
+
expect{ FailCar.new(:wheels => 4).save }.to raise_error(FailCar::Oops)
|
91
|
+
car = FailCar.find(car)
|
92
|
+
expect{ car.update_attributes(:wheels => 2) }.to raise_error(FailCar::Oops)
|
93
|
+
expect{ car.destroy }.to raise_error(FailCar::Oops)
|
94
|
+
}.to_not change{ CIA::Event.count }
|
95
|
+
end
|
96
|
+
|
97
|
+
it "is rolled back if auditing fails" do
|
98
|
+
CIA.should_receive(:record).and_raise("XXX")
|
99
|
+
expect{
|
100
|
+
expect{
|
101
|
+
CIA.audit{ object.save! }
|
102
|
+
}.to raise_error("XXX")
|
103
|
+
}.to_not change{ object.class.count }
|
104
|
+
end
|
105
|
+
|
106
|
+
context "nested classes with multiple audited_attributes" do
|
107
|
+
let(:object){ NestedCar.new }
|
108
|
+
|
109
|
+
it "has the exclusive sub-classes attributes of the nested class" do
|
110
|
+
object.class.audited_attributes.should == ["drivers"]
|
111
|
+
end
|
112
|
+
|
113
|
+
it "does not record twice for nested classes" do
|
114
|
+
expect{
|
115
|
+
CIA.audit{ object.save! }
|
116
|
+
}.to change{ CIA::Event.count }.by(+1)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "does not record twice for super classes" do
|
120
|
+
expect{
|
121
|
+
CIA.audit{ Car.new.save! }
|
122
|
+
}.to change{ CIA::Event.count }.by(+1)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "nested classes with 1 audited_attributes" do
|
127
|
+
let(:object){ InheritedCar.new }
|
128
|
+
|
129
|
+
it "has the super-classes attributes" do
|
130
|
+
object.class.audited_attributes.should == ["wheels"]
|
131
|
+
end
|
132
|
+
|
133
|
+
it "does not record twice for nested classes" do
|
134
|
+
expect{
|
135
|
+
CIA.audit{ object.save! }
|
136
|
+
}.to change{ CIA::Event.count }.by(+1)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "does not record twice for super classes" do
|
140
|
+
expect{
|
141
|
+
CIA.audit{ Car.new.save! }
|
142
|
+
}.to change{ CIA::Event.count }.by(+1)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
87
146
|
context "custom changes" do
|
88
147
|
let(:object) { CarWithCustomChanges.new }
|
89
148
|
|
@@ -254,6 +313,28 @@ describe CIA do
|
|
254
313
|
ex.inspect.should == '#<StandardError: foo>'
|
255
314
|
end
|
256
315
|
end
|
316
|
+
|
317
|
+
context "with after_commit" do
|
318
|
+
let(:object){ CarWithTransactions.new }
|
319
|
+
|
320
|
+
it "still tracks" do
|
321
|
+
expect{
|
322
|
+
CIA.audit{ object.save! }
|
323
|
+
}.to change{ CIA::Event.count }.by(+1)
|
324
|
+
end
|
325
|
+
|
326
|
+
it "is not rolled back if auditing fails" do
|
327
|
+
CIA.should_receive(:record).and_raise("XXX")
|
328
|
+
begin
|
329
|
+
expect{
|
330
|
+
CIA.audit{ object.save! }
|
331
|
+
}.to change{ object.class.count }.by(+1)
|
332
|
+
rescue RuntimeError => e
|
333
|
+
# errors from after_commit are never raised in rails 3+
|
334
|
+
raise e if ActiveRecord::VERSION::MAJOR != 2 || e.message != "XXX"
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
257
338
|
end
|
258
339
|
|
259
340
|
context ".current_actor" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
$LOAD_PATH.unshift 'lib'
|
2
2
|
require 'cia'
|
3
|
+
require 'after_commit' if ActiveRecord::VERSION::MAJOR == 2
|
3
4
|
|
4
5
|
RSpec.configure do |config|
|
5
6
|
config.before do
|
@@ -45,8 +46,7 @@ end
|
|
45
46
|
class CarWith3Attributes < ActiveRecord::Base
|
46
47
|
self.table_name = "cars"
|
47
48
|
include CIA::Auditable
|
48
|
-
audit_attribute :wheels, :color
|
49
|
-
audit_attribute :drivers
|
49
|
+
audit_attribute :wheels, :color, :drivers
|
50
50
|
end
|
51
51
|
|
52
52
|
class CarWithIf < ActiveRecord::Base
|
@@ -73,6 +73,32 @@ class CarWithCustomChanges < ActiveRecord::Base
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
+
class FailCar < ActiveRecord::Base
|
77
|
+
self.table_name = "cars"
|
78
|
+
include CIA::Auditable
|
79
|
+
audit_attribute :wheels
|
80
|
+
|
81
|
+
class Oops < Exception
|
82
|
+
end
|
83
|
+
|
84
|
+
after_update { |x| raise Oops }
|
85
|
+
after_create { |x| raise Oops }
|
86
|
+
after_destroy { |x| raise Oops }
|
87
|
+
end
|
88
|
+
|
89
|
+
class CarWithTransactions < ActiveRecord::Base
|
90
|
+
self.table_name = "cars"
|
91
|
+
include CIA::Auditable
|
92
|
+
audit_attribute :wheels, :callback => :after_commit
|
93
|
+
end
|
94
|
+
|
95
|
+
class NestedCar < Car
|
96
|
+
audit_attribute :drivers
|
97
|
+
end
|
98
|
+
|
99
|
+
class InheritedCar < Car
|
100
|
+
end
|
101
|
+
|
76
102
|
def create_event(options={})
|
77
103
|
CIA::Event.create!({:source => Car.create!, :actor => User.create!, :action => "update"}.merge(options))
|
78
104
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.3.7
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Michael Grosser
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-10 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email: michael@grosser.it
|
@@ -46,23 +46,23 @@ rdoc_options: []
|
|
46
46
|
require_paths:
|
47
47
|
- lib
|
48
48
|
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
49
50
|
requirements:
|
50
51
|
- - ! '>='
|
51
52
|
- !ruby/object:Gem::Version
|
52
53
|
version: '0'
|
53
54
|
segments:
|
54
55
|
- 0
|
55
|
-
hash:
|
56
|
-
none: false
|
56
|
+
hash: 2880596585810436598
|
57
57
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
58
59
|
requirements:
|
59
60
|
- - ! '>='
|
60
61
|
- !ruby/object:Gem::Version
|
61
62
|
version: '0'
|
62
63
|
segments:
|
63
64
|
- 0
|
64
|
-
hash:
|
65
|
-
none: false
|
65
|
+
hash: 2880596585810436598
|
66
66
|
requirements: []
|
67
67
|
rubyforge_project:
|
68
68
|
rubygems_version: 1.8.24
|