espinita 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,14 +20,14 @@ describe GeneralModel do
20
20
 
21
21
  it "general auditable only method" do
22
22
  general_model.auditable only: [:name]
23
- expect(general_model.permited_columns).to include("name")
24
- expect(general_model.permited_columns.size).to eql 1
23
+ expect(general_model.permitted_columns).to include("name")
24
+ expect(general_model.permitted_columns.size).to eql 1
25
25
  end
26
26
 
27
27
  it "general auditable except method" do
28
28
  general_model.auditable except: [:name]
29
29
  expect(general_model.excluded_cols).to include("name")
30
- expect(general_model.permited_columns).not_to include("name")
30
+ expect(general_model.permitted_columns).not_to include("name")
31
31
  end
32
32
  end
33
33
 
@@ -217,4 +217,220 @@ describe GeneralModel do
217
217
  end
218
218
  end
219
219
 
220
+ context "history_from_audits_for" do
221
+ before do
222
+ Timecop.freeze(Time.now.localtime)
223
+ end
224
+
225
+ after do
226
+ Timecop.return
227
+ end
228
+
229
+ let!(:later){ Time.now.localtime + 10.days }
230
+ let!(:even_later){ Time.now.localtime + 1.year }
231
+
232
+ let!(:general_model) do
233
+ [:create, :update, :destroy].each do |c|
234
+ GeneralModel.reset_callbacks(c)
235
+ end
236
+ GeneralModel.auditable on: [:update]
237
+ FactoryGirl.create(:general_model)
238
+ end
239
+
240
+ let!(:updated_model) do
241
+ general_model.update_attributes(name: "Foo", audit_comment: "Some comment" )
242
+ general_model
243
+ end
244
+
245
+ context "given a single column as an argument" do
246
+
247
+ it "should accept a symbol column name" do
248
+ expect(updated_model.history_from_audits_for(:name)).to eq([
249
+ {changes: {name:"Foo"}, changed_at: Time.now.localtime}
250
+ ])
251
+ end
252
+
253
+ it "should accept a string column name" do
254
+ expect(updated_model.history_from_audits_for("name")).to eq([
255
+ {changes: {name:"Foo"}, changed_at: Time.now.localtime}
256
+ ])
257
+ end
258
+
259
+ it "should handle multiple audits" do
260
+ Timecop.freeze(later) do
261
+ updated_model.update_attributes(name: "Baz", audit_comment: "Some comment" )
262
+ end
263
+ Timecop.freeze(even_later) do
264
+ updated_model.update_attributes(name: "Arglebargle", audit_comment: "Some comment" )
265
+ end
266
+ expect(updated_model.history_from_audits_for(:name)).to eq(
267
+ [
268
+ {changes: {name:"Arglebargle"}, changed_at: even_later},
269
+ {changes: {name:"Baz"}, changed_at: later},
270
+ {changes: {name:"Foo"}, changed_at: Time.now.localtime},
271
+ ]
272
+ )
273
+ end
274
+ end
275
+
276
+ context "for multiple specified columns" do
277
+
278
+ before do
279
+ Timecop.freeze(later) do
280
+ updated_model.update_attributes(name: "Baz", position: 42, audit_comment: "Some comment" )
281
+ end
282
+ Timecop.freeze(even_later) do
283
+ updated_model.update_attributes(name: "Arglebargle", settings: "Waffles", audit_comment: "Some comment" )
284
+ end
285
+ end
286
+
287
+ it "should return history including each specified column" do
288
+ expect(updated_model.history_from_audits_for([:name, :settings])).to eq(
289
+ [
290
+ {changes: {name: "Arglebargle", settings: "Waffles"}, changed_at: even_later},
291
+ {changes: {name: "Baz"}, changed_at: later},
292
+ {changes: {name: "Foo"}, changed_at: Time.now.localtime},
293
+ ]
294
+ )
295
+ expect(updated_model.history_from_audits_for([:position, :settings])).to eq(
296
+ [
297
+ {changes: {settings: "Waffles"}, changed_at: even_later},
298
+ {changes: {position: 42}, changed_at: later},
299
+ ]
300
+ )
301
+ end
302
+
303
+ end
304
+
305
+ it "should raise an error if the requested column does not exist" do
306
+ expect{ updated_model.history_from_audits_for(:waffles) }.to raise_error(ArgumentError)
307
+ end
308
+
309
+ end
310
+
311
+ context "restore_attributes!" do
312
+
313
+ let!(:general_model) do
314
+ [:create, :update, :destroy].each do |c|
315
+ GeneralModel.reset_callbacks(c)
316
+ end
317
+ GeneralModel.auditable on: [:update]
318
+ FactoryGirl.create(:general_model)
319
+ end
320
+
321
+ let!(:historical_model) do
322
+ recent = Time.now.localtime - 10.days
323
+ less_recent = Time.now.localtime - 50.days
324
+ ancient = Time.now.localtime - 1.year
325
+ # these timed changes must be made in reverse chrono order to make the audits work for testing
326
+ Timecop.freeze(ancient) do
327
+ general_model.update_attributes(name: "Walrus", position: 1, audit_comment: "Some comment" )
328
+ end
329
+ Timecop.freeze(less_recent) do
330
+ general_model.update_attributes(name: "Arglebargle", settings: "IHOP", position: 2, audit_comment: "Some comment" )
331
+ end
332
+ Timecop.freeze(recent) do
333
+ general_model.update_attributes(name: "Baz", settings: "", position: nil, audit_comment: "Some comment" )
334
+ end
335
+ general_model
336
+ end
337
+
338
+ context "given valid arguments" do
339
+
340
+ it "should restore a single property from a datetime" do
341
+ result = historical_model.restore_attributes!(:name, DateTime.now - 12.days)
342
+
343
+ expect(result).to be(true)
344
+ expect(historical_model.name).to eq("Arglebargle")
345
+ end
346
+
347
+ it "should restore multiple attributes from a datetime" do
348
+ result = historical_model.restore_attributes!([:name, :settings], DateTime.now - 57.days)
349
+
350
+ expect(result).to be(true)
351
+ expect(historical_model.name).to eq("Walrus")
352
+ expect(historical_model.settings).to eq("MyText")
353
+ end
354
+
355
+ it "should return false when no restoration change is performed" do
356
+ original = historical_model
357
+ result = historical_model.restore_attributes!(:settings, DateTime.now + 5.days)
358
+
359
+ expect(original).to match(historical_model)
360
+ expect(result).to be(false)
361
+ end
362
+
363
+ end
364
+
365
+ context "given invalid arguments" do
366
+
367
+ it "should raise when called with no arguments" do
368
+ expect{ historical_model.restore_attributes! }.to raise_error(ArgumentError)
369
+ end
370
+
371
+ end
372
+
373
+ end
374
+
375
+ context "restore_to_audit" do
376
+
377
+ let!(:general_model) do
378
+ [:create, :update, :destroy].each do |c|
379
+ GeneralModel.reset_callbacks(c)
380
+ end
381
+ GeneralModel.auditable on: [:update]
382
+ FactoryGirl.create(:general_model)
383
+ end
384
+
385
+ context "given valid arguments" do
386
+ it "should restore when given an audit id" do
387
+ original_model = general_model.dup
388
+
389
+ general_model.update_attributes(name: "Ringo", settings: "Walrus")
390
+ general_model.update_attributes(settings: "Walrus", position: 7)
391
+ general_model.update_attributes(name: "Ringo", position: 3)
392
+ general_model.restore_to_audit(general_model.audits.first.id)
393
+
394
+ expect(general_model.name).to eq(original_model.name)
395
+ expect(general_model.settings).to eq(original_model.settings)
396
+ end
397
+
398
+ it "should restore when given an audit record" do
399
+ original_model = general_model.dup
400
+
401
+ general_model.update_attributes(name: "Ringo", settings: "Walrus")
402
+ general_model.update_attributes(settings: "Walrus", position: 7)
403
+ general_model.update_attributes(name: "Ringo", position: 3)
404
+ general_model.restore_to_audit(general_model.audits.first.id)
405
+
406
+ expect(general_model.name).to eq(original_model.name)
407
+ expect(general_model.settings).to eq(original_model.settings)
408
+ end
409
+ end
410
+
411
+ context "given invalid arguments" do
412
+
413
+ let!(:other_model) do
414
+ other_model = general_model.dup
415
+ other_model.save
416
+ other_model.update_attributes(name: "Foo", settings: "Bar")
417
+ other_model
418
+ end
419
+
420
+ it "should raise when called with a valid audit id for a different model" do
421
+ expect{ general_model.restore_to_audit(other_model.audits.first.id) }.to raise_error
422
+ end
423
+
424
+ it "should raise when called with a valid audit record for a different model" do
425
+ expect{ general_model.restore_to_audit(other_model.audits.first) }.to raise_error
426
+ end
427
+
428
+ it "should raise when called with an invalid audit id" do
429
+ expect{ general_model.restore_to_audit(999999999) }.to raise_error
430
+ end
431
+
432
+ end
433
+
434
+ end
435
+
220
436
  end
