draftsman 0.6.0 → 0.7.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.
- checksums.yaml +4 -4
- data/.travis.yml +8 -3
- data/CHANGELOG.md +32 -1
- data/README.md +4 -4
- data/draftsman.gemspec +2 -2
- data/gemfiles/ar_4_2.gemfile +6 -0
- data/gemfiles/ar_5_0.gemfile +6 -0
- data/gemfiles/ar_5_1.gemfile +6 -0
- data/lib/draftsman.rb +5 -0
- data/lib/draftsman/draft.rb +4 -16
- data/lib/draftsman/model.rb +15 -9
- data/lib/draftsman/version.rb +1 -1
- data/spec/controllers/informants_controller_spec.rb +33 -15
- data/spec/controllers/users_controller_spec.rb +15 -8
- data/spec/controllers/whodunnits_controller_spec.rb +17 -12
- data/spec/models/child_spec.rb +4 -4
- data/spec/models/skipper_spec.rb +81 -7
- data/spec/models/vanilla_spec.rb +105 -0
- data/spec/models/whitelister_spec.rb +12 -0
- data/spec/spec_helper.rb +0 -5
- data/spec/support/feature_detection.rb +11 -0
- metadata +16 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b81db1f80bb1d8742793931418a05f425f4574d
|
4
|
+
data.tar.gz: 40e32fd2383a15cc1e8e96552e63220faf0c4784
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b3e3e7a21e4078e32d66726366674d1bc0af4eb68fdb7aeec02d82dcb8d0c96f09be4366d3239dbee20b3363758507fbb608b5e5b2c3b04da510a0a003c4a2c
|
7
|
+
data.tar.gz: c97dd6e0a81c69d5c5d83ba034b8fceb6db7fee0fa54da1c8b62bc73ee5550c9812e74754910796172d338bdc0549e1cd1afa8708d696c74900136dfe0278bf9
|
data/.travis.yml
CHANGED
@@ -4,9 +4,14 @@ cache: bundler
|
|
4
4
|
sudo: false
|
5
5
|
|
6
6
|
rvm:
|
7
|
-
- 2.4.
|
8
|
-
- 2.3.
|
9
|
-
- 2.2.
|
7
|
+
- 2.4.1
|
8
|
+
- 2.3.4
|
9
|
+
- 2.2.7
|
10
|
+
|
11
|
+
gemfile:
|
12
|
+
- gemfiles/ar_5_1.gemfile
|
13
|
+
- gemfiles/ar_5_0.gemfile
|
14
|
+
- gemfiles/ar_4_2.gemfile
|
10
15
|
|
11
16
|
before_script:
|
12
17
|
- bundle exec rake -f spec/dummy/Rakefile db:schema:load
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,37 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
-
## 0.
|
3
|
+
## 0.7.0 - June 12, 2017
|
4
|
+
|
5
|
+
### Enhancements
|
6
|
+
|
7
|
+
- [@jmfederico](https://github.com/jmfederico)
|
8
|
+
[implemented](https://github.com/liveeditor/draftsman/commit/87f242374ad9fd97f7dba2e485d68da407c46fed)
|
9
|
+
[#67](https://github.com/liveeditor/draftsman/pull/67)
|
10
|
+
5.1 compatibility
|
11
|
+
- [@chrisdpeters](https://github.com/chrisdpeters)
|
12
|
+
[implemented](https://github.com/liveeditor/draftsman/commit/e2c8e497899a453daf4c60d6ce02cacbf15a0f12)
|
13
|
+
Change Draft.object_col_is_json? to skip over itself if not stashing drafted changes
|
14
|
+
- [@npezza93](https://github.com/npezza93)
|
15
|
+
[implemented](https://github.com/liveeditor/draftsman/commit/936d5a37c044c5ca0a5699a553d9bc111f2d91d2)
|
16
|
+
[#58](https://github.com/liveeditor/draftsman/pull/58)
|
17
|
+
Only update attributes that get changed instead of all of them
|
18
|
+
- [@jmfederico](https://github.com/jmfederico)
|
19
|
+
[implemented](https://github.com/liveeditor/draftsman/commit/e8ba201db6bb88ea0ebc47c1262eb24e892e9a0b)
|
20
|
+
[#65](https://github.com/liveeditor/draftsman/pull/65)
|
21
|
+
Do not "touch" models when not updating the base table content
|
22
|
+
|
23
|
+
### Bug Fixes
|
24
|
+
|
25
|
+
- [@jokius](https://github.com/jokius)
|
26
|
+
[fixed](https://github.com/liveeditor/draftsman/commit/5ca7d6717109d753959a5d56c0fe81c3cd7b75f1)
|
27
|
+
[#57](https://github.com/liveeditor/draftsman/pull/57)
|
28
|
+
Fix if self.changeset is nil
|
29
|
+
- [@jmfederico](https://github.com/jmfederico)
|
30
|
+
[fixed](https://github.com/liveeditor/draftsman/commit/207d158d054ed13ca6dc0a15ae2c499b0aac5f5f)
|
31
|
+
[#64](https://github.com/liveeditor/draftsman/pull/64)
|
32
|
+
Fix error when saving a draft when one already existed
|
33
|
+
|
34
|
+
## 0.6.0 - November 16, 2016
|
4
35
|
|
5
36
|
### Enhancements
|
6
37
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Draftsman v0.
|
1
|
+
# Draftsman v0.7.0
|
2
2
|
|
3
3
|
[](http://travis-ci.org/liveeditor/draftsman)
|
4
4
|
|
@@ -64,7 +64,7 @@ ActiveRecord.
|
|
64
64
|
Add Draftsman to your `Gemfile`.
|
65
65
|
|
66
66
|
```ruby
|
67
|
-
gem 'draftsman', '~> 0.
|
67
|
+
gem 'draftsman', '~> 0.7.0'
|
68
68
|
```
|
69
69
|
|
70
70
|
Or if you want to grab the latest from `master`:
|
@@ -611,8 +611,8 @@ included, please do the following:
|
|
611
611
|
|
612
612
|
2. Run `bundle install`.
|
613
613
|
|
614
|
-
3.
|
615
|
-
database
|
614
|
+
3. Run `RAILS_ENV=test bundle exec rake -f spec/dummy/
|
615
|
+
Rakefile db:schema:load` to load test database schema.
|
616
616
|
|
617
617
|
4. Add at least one test for your change. Only refactoring and documentation
|
618
618
|
changes require no new tests. If you are adding functionality or fixing a
|
data/draftsman.gemspec
CHANGED
@@ -16,10 +16,10 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
17
|
s.require_paths = ['lib']
|
18
18
|
|
19
|
-
s.add_dependency 'activerecord', ['>=
|
19
|
+
s.add_dependency 'activerecord', ['>= 4.0', '< 5.2']
|
20
20
|
|
21
21
|
s.add_development_dependency 'rake'
|
22
|
-
s.add_development_dependency 'railties', ['>=
|
22
|
+
s.add_development_dependency 'railties', ['>= 4.0', '< 5.2']
|
23
23
|
s.add_development_dependency 'sinatra', '~> 1.0'
|
24
24
|
s.add_development_dependency 'rspec-rails', '~> 3.5'
|
25
25
|
|
data/lib/draftsman.rb
CHANGED
@@ -30,6 +30,11 @@ module Draftsman
|
|
30
30
|
!!draftsman_store[:request_enabled_for_controller]
|
31
31
|
end
|
32
32
|
|
33
|
+
# Returns whether or not ActiveRecord is configured to assume that `belongs_to` associations are required.
|
34
|
+
def self.active_record_belongs_to_required?
|
35
|
+
@active_record_belongs_to_required ||= ActiveRecord::VERSION::STRING.to_f >= 5.0
|
36
|
+
end
|
37
|
+
|
33
38
|
# Returns whether or not ActiveRecord is configured to require mass assignment whitelisting via `attr_accessible`.
|
34
39
|
def self.active_record_protected_attributes?
|
35
40
|
@active_record_protected_attributes ||= ActiveRecord::VERSION::STRING.to_f < 4.0 || defined?(ProtectedAttributes)
|
data/lib/draftsman/draft.rb
CHANGED
@@ -20,7 +20,7 @@ class Draftsman::Draft < ActiveRecord::Base
|
|
20
20
|
# Returns whether the `object` column is using the `json` type supported by
|
21
21
|
# PostgreSQL.
|
22
22
|
def self.object_col_is_json?
|
23
|
-
@object_col_is_json ||= columns_hash['object'].type == :json
|
23
|
+
@object_col_is_json ||= Draftsman.stash_drafted_changes? && columns_hash['object'].type == :json
|
24
24
|
end
|
25
25
|
|
26
26
|
# Returns whether or not this class has an `object_changes` column.
|
@@ -175,23 +175,11 @@ class Draftsman::Draft < ActiveRecord::Base
|
|
175
175
|
self.item.attributes = self.reify.attributes if Draftsman.stash_drafted_changes? && self.update?
|
176
176
|
|
177
177
|
# Write `published_at` attribute
|
178
|
-
self.item.send("#{self.item.class.published_at_attribute_name}=",
|
178
|
+
self.item.send("#{self.item.class.published_at_attribute_name}=", current_time_from_proper_timezone)
|
179
179
|
|
180
180
|
# Clear out draft
|
181
181
|
self.item.send("#{self.item.class.draft_association_name}_id=", nil)
|
182
182
|
|
183
|
-
# Determine which columns should be updated
|
184
|
-
only = self.item.class.draftsman_options[:only]
|
185
|
-
ignore = self.item.class.draftsman_options[:ignore]
|
186
|
-
skip = self.item.class.draftsman_options[:skip]
|
187
|
-
attributes_to_change = only.any? ? only : self.item.attribute_names
|
188
|
-
attributes_to_change = attributes_to_change - ignore + ['published_at', "#{self.item.class.draft_association_name}_id"] - skip
|
189
|
-
|
190
|
-
# Save without validations or callbacks
|
191
|
-
self.item.attributes.slice(*attributes_to_change).each do |key, value|
|
192
|
-
self.item.send("#{key}=", value)
|
193
|
-
end
|
194
|
-
|
195
183
|
self.item.save(validate: false)
|
196
184
|
self.item.reload
|
197
185
|
|
@@ -223,7 +211,7 @@ class Draftsman::Draft < ActiveRecord::Base
|
|
223
211
|
elsif self.previous_draft.present?
|
224
212
|
reify_previous_draft.reify
|
225
213
|
# Prefer changeset for refication if it's present.
|
226
|
-
elsif
|
214
|
+
elsif self.changeset.present? && self.changeset.any?
|
227
215
|
self.changeset.each do |key, value|
|
228
216
|
# Skip counter_cache columns
|
229
217
|
if self.item.respond_to?("#{key}=") && !key.end_with?('_count')
|
@@ -277,7 +265,7 @@ class Draftsman::Draft < ActiveRecord::Base
|
|
277
265
|
end
|
278
266
|
# Then clear out the draft ID.
|
279
267
|
self.item.send("#{self.item.class.draft_association_name}_id=", nil)
|
280
|
-
self.item.save!(validate: false)
|
268
|
+
self.item.save!(validate: false, touch: false)
|
281
269
|
# Then destroy draft.
|
282
270
|
self.destroy
|
283
271
|
when :destroy
|
data/lib/draftsman/model.rb
CHANGED
@@ -90,7 +90,11 @@ module Draftsman
|
|
90
90
|
self.trashed_at_attribute_name = options[:trashed_at] || :trashed_at
|
91
91
|
|
92
92
|
# `belongs_to :draft` association
|
93
|
-
|
93
|
+
if ::Draftsman.active_record_belongs_to_required?
|
94
|
+
belongs_to(self.draft_association_name, class_name: self.draft_class_name, dependent: :destroy, optional: true)
|
95
|
+
else
|
96
|
+
belongs_to(self.draft_association_name, class_name: self.draft_class_name, dependent: :destroy)
|
97
|
+
end
|
94
98
|
|
95
99
|
# Scopes
|
96
100
|
scope :drafted, -> (referenced_table_name = nil) {
|
@@ -169,7 +173,7 @@ module Draftsman
|
|
169
173
|
object ||= self
|
170
174
|
|
171
175
|
attrs = object.attributes.except(*self.class.draftsman_options[:skip]).tap do |attributes|
|
172
|
-
self.class.serialize_attributes_for_draftsman
|
176
|
+
self.class.serialize_attributes_for_draftsman(attributes)
|
173
177
|
end
|
174
178
|
|
175
179
|
if self.class.draft_class.object_col_is_json?
|
@@ -326,17 +330,18 @@ module Draftsman
|
|
326
330
|
|
327
331
|
data = merge_metadata_for_draft(data)
|
328
332
|
send(self.class.draft_association_name).update(data)
|
329
|
-
|
333
|
+
save
|
330
334
|
else
|
331
335
|
the_changes = changes_for_draftsman(:update)
|
332
336
|
save_only_columns_for_draft if Draftsman.stash_drafted_changes?
|
333
337
|
|
334
|
-
# Destroy the draft if this record has changed back to the
|
335
|
-
#
|
338
|
+
# Destroy the draft if this record has changed back to the
|
339
|
+
# original values.
|
336
340
|
if self.draft? && the_changes.empty?
|
337
341
|
nilified_draft = send(self.class.draft_association_name)
|
342
|
+
touch = changed?
|
338
343
|
send("#{self.class.draft_association_name}_id=", nil)
|
339
|
-
|
344
|
+
save(touch: touch)
|
340
345
|
nilified_draft.destroy
|
341
346
|
# Save an update draft if record is changed notably.
|
342
347
|
elsif !the_changes.empty?
|
@@ -397,7 +402,7 @@ module Draftsman
|
|
397
402
|
if event == :update
|
398
403
|
# Collect all attributes' previous and new values.
|
399
404
|
draftable_attrs.each do |attr|
|
400
|
-
if self.draft? && self.draft.changeset.key?(attr)
|
405
|
+
if self.draft? && self.draft.changeset && self.draft.changeset.key?(attr)
|
401
406
|
the_changes[attr] = [self.draft.changeset[attr].first, send(attr)]
|
402
407
|
else
|
403
408
|
the_changes[attr] = [self.send("#{attr}_was"), send(attr)]
|
@@ -443,7 +448,7 @@ module Draftsman
|
|
443
448
|
only_changed_attributes = self.attributes.keys - self.class.draftsman_options[:only]
|
444
449
|
|
445
450
|
only_changed_attributes.each do |key|
|
446
|
-
only_changes[key] = send(key)
|
451
|
+
only_changes[key] = send(key) if changed.include?(key)
|
447
452
|
end
|
448
453
|
|
449
454
|
self.update_columns(only_changes) if only_changes.any?
|
@@ -469,7 +474,8 @@ module Draftsman
|
|
469
474
|
# Updates skipped attributes' values on this model.
|
470
475
|
def update_skipped_attributes
|
471
476
|
# Skip over this if nothing's being skipped.
|
472
|
-
|
477
|
+
skipped_changed = changed_attributes.keys & draftsman_options[:skip]
|
478
|
+
return true unless skipped_changed.present?
|
473
479
|
|
474
480
|
keys = self.attributes.keys.select { |key| draftsman_options[:skip].include?(key) }
|
475
481
|
attrs = {}
|
data/lib/draftsman/version.rb
CHANGED
@@ -1,45 +1,63 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'support/feature_detection'
|
2
3
|
|
3
4
|
# Tests controller `info_for_draftsman` method
|
4
5
|
describe InformantsController, type: :controller do
|
5
6
|
let(:trashable) { Trashable.create!(name: 'Bob') }
|
6
7
|
|
7
8
|
describe 'create' do
|
8
|
-
before { post :create }
|
9
|
-
subject { Draftsman::Draft.last }
|
10
|
-
|
11
9
|
it 'records `ip` from custom `info_for_draftsman`' do
|
12
|
-
|
10
|
+
post :create
|
11
|
+
expect(Draftsman::Draft.last.ip).to eql '123.45.67.89'
|
13
12
|
end
|
14
13
|
|
15
14
|
it 'records `user_agent` from custom `info_for_draftsman`' do
|
16
|
-
|
15
|
+
post :create
|
16
|
+
expect(Draftsman::Draft.last.user_agent).to eql '007'
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
describe 'update' do
|
21
|
-
before { put :update, id: trashable.id }
|
22
|
-
subject { Draftsman::Draft.last }
|
23
|
-
|
24
21
|
it 'records `ip` from custom `info_for_draftsman`' do
|
25
|
-
|
22
|
+
if request_test_helpers_require_keyword_args?
|
23
|
+
put :update, params: { id: trashable.id }
|
24
|
+
else
|
25
|
+
put :update, id: trashable.id
|
26
|
+
end
|
27
|
+
|
28
|
+
expect(Draftsman::Draft.last.ip).to eql '123.45.67.89'
|
26
29
|
end
|
27
30
|
|
28
31
|
it 'records `user_agent` from custom `info_for_draftsman`' do
|
29
|
-
|
32
|
+
if request_test_helpers_require_keyword_args?
|
33
|
+
put :update, params: { id: trashable.id }
|
34
|
+
else
|
35
|
+
put :update, id: trashable.id
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(Draftsman::Draft.last.user_agent).to eql '007'
|
30
39
|
end
|
31
40
|
end
|
32
41
|
|
33
42
|
describe 'destroy' do
|
34
|
-
before { delete :destroy, id: trashable.id }
|
35
|
-
subject { Draftsman::Draft.last }
|
36
|
-
|
37
43
|
it 'records `ip` from custom `info_for_draftsman`' do
|
38
|
-
|
44
|
+
if request_test_helpers_require_keyword_args?
|
45
|
+
delete :destroy, params: { id: trashable.id }
|
46
|
+
else
|
47
|
+
delete :destroy, id: trashable.id
|
48
|
+
end
|
49
|
+
|
50
|
+
expect(Draftsman::Draft.last.ip).to eql '123.45.67.89'
|
39
51
|
end
|
40
52
|
|
41
53
|
it 'records `user_agent` from custom `info_for_draftsman`' do
|
42
|
-
|
54
|
+
if request_test_helpers_require_keyword_args?
|
55
|
+
delete :destroy, params: { id: trashable.id }
|
56
|
+
else
|
57
|
+
delete :destroy, id: trashable.id
|
58
|
+
end
|
59
|
+
|
60
|
+
expect(Draftsman::Draft.last.user_agent).to eql '007'
|
43
61
|
end
|
44
62
|
end
|
45
63
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'support/feature_detection'
|
2
3
|
|
3
4
|
describe UsersController, type: :controller do
|
4
5
|
let(:trashable) { Trashable.create!(name: 'Bob') }
|
@@ -13,20 +14,26 @@ describe UsersController, type: :controller do
|
|
13
14
|
end
|
14
15
|
|
15
16
|
describe 'update' do
|
16
|
-
before { put :update, id: trashable.id }
|
17
|
-
subject { return Draftsman::Draft.last }
|
18
|
-
|
19
17
|
it 'records user name via `user_for_draftsman`' do
|
20
|
-
|
18
|
+
if request_test_helpers_require_keyword_args?
|
19
|
+
put :update, params: { id: trashable.id }
|
20
|
+
else
|
21
|
+
put :update, id: trashable.id
|
22
|
+
end
|
23
|
+
|
24
|
+
expect(Draftsman::Draft.last.whodunnit).to eql 'A User'
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
24
28
|
describe 'destroy' do
|
25
|
-
before { delete :destroy, id: trashable.id }
|
26
|
-
subject { return Draftsman::Draft.last }
|
27
|
-
|
28
29
|
it 'records user name via `user_for_draftsman`' do
|
29
|
-
|
30
|
+
if request_test_helpers_require_keyword_args?
|
31
|
+
delete :destroy, params: { id: trashable.id }
|
32
|
+
else
|
33
|
+
delete :destroy, id: trashable.id
|
34
|
+
end
|
35
|
+
|
36
|
+
expect(Draftsman::Draft.last.whodunnit).to eql 'A User'
|
30
37
|
end
|
31
38
|
end
|
32
39
|
end
|
@@ -1,33 +1,38 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'support/feature_detection'
|
2
3
|
|
3
4
|
# Tests the automatic usage of `current_user` as the `whodunnit` attribute on the draft object
|
4
5
|
describe WhodunnitsController, type: :controller do
|
5
6
|
let(:trashable) { Trashable.create!(name: 'Bob') }
|
6
7
|
|
7
8
|
describe 'create' do
|
8
|
-
before { post :create }
|
9
|
-
subject { Draftsman::Draft.last }
|
10
|
-
|
11
9
|
it 'records `current_user` via `user_for_draftsman' do
|
12
|
-
|
10
|
+
post :create
|
11
|
+
expect(Draftsman::Draft.last.whodunnit).to eql '153'
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
16
15
|
describe 'update' do
|
17
|
-
before { put :update, id: trashable.id }
|
18
|
-
subject { Draftsman::Draft.last }
|
19
|
-
|
20
16
|
it 'records `current_user` via `user_for_draftsman' do
|
21
|
-
|
17
|
+
if request_test_helpers_require_keyword_args?
|
18
|
+
put :update, params: { id: trashable.id }
|
19
|
+
else
|
20
|
+
put :update, id: trashable.id
|
21
|
+
end
|
22
|
+
|
23
|
+
expect(Draftsman::Draft.last.whodunnit).to eql '153'
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
27
|
describe 'destroy' do
|
26
|
-
before { delete :destroy, id: trashable.id }
|
27
|
-
subject { Draftsman::Draft.last }
|
28
|
-
|
29
28
|
it 'records `current_user` via `user_for_draftsman' do
|
30
|
-
|
29
|
+
if request_test_helpers_require_keyword_args?
|
30
|
+
delete :destroy, params: { id: trashable.id }
|
31
|
+
else
|
32
|
+
delete :destroy, id: trashable.id
|
33
|
+
end
|
34
|
+
|
35
|
+
expect(Draftsman::Draft.last.whodunnit).to eql '153'
|
31
36
|
end
|
32
37
|
end
|
33
38
|
end
|
data/spec/models/child_spec.rb
CHANGED
@@ -4,7 +4,7 @@ RSpec.describe Child, type: :model do
|
|
4
4
|
let(:parent) { Parent.new(name: 'Marge') }
|
5
5
|
let(:child) { Child.new(name: 'Lisa', parent: parent) }
|
6
6
|
|
7
|
-
describe 'publish!' do
|
7
|
+
describe '#publish!' do
|
8
8
|
context 'parent `create` draft with child `create` draft' do
|
9
9
|
before do
|
10
10
|
parent.save_draft
|
@@ -74,7 +74,7 @@ RSpec.describe Child, type: :model do
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
describe 'revert!' do
|
77
|
+
describe '#revert!' do
|
78
78
|
context 'parent `create` draft with child `create` draft' do
|
79
79
|
before do
|
80
80
|
parent.save_draft
|
@@ -150,7 +150,7 @@ RSpec.describe Child, type: :model do
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
-
describe 'draft_publication_dependencies' do
|
153
|
+
describe '#draft_publication_dependencies' do
|
154
154
|
context 'parent `create` draft with child `create` draft' do
|
155
155
|
before do
|
156
156
|
parent.save_draft
|
@@ -228,7 +228,7 @@ RSpec.describe Child, type: :model do
|
|
228
228
|
end
|
229
229
|
end
|
230
230
|
|
231
|
-
describe 'draft_reversion_dependencies' do
|
231
|
+
describe '#draft_reversion_dependencies' do
|
232
232
|
context 'parent `create` draft with child `create` draft' do
|
233
233
|
before do
|
234
234
|
parent.save_draft
|
data/spec/models/skipper_spec.rb
CHANGED
@@ -1,10 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Skipper, type: :model do
|
4
|
-
let(:skipper) { Skipper.new
|
4
|
+
let(:skipper) { Skipper.new(name: 'Bob', skip_me: 'Skipped 1') }
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
describe '.draftable?' do
|
7
|
+
it 'is `true`' do
|
8
|
+
expect(subject.class.draftable?).to eql true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#object_attrs_for_draft_record' do
|
13
|
+
it 'contains changed but not skipped column name' do
|
14
|
+
expect(skipper.object_attrs_for_draft_record).to include 'name'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'does not contain the skipped column name' do
|
18
|
+
expect(skipper.object_attrs_for_draft_record).to_not include 'skip_me'
|
19
|
+
end
|
8
20
|
end
|
9
21
|
|
10
22
|
describe '#save_draft' do
|
@@ -41,6 +53,11 @@ RSpec.describe Skipper, type: :model do
|
|
41
53
|
it 'has a value for `skip_me`' do
|
42
54
|
expect(subject.skip_me).to eql 'Skipped 1'
|
43
55
|
end
|
56
|
+
|
57
|
+
it 'sets `updated_at`' do
|
58
|
+
time = Time.now
|
59
|
+
expect(subject.updated_at).to be > time
|
60
|
+
end
|
44
61
|
end
|
45
62
|
|
46
63
|
context 'on update' do
|
@@ -87,6 +104,11 @@ RSpec.describe Skipper, type: :model do
|
|
87
104
|
it 'creates a new draft' do
|
88
105
|
expect { subject }.to change(Draftsman::Draft, :count).by(1)
|
89
106
|
end
|
107
|
+
|
108
|
+
it 'has a newer `updated_at`' do
|
109
|
+
time = skipper.updated_at
|
110
|
+
expect(subject.updated_at).to be > time
|
111
|
+
end
|
90
112
|
end
|
91
113
|
|
92
114
|
describe 'changing back to initial state' do
|
@@ -123,10 +145,18 @@ RSpec.describe Skipper, type: :model do
|
|
123
145
|
it 'destroys the draft' do
|
124
146
|
expect { subject }.to change(Draftsman::Draft.where(:id => skipper.draft_id), :count).by(-1)
|
125
147
|
end
|
148
|
+
|
149
|
+
it 'has a newer `updated_at`' do
|
150
|
+
time = skipper.updated_at
|
151
|
+
expect(subject.updated_at).to be > time
|
152
|
+
end
|
126
153
|
end
|
127
154
|
|
128
155
|
context 'with existing `create` draft' do
|
129
|
-
before
|
156
|
+
before do
|
157
|
+
skipper.save_draft
|
158
|
+
skipper.reload
|
159
|
+
end
|
130
160
|
|
131
161
|
context 'with changes' do
|
132
162
|
before do
|
@@ -169,6 +199,33 @@ RSpec.describe Skipper, type: :model do
|
|
169
199
|
it "updates the draft's `name`" do
|
170
200
|
expect(subject.draft.reify.name).to eql 'Sam'
|
171
201
|
end
|
202
|
+
|
203
|
+
it 'has a newer `updated_at`' do
|
204
|
+
time = skipper.updated_at
|
205
|
+
expect(subject.updated_at).to be > time
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'with changes to drafted attribute' do
|
210
|
+
before do
|
211
|
+
skipper.name = 'Sam'
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'has a newer `updated_at`' do
|
215
|
+
time = skipper.updated_at
|
216
|
+
expect(subject.updated_at).to be > time
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context 'with changes to skipped attribute' do
|
221
|
+
before do
|
222
|
+
skipper.skip_me = 'Skipped 2'
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'has a newer `updated_at`' do
|
226
|
+
time = skipper.updated_at
|
227
|
+
expect(subject.updated_at).to be > time
|
228
|
+
end
|
172
229
|
end
|
173
230
|
|
174
231
|
context 'with no changes' do
|
@@ -203,6 +260,11 @@ RSpec.describe Skipper, type: :model do
|
|
203
260
|
it "doesn't change the number of drafts" do
|
204
261
|
expect { subject }.to_not change(Draftsman::Draft.where(:id => skipper.draft_id), :count)
|
205
262
|
end
|
263
|
+
|
264
|
+
it 'has the original `updated_at`' do
|
265
|
+
time = skipper.updated_at
|
266
|
+
expect(subject.updated_at).to eq time
|
267
|
+
end
|
206
268
|
end
|
207
269
|
end
|
208
270
|
|
@@ -254,14 +316,16 @@ RSpec.describe Skipper, type: :model do
|
|
254
316
|
it "updates the draft's `name`" do
|
255
317
|
expect(subject.draft.reify.name).to eql 'Steve'
|
256
318
|
end
|
319
|
+
|
320
|
+
it 'has the original `updated_at`' do
|
321
|
+
time = skipper.updated_at
|
322
|
+
expect(subject.updated_at).to eq time
|
323
|
+
end
|
257
324
|
end
|
258
325
|
|
259
326
|
context 'with changes to skipped attributes' do
|
260
327
|
before do
|
261
328
|
skipper.skip_me = 'Skip and save'
|
262
|
-
skipper.save_draft
|
263
|
-
skipper.reload
|
264
|
-
skipper.attributes = skipper.draft.reify.attributes
|
265
329
|
end
|
266
330
|
|
267
331
|
it 'is persisted' do
|
@@ -303,6 +367,11 @@ RSpec.describe Skipper, type: :model do
|
|
303
367
|
it 'updates skipped attribute on draft' do
|
304
368
|
expect(subject.draft.reify.skip_me).to eql 'Skip and save'
|
305
369
|
end
|
370
|
+
|
371
|
+
it 'has a newer `updated_at`' do
|
372
|
+
time = skipper.updated_at
|
373
|
+
expect(subject.updated_at).to be > time
|
374
|
+
end
|
306
375
|
end
|
307
376
|
|
308
377
|
context 'with no changes' do
|
@@ -341,6 +410,11 @@ RSpec.describe Skipper, type: :model do
|
|
341
410
|
it "does not update the draft's `name`" do
|
342
411
|
expect(subject.draft.reify.name).to eql 'Sam'
|
343
412
|
end
|
413
|
+
|
414
|
+
it 'has the original `updated_at`' do
|
415
|
+
time = skipper.updated_at
|
416
|
+
expect(subject.updated_at).to eq time
|
417
|
+
end
|
344
418
|
end
|
345
419
|
end
|
346
420
|
end
|
data/spec/models/vanilla_spec.rb
CHANGED
@@ -5,6 +5,20 @@ describe Vanilla do
|
|
5
5
|
let(:vanilla) { Vanilla.new(name: 'Bob') }
|
6
6
|
it { should be_draftable }
|
7
7
|
|
8
|
+
describe '#object_attrs_for_draft_record' do
|
9
|
+
it 'contains column name' do
|
10
|
+
expect(vanilla.object_attrs_for_draft_record).to include 'name'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'contains column updated_at' do
|
14
|
+
expect(vanilla.object_attrs_for_draft_record).to include 'updated_at'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'contains column created_at' do
|
18
|
+
expect(vanilla.object_attrs_for_draft_record).to include 'created_at'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
8
22
|
describe '#save_draft' do
|
9
23
|
context 'on create' do
|
10
24
|
it 'is persisted' do
|
@@ -36,6 +50,18 @@ describe Vanilla do
|
|
36
50
|
vanilla.save_draft
|
37
51
|
expect(vanilla.name).to eql 'Bob'
|
38
52
|
end
|
53
|
+
|
54
|
+
it 'sets `updated_at`' do
|
55
|
+
time = Time.now
|
56
|
+
vanilla.save_draft
|
57
|
+
expect(vanilla.updated_at).to be > time
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'sets `created_at`' do
|
61
|
+
time = Time.now
|
62
|
+
vanilla.save_draft
|
63
|
+
expect(vanilla.created_at).to be > time
|
64
|
+
end
|
39
65
|
end
|
40
66
|
|
41
67
|
context 'on update' do
|
@@ -84,6 +110,12 @@ describe Vanilla do
|
|
84
110
|
it 'creates a new draft' do
|
85
111
|
expect { vanilla.save_draft }.to change(Draftsman::Draft, :count).by(1)
|
86
112
|
end
|
113
|
+
|
114
|
+
it 'has the original `updated_at`' do
|
115
|
+
vanilla.save_draft
|
116
|
+
vanilla.reload
|
117
|
+
expect(vanilla.updated_at).to eq vanilla.created_at
|
118
|
+
end
|
87
119
|
end
|
88
120
|
|
89
121
|
describe 'changing back to initial state' do
|
@@ -123,6 +155,14 @@ describe Vanilla do
|
|
123
155
|
it 'destroys the draft' do
|
124
156
|
expect { vanilla.save_draft }.to change(Draftsman::Draft.where(id: vanilla.draft_id), :count).by(-1)
|
125
157
|
end
|
158
|
+
|
159
|
+
it 'has the original `updated_at`' do
|
160
|
+
if activerecord_save_touch_option?
|
161
|
+
vanilla.save_draft
|
162
|
+
vanilla.reload
|
163
|
+
expect(vanilla.updated_at).to eq vanilla.created_at
|
164
|
+
end
|
165
|
+
end
|
126
166
|
end
|
127
167
|
|
128
168
|
context 'with existing `create` draft' do
|
@@ -176,6 +216,13 @@ describe Vanilla do
|
|
176
216
|
vanilla.reload
|
177
217
|
expect(vanilla.draft.create?).to eql true
|
178
218
|
end
|
219
|
+
|
220
|
+
it 'has a new `updated_at`' do
|
221
|
+
time = vanilla.updated_at
|
222
|
+
vanilla.save_draft
|
223
|
+
vanilla.reload
|
224
|
+
expect(vanilla.updated_at).to be > time
|
225
|
+
end
|
179
226
|
end # with changes
|
180
227
|
|
181
228
|
context 'with no changes' do
|
@@ -217,6 +264,12 @@ describe Vanilla do
|
|
217
264
|
it "doesn't change the number of drafts" do
|
218
265
|
expect { vanilla.save_draft }.to_not change(Draftsman::Draft.where(id: vanilla.draft_id), :count)
|
219
266
|
end
|
267
|
+
|
268
|
+
it 'has the original `updated_at`' do
|
269
|
+
vanilla.save_draft
|
270
|
+
vanilla.reload
|
271
|
+
expect(vanilla.updated_at).to eq vanilla.created_at
|
272
|
+
end
|
220
273
|
end
|
221
274
|
end # with no changes
|
222
275
|
|
@@ -275,6 +328,12 @@ describe Vanilla do
|
|
275
328
|
vanilla.save_draft
|
276
329
|
expect(vanilla.draft.update?).to eql true
|
277
330
|
end
|
331
|
+
|
332
|
+
it 'has the original `updated_at`' do
|
333
|
+
vanilla.save_draft
|
334
|
+
vanilla.reload
|
335
|
+
expect(vanilla.updated_at).to eq vanilla.created_at
|
336
|
+
end
|
278
337
|
end # with changes
|
279
338
|
|
280
339
|
context 'with no changes' do
|
@@ -322,6 +381,12 @@ describe Vanilla do
|
|
322
381
|
vanilla.reload
|
323
382
|
expect(vanilla.draft.reify.name).to eql 'Sam'
|
324
383
|
end
|
384
|
+
|
385
|
+
it 'has the original `updated_at`' do
|
386
|
+
vanilla.save_draft
|
387
|
+
vanilla.reload
|
388
|
+
expect(vanilla.updated_at).to eq vanilla.created_at
|
389
|
+
end
|
325
390
|
end # with no changes
|
326
391
|
end # with existing `update` draft
|
327
392
|
end # with stashed drafted changes
|
@@ -374,6 +439,13 @@ describe Vanilla do
|
|
374
439
|
it 'creates a new draft' do
|
375
440
|
expect { vanilla.save_draft }.to change(Draftsman::Draft, :count).by(1)
|
376
441
|
end
|
442
|
+
|
443
|
+
it 'has a new `updated_at`' do
|
444
|
+
time = vanilla.updated_at
|
445
|
+
vanilla.save_draft
|
446
|
+
vanilla.reload
|
447
|
+
expect(vanilla.updated_at).to be > time
|
448
|
+
end
|
377
449
|
end
|
378
450
|
|
379
451
|
describe 'changing back to initial state' do
|
@@ -413,6 +485,13 @@ describe Vanilla do
|
|
413
485
|
it 'destroys the draft' do
|
414
486
|
expect { vanilla.save_draft }.to change(Draftsman::Draft.where(id: vanilla.draft_id), :count).by(-1)
|
415
487
|
end
|
488
|
+
|
489
|
+
it 'has a new `updated_at`' do
|
490
|
+
time = vanilla.updated_at
|
491
|
+
vanilla.save_draft
|
492
|
+
vanilla.reload
|
493
|
+
expect(vanilla.updated_at).to be > time
|
494
|
+
end
|
416
495
|
end
|
417
496
|
|
418
497
|
context 'with existing `create` draft' do
|
@@ -459,6 +538,13 @@ describe Vanilla do
|
|
459
538
|
vanilla.save_draft
|
460
539
|
expect(vanilla.draft.create?).to eql true
|
461
540
|
end
|
541
|
+
|
542
|
+
it 'has a new `updated_at`' do
|
543
|
+
time = vanilla.updated_at
|
544
|
+
vanilla.save_draft
|
545
|
+
vanilla.reload
|
546
|
+
expect(vanilla.updated_at).to be > time
|
547
|
+
end
|
462
548
|
end
|
463
549
|
|
464
550
|
context 'with no changes' do
|
@@ -494,6 +580,11 @@ describe Vanilla do
|
|
494
580
|
it "doesn't change the number of drafts" do
|
495
581
|
expect { vanilla.save_draft }.to_not change(Draftsman::Draft.where(id: vanilla.draft_id), :count)
|
496
582
|
end
|
583
|
+
|
584
|
+
it 'has the original `updated_at`' do
|
585
|
+
vanilla.save_draft
|
586
|
+
expect(vanilla.reload.updated_at).to eq vanilla.created_at
|
587
|
+
end
|
497
588
|
end
|
498
589
|
end
|
499
590
|
|
@@ -553,6 +644,13 @@ describe Vanilla do
|
|
553
644
|
vanilla.reload
|
554
645
|
expect(vanilla.draft.update?).to eql true
|
555
646
|
end
|
647
|
+
|
648
|
+
it 'has a new `updated_at`' do
|
649
|
+
time = vanilla.updated_at
|
650
|
+
vanilla.save_draft
|
651
|
+
vanilla.reload
|
652
|
+
expect(vanilla.updated_at).to be > time
|
653
|
+
end
|
556
654
|
end # with changes
|
557
655
|
|
558
656
|
context 'with no changes' do
|
@@ -594,6 +692,13 @@ describe Vanilla do
|
|
594
692
|
vanilla.save_draft
|
595
693
|
expect(vanilla.draft.reify.name).to eql 'Sam'
|
596
694
|
end
|
695
|
+
|
696
|
+
it 'does not update `updated_at`' do
|
697
|
+
time = vanilla.updated_at
|
698
|
+
vanilla.save_draft
|
699
|
+
vanilla.reload
|
700
|
+
expect(vanilla.updated_at).to eq time
|
701
|
+
end
|
597
702
|
end # with no changes
|
598
703
|
end # with existing `update` draft
|
599
704
|
end # without stashed drafted changes
|
@@ -4,6 +4,18 @@ describe Whitelister do
|
|
4
4
|
let(:whitelister) { Whitelister.new(name: 'Bob') }
|
5
5
|
it { should be_draftable }
|
6
6
|
|
7
|
+
describe '#object_attrs_for_draft_record' do
|
8
|
+
before { whitelister.ignored = 'Meh.' }
|
9
|
+
|
10
|
+
it 'contains included column name' do
|
11
|
+
expect(whitelister.object_attrs_for_draft_record).to include 'name'
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'does not include non-included column name' do
|
15
|
+
expect(whitelister.object_attrs_for_draft_record).to include 'name'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
7
19
|
describe '#save_draft' do
|
8
20
|
# Not affected by this customization.
|
9
21
|
context 'on create' do
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Returns whether or not Rails test helpers recommend or require keyword
|
2
|
+
# arguments for controller/request helpers.
|
3
|
+
def request_test_helpers_require_keyword_args?
|
4
|
+
ActiveRecord::VERSION::STRING.to_f >= 5.0
|
5
|
+
end
|
6
|
+
|
7
|
+
# Returns whether or not the current version of ActiveRecord supports the
|
8
|
+
# `touch` option for `#save`.
|
9
|
+
def activerecord_save_touch_option?
|
10
|
+
ActiveRecord::VERSION::STRING.to_f >= 5.0
|
11
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: draftsman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Peters
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '5.
|
22
|
+
version: '5.2'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '4.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '5.
|
32
|
+
version: '5.2'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rake
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,20 +50,20 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '4.0'
|
54
54
|
- - "<"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '5.
|
56
|
+
version: '5.2'
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
61
|
- - ">="
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: '
|
63
|
+
version: '4.0'
|
64
64
|
- - "<"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: '5.
|
66
|
+
version: '5.2'
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: sinatra
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +122,9 @@ files:
|
|
122
122
|
- README.md
|
123
123
|
- Rakefile
|
124
124
|
- draftsman.gemspec
|
125
|
+
- gemfiles/ar_4_2.gemfile
|
126
|
+
- gemfiles/ar_5_0.gemfile
|
127
|
+
- gemfiles/ar_5_1.gemfile
|
125
128
|
- lib/draftsman.rb
|
126
129
|
- lib/draftsman/attributes_serialization.rb
|
127
130
|
- lib/draftsman/config.rb
|
@@ -204,6 +207,7 @@ files:
|
|
204
207
|
- spec/models/vanilla_spec.rb
|
205
208
|
- spec/models/whitelister_spec.rb
|
206
209
|
- spec/spec_helper.rb
|
210
|
+
- spec/support/feature_detection.rb
|
207
211
|
homepage: https://github.com/liveeditor/draftsman
|
208
212
|
licenses:
|
209
213
|
- MIT
|
@@ -224,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
224
228
|
version: '0'
|
225
229
|
requirements: []
|
226
230
|
rubyforge_project:
|
227
|
-
rubygems_version: 2.
|
231
|
+
rubygems_version: 2.6.11
|
228
232
|
signing_key:
|
229
233
|
specification_version: 4
|
230
234
|
summary: Create draft versions of your database records.
|
@@ -293,3 +297,4 @@ test_files:
|
|
293
297
|
- spec/models/vanilla_spec.rb
|
294
298
|
- spec/models/whitelister_spec.rb
|
295
299
|
- spec/spec_helper.rb
|
300
|
+
- spec/support/feature_detection.rb
|