audited 4.2.1 → 4.3.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -9
  3. data/Appraisals +10 -6
  4. data/Gemfile +1 -13
  5. data/README.md +46 -33
  6. data/Rakefile +3 -18
  7. data/gemfiles/rails40.gemfile +1 -5
  8. data/gemfiles/rails41.gemfile +1 -5
  9. data/gemfiles/rails42.gemfile +1 -5
  10. data/gemfiles/rails50.gemfile +8 -0
  11. data/lib/audited/audit.rb +97 -57
  12. data/lib/audited/auditor.rb +75 -47
  13. data/lib/audited/rspec_matchers.rb +6 -2
  14. data/lib/audited/sweeper.rb +12 -23
  15. data/lib/audited/version.rb +1 -1
  16. data/lib/audited-rspec.rb +4 -0
  17. data/lib/audited.rb +15 -2
  18. data/lib/generators/audited/install_generator.rb +20 -0
  19. data/lib/generators/audited/migration.rb +15 -0
  20. data/lib/generators/audited/templates/add_association_to_audits.rb +11 -0
  21. data/lib/generators/audited/templates/add_comment_to_audits.rb +9 -0
  22. data/lib/generators/audited/templates/add_remote_address_to_audits.rb +10 -0
  23. data/lib/generators/audited/templates/add_request_uuid_to_audits.rb +10 -0
  24. data/lib/generators/audited/templates/install.rb +30 -0
  25. data/lib/generators/audited/templates/rename_association_to_associated.rb +23 -0
  26. data/lib/generators/audited/templates/rename_changes_to_audited_changes.rb +9 -0
  27. data/lib/generators/audited/templates/rename_parent_to_association.rb +11 -0
  28. data/lib/generators/audited/upgrade_generator.rb +57 -0
  29. data/spec/audited/audit_spec.rb +199 -0
  30. data/spec/audited/auditor_spec.rb +607 -0
  31. data/spec/audited/sweeper_spec.rb +106 -0
  32. data/spec/audited_spec_helpers.rb +6 -22
  33. data/spec/rails_app/config/environments/test.rb +7 -4
  34. data/spec/rails_app/config/initializers/secret_token.rb +1 -1
  35. data/spec/rails_app/config/routes.rb +1 -4
  36. data/spec/spec_helper.rb +7 -9
  37. data/spec/support/active_record/models.rb +23 -13
  38. data/spec/support/active_record/schema.rb +37 -12
  39. data/test/db/version_1.rb +4 -4
  40. data/test/db/version_2.rb +4 -4
  41. data/test/db/version_3.rb +4 -4
  42. data/test/db/version_4.rb +4 -4
  43. data/test/db/version_5.rb +2 -2
  44. data/test/db/version_6.rb +2 -2
  45. data/test/install_generator_test.rb +1 -1
  46. data/test/upgrade_generator_test.rb +10 -10
  47. metadata +73 -37
  48. data/lib/audited/active_record/version.rb +0 -5
  49. data/lib/audited/mongo_mapper/version.rb +0 -5
  50. data/spec/support/mongo_mapper/connection.rb +0 -4
  51. data/spec/support/mongo_mapper/models.rb +0 -214