@@ -6,12 +6,14 @@ ENV["RAILS_ENV"] ||= 'test'
6
6
  require File.expand_path("../../spec/dummy/config/environment", __FILE__)
7
7
  require 'rspec/rails'
8
8
  require 'rspec/autorun'
9
+ require 'rspec/collection_matchers'
9
10
 
10
11
  require "factory_girl_rails"
11
12
  require "database_cleaner"
12
13
  require 'capybara'
13
14
  require 'capybara/rspec'
14
15
  require 'shoulda/matchers/integrations/rspec'
16
+ require 'timecop'
15
17
 
16
18
  require "espinita"
17
19
  require 'support/schema'
metadata CHANGED
@@ -1,111 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: espinita
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Michelson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-03 00:00:00.000000000 Z
11
+ date: 2015-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '4.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '4.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: request_store
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sqlite3
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec-rails
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '3.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: factory_girl
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: factory_girl_rails
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec-collection_matchers
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
@@ -126,28 +126,42 @@ dependencies:
126
126
  name: database_cleaner
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - '>='
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - '>='
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: capybara
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - '>='
143
+ - - ">="
144
144
  - !ruby/object:Gem::Version
145
145
  version: '0'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - '>='
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: timecop
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
151
165
  - !ruby/object:Gem::Version
152
166
  version: '0'
153
167
  description: Audit activerecord models like a boss
@@ -157,21 +171,23 @@ executables: []
157
171
  extensions: []
158
172
  extra_rdoc_files: []
159
173
  files:
174
+ - MIT-LICENSE
175
+ - README.md
176
+ - Rakefile
160
177
  - app/models/espinita/audit.rb
161
178
  - config/database.yml
162
179
  - config/routes.rb
163
180
  - db/migrate/20131029200927_create_auditable_audits.rb
181
+ - lib/espinita.rb
164
182
  - lib/espinita/auditor.rb
165
183
  - lib/espinita/auditor_behavior.rb
166
184
  - lib/espinita/auditor_request.rb
167
185
  - lib/espinita/engine.rb
168
186
  - lib/espinita/version.rb
169
- - lib/espinita.rb
170
187
  - lib/tasks/espinita_tasks.rake
171
- - MIT-LICENSE
172
- - Rakefile
173
- - README.md
174
188
  - spec/controllers/audits_controller_spec.rb
189
+ - spec/dummy/README.rdoc
190
+ - spec/dummy/Rakefile
175
191
  - spec/dummy/app/assets/javascripts/application.js
176
192
  - spec/dummy/app/assets/javascripts/general_controller.js
177
193
  - spec/dummy/app/assets/stylesheets/application.css
@@ -186,6 +202,7 @@ files:
186
202
  - spec/dummy/bin/bundle
187
203
  - spec/dummy/bin/rails
188
204
  - spec/dummy/bin/rake
205
+ - spec/dummy/config.ru
189
206
  - spec/dummy/config/application.rb
190
207
  - spec/dummy/config/boot.rb
191
208
  - spec/dummy/config/database.yml
@@ -202,7 +219,6 @@ files:
202
219
  - spec/dummy/config/initializers/wrap_parameters.rb
203
220
  - spec/dummy/config/locales/en.yml
204
221
  - spec/dummy/config/routes.rb
205
- - spec/dummy/config.ru
206
222
  - spec/dummy/db/migrate/20131029211126_create_general_models.rb
207
223
  - spec/dummy/db/migrate/20131030014901_create_users.rb
208
224
  - spec/dummy/db/schema.rb
@@ -211,8 +227,6 @@ files:
211
227
  - spec/dummy/public/422.html
212
228
  - spec/dummy/public/500.html
213
229
  - spec/dummy/public/favicon.ico
214
- - spec/dummy/Rakefile
215
- - spec/dummy/README.rdoc
216
230
  - spec/factories/auditable_audits.rb
217
231
  - spec/factories/general_models.rb
218
232
  - spec/factories/users.rb
@@ -231,17 +245,17 @@ require_paths:
231
245
  - lib
232
246
  required_ruby_version: !ruby/object:Gem::Requirement
233
247
  requirements:
234
- - - '>='
248
+ - - ">="
235
249
  - !ruby/object:Gem::Version
236
250
  version: '0'
237
251
  required_rubygems_version: !ruby/object:Gem::Requirement
238
252
  requirements:
239
- - - '>='
253
+ - - ">="
240
254
  - !ruby/object:Gem::Version
241
255
  version: '0'
242
256
  requirements: []
243
257
  rubyforge_project:
244
- rubygems_version: 2.0.6
258
+ rubygems_version: 2.2.2
245
259
  signing_key:
246
260
  specification_version: 4
247
261
  summary: Auditable Rails Engine.