@@ -0,0 +1,199 @@
1
+ require "spec_helper"
2
+
3
+ describe Audited::Audit do
4
+ let(:user) { Models::ActiveRecord::User.new name: "Testing" }
5
+
6
+ describe "user=" do
7
+
8
+ it "should be able to set the user to a model object" do
9
+ subject.user = user
10
+ expect(subject.user).to eq(user)
11
+ end
12
+
13
+ it "should be able to set the user to nil" do
14
+ subject.user_id = 1
15
+ subject.user_type = 'Models::ActiveRecord::User'
16
+ subject.username = 'joe'
17
+
18
+ subject.user = nil
19
+
20
+ expect(subject.user).to be_nil
21
+ expect(subject.user_id).to be_nil
22
+ expect(subject.user_type).to be_nil
23
+ expect(subject.username).to be_nil
24
+ end
25
+
26
+ it "should be able to set the user to a string" do
27
+ subject.user = 'test'
28
+ expect(subject.user).to eq('test')
29
+ end
30
+
31
+ it "should clear model when setting to a string" do
32
+ subject.user = user
33
+ subject.user = 'testing'
34
+ expect(subject.user_id).to be_nil
35
+ expect(subject.user_type).to be_nil
36
+ end
37
+
38
+ it "should clear the username when setting to a model" do
39
+ subject.username = 'test'
40
+ subject.user = user
41
+ expect(subject.username).to be_nil
42
+ end
43
+
44
+ end
45
+
46
+ describe "revision" do
47
+
48
+ it "should recreate attributes" do
49
+ user = Models::ActiveRecord::User.create name: "1"
50
+ 5.times {|i| user.update_attribute :name, (i + 2).to_s }
51
+
52
+ user.audits.each do |audit|
53
+ expect(audit.revision.name).to eq(audit.version.to_s)
54
+ end
55
+ end
56
+
57
+ it "should set protected attributes" do
58
+ u = Models::ActiveRecord::User.create(name: "Brandon")
59
+ u.update_attribute :logins, 1
60
+ u.update_attribute :logins, 2
61
+
62
+ expect(u.audits[2].revision.logins).to eq(2)
63
+ expect(u.audits[1].revision.logins).to eq(1)
64
+ expect(u.audits[0].revision.logins).to eq(0)
65
+ end
66
+
67
+ it "should bypass attribute assignment wrappers" do
68
+ u = Models::ActiveRecord::User.create(name: "<Joe>")
69
+ expect(u.audits.first.revision.name).to eq("&lt;Joe&gt;")
70
+ end
71
+
72
+ it "should work for deleted records" do
73
+ user = Models::ActiveRecord::User.create name: "1"
74
+ user.destroy
75
+ revision = user.audits.last.revision
76
+ expect(revision.name).to eq(user.name)
77
+ expect(revision).to be_a_new_record
78
+ end
79
+ end
80
+
81
+ it "should set the version number on create" do
82
+ user = Models::ActiveRecord::User.create! name: "Set Version Number"
83
+ expect(user.audits.first.version).to eq(1)
84
+ user.update_attribute :name, "Set to 2"
85
+ expect(user.audits.reload.first.version).to eq(1)
86
+ expect(user.audits.reload.last.version).to eq(2)
87
+ user.destroy
88
+ expect(Audited::Audit.where(auditable_type: "Models::ActiveRecord::User", auditable_id: user.id).last.version).to eq(3)
89
+ end
90
+
91
+ it "should set the request uuid on create" do
92
+ user = Models::ActiveRecord::User.create! name: "Set Request UUID"
93
+ expect(user.audits.reload.first.request_uuid).not_to be_blank
94
+ end
95
+
96
+ describe "reconstruct_attributes" do
97
+ it "should work with the old way of storing just the new value" do
98
+ audits = Audited::Audit.reconstruct_attributes([Audited::Audit.new(audited_changes: {"attribute" => "value"})])
99
+ expect(audits["attribute"]).to eq("value")
100
+ end
101
+ end
102
+
103
+ describe "audited_classes" do
104
+ class Models::ActiveRecord::CustomUser < ::ActiveRecord::Base
105
+ end
106
+ class Models::ActiveRecord::CustomUserSubclass < Models::ActiveRecord::CustomUser
107
+ audited
108
+ end
109
+
110
+ it "should include audited classes" do
111
+ expect(Audited::Audit.audited_classes).to include(Models::ActiveRecord::User)
112
+ end
113
+
114
+ it "should include subclasses" do
115
+ expect(Audited::Audit.audited_classes).to include(Models::ActiveRecord::CustomUserSubclass)
116
+ end
117
+ end
118
+
119
+ describe "new_attributes" do
120
+ it "should return a hash of the new values" do
121
+ new_attributes = Audited::Audit.new(audited_changes: {a: [1, 2], b: [3, 4]}).new_attributes
122
+ expect(new_attributes).to eq({"a" => 2, "b" => 4})
123
+ end
124
+ end
125
+
126
+ describe "old_attributes" do
127
+ it "should return a hash of the old values" do
128
+ old_attributes = Audited::Audit.new(audited_changes: {a: [1, 2], b: [3, 4]}).old_attributes
129
+ expect(old_attributes).to eq({"a" => 1, "b" => 3})
130
+ end
131
+ end
132
+
133
+ describe "as_user" do
134
+ it "should record user objects" do
135
+ Audited::Audit.as_user(user) do
136
+ company = Models::ActiveRecord::Company.create name: "The auditors"
137
+ company.name = "The Auditors, Inc"
138
+ company.save
139
+
140
+ company.audits.each do |audit|
141
+ expect(audit.user).to eq(user)
142
+ end
143
+ end
144
+ end
145
+
146
+ it "should record usernames" do
147
+ Audited::Audit.as_user(user.name) do
148
+ company = Models::ActiveRecord::Company.create name: "The auditors"
149
+ company.name = "The Auditors, Inc"
150
+ company.save
151
+
152
+ company.audits.each do |audit|
153
+ expect(audit.username).to eq(user.name)
154
+ end
155
+ end
156
+ end
157
+
158
+ it "should be thread safe" do
159
+ begin
160
+ expect(user.save).to eq(true)
161
+
162
+ t1 = Thread.new do
163
+ Audited::Audit.as_user(user) do
164
+ sleep 1
165
+ expect(Models::ActiveRecord::Company.create(name: "The Auditors, Inc").audits.first.user).to eq(user)
166
+ end
167
+ end
168
+
169
+ t2 = Thread.new do
170
+ Audited::Audit.as_user(user.name) do
171
+ expect(Models::ActiveRecord::Company.create(name: "The Competing Auditors, LLC").audits.first.username).to eq(user.name)
172
+ sleep 0.5
173
+ end
174
+ end
175
+
176
+ t1.join
177
+ t2.join
178
+ end
179
+ end if ActiveRecord::Base.connection.adapter_name != 'SQLite'
180
+
181
+ it "should return the value from the yield block" do
182
+ result = Audited::Audit.as_user('foo') do
183
+ 42
184
+ end
185
+ expect(result).to eq(42)
186
+ end
187
+
188
+ it "should reset audited_user when the yield block raises an exception" do
189
+ expect {
190
+ Audited::Audit.as_user('foo') do
191
+ raise StandardError.new('expected')
192
+ end
193
+ }.to raise_exception('expected')
194
+ expect(Thread.current[:audited_user]).to be_nil
195
+ end
196
+
197
+ end
198
+
199
+ end