paper_trail 3.0.9 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +1 -2
- data/.travis.yml +5 -0
- data/CHANGELOG.md +37 -23
- data/README.md +170 -63
- data/gemfiles/3.0.gemfile +10 -4
- data/lib/generators/paper_trail/install_generator.rb +19 -3
- data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb +11 -0
- data/lib/generators/paper_trail/templates/create_version_associations.rb +17 -0
- data/lib/paper_trail.rb +24 -4
- data/lib/paper_trail/cleaner.rb +3 -3
- data/lib/paper_trail/config.rb +17 -0
- data/lib/paper_trail/frameworks/active_record/models/paper_trail/version_association.rb +7 -0
- data/lib/paper_trail/frameworks/rails.rb +1 -0
- data/lib/paper_trail/frameworks/rspec.rb +5 -0
- data/lib/paper_trail/has_paper_trail.rb +112 -38
- data/lib/paper_trail/version_association_concern.rb +13 -0
- data/lib/paper_trail/version_concern.rb +145 -38
- data/lib/paper_trail/version_number.rb +3 -3
- data/paper_trail.gemspec +11 -4
- data/spec/generators/install_generator_spec.rb +4 -4
- data/spec/models/fluxor_spec.rb +19 -0
- data/spec/models/gadget_spec.rb +10 -10
- data/spec/models/joined_version_spec.rb +9 -9
- data/spec/models/post_with_status_spec.rb +3 -3
- data/spec/models/version_spec.rb +49 -71
- data/spec/models/widget_spec.rb +124 -71
- data/spec/modules/version_concern_spec.rb +8 -8
- data/spec/modules/version_number_spec.rb +16 -16
- data/spec/paper_trail_spec.rb +17 -17
- data/spec/rails_helper.rb +34 -0
- data/spec/requests/articles_spec.rb +11 -11
- data/spec/spec_helper.rb +77 -36
- data/test/dummy/app/models/animal.rb +0 -2
- data/test/dummy/app/models/book.rb +4 -0
- data/test/dummy/app/models/customer.rb +4 -0
- data/test/dummy/app/models/editor.rb +4 -0
- data/test/dummy/app/models/editorship.rb +5 -0
- data/test/dummy/app/models/line_item.rb +4 -0
- data/test/dummy/app/models/order.rb +5 -0
- data/test/dummy/app/models/person.rb +1 -1
- data/test/dummy/app/models/post.rb +0 -1
- data/test/dummy/app/models/song.rb +0 -20
- data/test/dummy/app/models/widget.rb +4 -0
- data/test/dummy/config/application.rb +3 -0
- data/test/dummy/config/initializers/paper_trail.rb +1 -1
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +41 -0
- data/test/dummy/db/schema.rb +95 -25
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/javascripts/application.js +2 -0
- data/test/dummy/public/javascripts/controls.js +965 -0
- data/test/dummy/public/javascripts/dragdrop.js +974 -0
- data/test/dummy/public/javascripts/effects.js +1123 -0
- data/test/dummy/public/javascripts/rails.js +175 -0
- data/test/dummy/public/stylesheets/.gitkeep +0 -0
- data/test/test_helper.rb +2 -2
- data/test/time_travel_helper.rb +15 -0
- data/test/unit/model_test.rb +613 -185
- data/test/unit/serializer_test.rb +3 -3
- metadata +104 -54
- data/spec/models/animal_spec.rb +0 -19
- data/test/dummy/public/javascripts/prototype.js +0 -6001
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module PaperTrail
|
4
|
+
module VersionAssociationConcern
|
5
|
+
extend ::ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
belongs_to :version
|
9
|
+
|
10
|
+
attr_accessible :version_id, :foreign_key_name, :foreign_key_id if PaperTrail.active_record_protected_attributes?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -6,10 +6,15 @@ module PaperTrail
|
|
6
6
|
|
7
7
|
included do
|
8
8
|
belongs_to :item, :polymorphic => true
|
9
|
+
has_many :version_associations, :dependent => :destroy
|
10
|
+
|
9
11
|
validates_presence_of :event
|
10
|
-
|
12
|
+
|
13
|
+
attr_accessible :item_type, :item_id, :event, :whodunnit, :object, :object_changes, :transaction_id, :created_at if PaperTrail.active_record_protected_attributes?
|
11
14
|
|
12
15
|
after_create :enforce_version_limit!
|
16
|
+
|
17
|
+
scope :within_transaction, lambda { |id| where :transaction_id => id }
|
13
18
|
end
|
14
19
|
|
15
20
|
module ClassMethods
|
@@ -102,21 +107,28 @@ module PaperTrail
|
|
102
107
|
|
103
108
|
# Restore the item from this version.
|
104
109
|
#
|
105
|
-
#
|
106
|
-
# if they are also being versioned by PaperTrail.
|
107
|
-
# to work so you can either change the lookback period (from the default 3 seconds) or
|
108
|
-
# opt out.
|
110
|
+
# Optionally this can also restore all :has_one and :has_many (including has_many :through) associations as
|
111
|
+
# they were "at the time", if they are also being versioned by PaperTrail.
|
109
112
|
#
|
110
113
|
# Options:
|
111
|
-
# :has_one
|
112
|
-
#
|
113
|
-
#
|
114
|
+
# :has_one set to `true` to also reify has_one associations. Default is `false`.
|
115
|
+
# :has_many set to `true` to also reify has_many and has_many :through associations.
|
116
|
+
# Default is `false`.
|
117
|
+
# :mark_for_destruction set to `true` to mark the has_one/has_many associations that did not exist in the
|
118
|
+
# reified version for destruction, instead of remove them. Default is `false`.
|
119
|
+
# This option is handy for people who want to persist the reified version.
|
120
|
+
# :dup `false` default behavior
|
121
|
+
# `true` it always create a new object instance. It is useful for comparing two versions of the same object
|
114
122
|
def reify(options = {})
|
115
123
|
return nil if object.nil?
|
116
124
|
|
117
125
|
without_identity_map do
|
118
|
-
options
|
119
|
-
|
126
|
+
options.reverse_merge!(
|
127
|
+
:version_at => created_at,
|
128
|
+
:mark_for_destruction => false,
|
129
|
+
:has_one => false,
|
130
|
+
:has_many => false
|
131
|
+
)
|
120
132
|
|
121
133
|
attrs = self.class.object_col_is_json? ? object : PaperTrail.serializer.load(object)
|
122
134
|
|
@@ -133,7 +145,7 @@ module PaperTrail
|
|
133
145
|
# `item_type` will be the base class, not the actual subclass.
|
134
146
|
# If `type` is present but empty, the class is the base class.
|
135
147
|
|
136
|
-
if item
|
148
|
+
if item && options[:dup] != true
|
137
149
|
model = item
|
138
150
|
# Look for attributes that exist in the model and not in this version. These attributes should be set to nil.
|
139
151
|
(model.attribute_names - attrs.keys).each { |k| attrs[k] = nil }
|
@@ -144,14 +156,14 @@ module PaperTrail
|
|
144
156
|
model = klass.new
|
145
157
|
end
|
146
158
|
|
147
|
-
|
159
|
+
if PaperTrail.serialized_attributes?
|
160
|
+
model.class.unserialize_attributes_for_paper_trail attrs
|
161
|
+
end
|
148
162
|
|
149
163
|
# Set all the attributes in this version on the model
|
150
164
|
attrs.each do |k, v|
|
151
165
|
if model.has_attribute?(k)
|
152
166
|
model[k.to_sym] = v
|
153
|
-
elsif model.respond_to?("#{k}=")
|
154
|
-
model.send("#{k}=", v)
|
155
167
|
else
|
156
168
|
logger.warn "Attribute #{k} does not exist on #{item_type} (Version id: #{id})."
|
157
169
|
end
|
@@ -160,34 +172,35 @@ module PaperTrail
|
|
160
172
|
model.send "#{model.class.version_association_name}=", self
|
161
173
|
|
162
174
|
unless options[:has_one] == false
|
163
|
-
reify_has_ones model, options
|
175
|
+
reify_has_ones model, options
|
176
|
+
end
|
177
|
+
|
178
|
+
unless options[:has_many] == false
|
179
|
+
reify_has_manys model, options
|
164
180
|
end
|
165
181
|
|
166
182
|
model
|
167
183
|
end
|
168
184
|
end
|
169
185
|
|
170
|
-
# Returns what changed in this version of the item.
|
171
|
-
#
|
186
|
+
# Returns what changed in this version of the item. `ActiveModel::Dirty#changes`.
|
187
|
+
# returns `nil` if your `versions` table does not have an `object_changes` text column.
|
172
188
|
def changeset
|
173
189
|
return nil unless self.class.column_names.include? 'object_changes'
|
174
190
|
|
175
191
|
_changes = self.class.object_changes_col_is_json? ? object_changes : PaperTrail.serializer.load(object_changes)
|
176
192
|
@changeset ||= HashWithIndifferentAccess.new(_changes).tap do |changes|
|
177
|
-
|
193
|
+
if PaperTrail.serialized_attributes?
|
194
|
+
item_type.constantize.unserialize_attribute_changes(changes)
|
195
|
+
end
|
178
196
|
end
|
179
197
|
rescue
|
180
198
|
{}
|
181
199
|
end
|
182
200
|
|
183
201
|
# Returns who put the item into the state stored in this version.
|
184
|
-
def paper_trail_originator
|
185
|
-
@paper_trail_originator ||= previous.whodunnit rescue nil
|
186
|
-
end
|
187
|
-
|
188
202
|
def originator
|
189
|
-
|
190
|
-
self.paper_trail_originator
|
203
|
+
@originator ||= previous.whodunnit rescue nil
|
191
204
|
end
|
192
205
|
|
193
206
|
# Returns who changed the item from the state it had in this version.
|
@@ -236,25 +249,119 @@ module PaperTrail
|
|
236
249
|
# Restore the `model`'s has_one associations as they were when this version was
|
237
250
|
# superseded by the next (because that's what the user was looking at when they
|
238
251
|
# made the change).
|
239
|
-
|
240
|
-
|
241
|
-
def reify_has_ones(model, lookback)
|
252
|
+
def reify_has_ones(model, options = {})
|
253
|
+
version_table_name = model.class.paper_trail_version_class.table_name
|
242
254
|
model.class.reflect_on_all_associations(:has_one).each do |assoc|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
if
|
251
|
-
|
252
|
-
|
255
|
+
if assoc.klass.paper_trail_enabled_for_model?
|
256
|
+
version = model.class.paper_trail_version_class.joins(:version_associations).
|
257
|
+
where("version_associations.foreign_key_name = ?", assoc.foreign_key).
|
258
|
+
where("version_associations.foreign_key_id = ?", model.id).
|
259
|
+
where("#{version_table_name}.item_type = ?", assoc.class_name).
|
260
|
+
where("created_at >= ? OR transaction_id = ?", options[:version_at], transaction_id).
|
261
|
+
order("#{version_table_name}.id ASC").first
|
262
|
+
if version
|
263
|
+
if version.event == 'create'
|
264
|
+
if options[:mark_for_destruction]
|
265
|
+
model.send(assoc.name).mark_for_destruction if model.send(assoc.name, true)
|
266
|
+
else
|
267
|
+
model.appear_as_new_record do
|
268
|
+
model.send "#{assoc.name}=", nil
|
269
|
+
end
|
270
|
+
end
|
271
|
+
else
|
272
|
+
child = version.reify(options.merge(:has_many => false, :has_one => false))
|
273
|
+
model.appear_as_new_record do
|
274
|
+
model.send "#{assoc.name}=", child
|
275
|
+
end
|
253
276
|
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
# Restore the `model`'s has_many associations as they were at version_at timestamp
|
283
|
+
# We lookup the first child versions after version_at timestamp or in same transaction.
|
284
|
+
def reify_has_manys(model, options = {})
|
285
|
+
assoc_has_many_through, assoc_has_many_directly =
|
286
|
+
model.class.reflect_on_all_associations(:has_many).partition { |assoc| assoc.options[:through] }
|
287
|
+
reify_has_many_directly(assoc_has_many_directly, model, options)
|
288
|
+
reify_has_many_through(assoc_has_many_through, model, options)
|
289
|
+
end
|
290
|
+
|
291
|
+
# Restore the `model`'s has_many associations not associated through another association
|
292
|
+
def reify_has_many_directly(associations, model, options = {})
|
293
|
+
version_table_name = model.class.paper_trail_version_class.table_name
|
294
|
+
associations.each do |assoc|
|
295
|
+
next unless assoc.klass.paper_trail_enabled_for_model?
|
296
|
+
version_id_subquery = PaperTrail::VersionAssociation.joins(model.class.version_association_name).
|
297
|
+
select("MIN(version_id)").
|
298
|
+
where("foreign_key_name = ?", assoc.foreign_key).
|
299
|
+
where("foreign_key_id = ?", model.id).
|
300
|
+
where("#{version_table_name}.item_type = ?", assoc.class_name).
|
301
|
+
where("created_at >= ? OR transaction_id = ?", options[:version_at], transaction_id).
|
302
|
+
group("item_id").to_sql
|
303
|
+
versions = model.class.paper_trail_version_class.where("id IN (#{version_id_subquery})").inject({}) do |acc, v|
|
304
|
+
acc.merge!(v.item_id => v)
|
305
|
+
end
|
306
|
+
|
307
|
+
# Pass true to force the model to load
|
308
|
+
collection = Array.new model.send(assoc.name, true)
|
309
|
+
|
310
|
+
# Iterate each child to replace it with the previous value if there is a version after the timestamp
|
311
|
+
collection.map! do |c|
|
312
|
+
if (version = versions.delete(c.id)).nil?
|
313
|
+
c
|
314
|
+
elsif version.event == 'create'
|
315
|
+
options[:mark_for_destruction] ? c.tap { |r| r.mark_for_destruction } : nil
|
316
|
+
else
|
317
|
+
version.reify(options.merge(:has_many => false, :has_one => false))
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
# Reify the rest of the versions and add them to the collection, these versions are for those that
|
322
|
+
# have been removed from the live associations
|
323
|
+
collection += versions.values.map { |version| version.reify(options.merge(:has_many => false, :has_one => false)) }
|
324
|
+
|
325
|
+
model.send(assoc.name).proxy_association.target = collection.compact
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
# Restore the `model`'s has_many associations through another association
|
330
|
+
# This must be called after the direct has_manys have been reified (reify_has_many_directly)
|
331
|
+
def reify_has_many_through(associations, model, options = {})
|
332
|
+
associations.each do |assoc|
|
333
|
+
next unless assoc.klass.paper_trail_enabled_for_model?
|
334
|
+
through_collection = model.send(assoc.options[:through])
|
335
|
+
collection_keys = through_collection.map { |through_model| through_model.send(assoc.foreign_key) }
|
336
|
+
|
337
|
+
version_id_subquery = assoc.klass.paper_trail_version_class.
|
338
|
+
select("MIN(id)").
|
339
|
+
where("item_type = ?", assoc.class_name).
|
340
|
+
where("item_id IN (?)", collection_keys).
|
341
|
+
where("created_at >= ? OR transaction_id = ?", options[:version_at], transaction_id).
|
342
|
+
group("item_id").to_sql
|
343
|
+
versions = assoc.klass.paper_trail_version_class.where("id IN (#{version_id_subquery})").inject({}) do |acc, v|
|
344
|
+
acc.merge!(v.item_id => v)
|
345
|
+
end
|
346
|
+
|
347
|
+
collection = Array.new assoc.klass.where(assoc.klass.primary_key => collection_keys)
|
348
|
+
|
349
|
+
# Iterate each child to replace it with the previous value if there is a version after the timestamp
|
350
|
+
collection.map! do |c|
|
351
|
+
if (version = versions.delete(c.id)).nil?
|
352
|
+
c
|
353
|
+
elsif version.event == 'create'
|
354
|
+
options[:mark_for_destruction] ? c.tap { |r| r.mark_for_destruction } : nil
|
254
355
|
else
|
255
|
-
|
356
|
+
version.reify(options.merge(:has_many => false, :has_one => false))
|
256
357
|
end
|
257
358
|
end
|
359
|
+
|
360
|
+
# Reify the rest of the versions and add them to the collection, these versions are for those that
|
361
|
+
# have been removed from the live associations
|
362
|
+
collection += versions.values.map { |version| version.reify(options.merge(:has_many => false, :has_one => false)) }
|
363
|
+
|
364
|
+
model.send(assoc.name).proxy_association.target = collection.compact
|
258
365
|
end
|
259
366
|
end
|
260
367
|
|
data/paper_trail.gemspec
CHANGED
@@ -19,20 +19,27 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.required_rubygems_version = '>= 1.3.6'
|
21
21
|
|
22
|
-
s.add_dependency 'activerecord', ['>= 3.0', '<
|
23
|
-
s.add_dependency 'activesupport', ['>= 3.0', '<
|
22
|
+
s.add_dependency 'activerecord', ['>= 3.0', '< 6.0']
|
23
|
+
s.add_dependency 'activesupport', ['>= 3.0', '< 6.0']
|
24
24
|
|
25
25
|
s.add_development_dependency 'rake', '~> 10.1.1'
|
26
26
|
s.add_development_dependency 'shoulda', '~> 3.5'
|
27
27
|
# s.add_development_dependency 'shoulda-matchers', '~> 1.5' # needed for ActiveRecord < 4
|
28
|
-
s.add_development_dependency 'ffaker',
|
28
|
+
s.add_development_dependency 'ffaker', '>= 1.15'
|
29
29
|
s.add_development_dependency 'railties', ['>= 3.0', '< 5.0']
|
30
30
|
s.add_development_dependency 'sinatra', '~> 1.0'
|
31
31
|
s.add_development_dependency 'rack-test', '>= 0.6'
|
32
|
-
s.add_development_dependency 'rspec-rails', '~>
|
32
|
+
s.add_development_dependency 'rspec-rails', '~> 3.1.0'
|
33
33
|
s.add_development_dependency 'generator_spec'
|
34
34
|
s.add_development_dependency 'database_cleaner', '~> 1.2'
|
35
35
|
|
36
|
+
# Allow time travel in testing. timecop is only supported after 1.9.2 but does a better cleanup at 'return'
|
37
|
+
if RUBY_VERSION < "1.9.2"
|
38
|
+
s.add_development_dependency 'delorean'
|
39
|
+
else
|
40
|
+
s.add_development_dependency 'timecop'
|
41
|
+
end
|
42
|
+
|
36
43
|
# JRuby support for the test ENV
|
37
44
|
unless defined?(JRUBY_VERSION)
|
38
45
|
s.add_development_dependency 'sqlite3', '~> 1.2'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'rails_helper'
|
2
2
|
require 'generator_spec/test_case'
|
3
3
|
require File.expand_path('../../../lib/generators/paper_trail/install_generator', __FILE__)
|
4
4
|
|
@@ -15,7 +15,7 @@ describe PaperTrail::InstallGenerator, :type => :generator do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it "generates a migration for creating the 'versions' table" do
|
18
|
-
destination_root.
|
18
|
+
expect(destination_root).to have_structure {
|
19
19
|
directory 'db' do
|
20
20
|
directory 'migrate' do
|
21
21
|
migration 'create_versions' do
|
@@ -36,7 +36,7 @@ describe PaperTrail::InstallGenerator, :type => :generator do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "generates a migration for creating the 'versions' table" do
|
39
|
-
destination_root.
|
39
|
+
expect(destination_root).to have_structure {
|
40
40
|
directory 'db' do
|
41
41
|
directory 'migrate' do
|
42
42
|
migration 'create_versions' do
|
@@ -50,7 +50,7 @@ describe PaperTrail::InstallGenerator, :type => :generator do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
it "generates a migration for adding the 'object_changes' column to the 'versions' table" do
|
53
|
-
destination_root.
|
53
|
+
expect(destination_root).to have_structure {
|
54
54
|
directory 'db' do
|
55
55
|
directory 'migrate' do
|
56
56
|
migration 'add_object_changes_to_versions' do
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe Fluxor, :type => :model do
|
4
|
+
describe '`be_versioned` matcher' do
|
5
|
+
it { is_expected.to_not be_versioned }
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "Methods" do
|
9
|
+
describe "Class" do
|
10
|
+
subject { Fluxor }
|
11
|
+
|
12
|
+
describe "#paper_trail_enabled_for_model?" do
|
13
|
+
it { is_expected.to respond_to(:paper_trail_enabled_for_model?) }
|
14
|
+
|
15
|
+
it { expect(subject.paper_trail_enabled_for_model?).to be false }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/spec/models/gadget_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require '
|
1
|
+
require 'rails_helper'
|
2
2
|
|
3
|
-
describe Gadget do
|
4
|
-
it {
|
3
|
+
describe Gadget, :type => :model do
|
4
|
+
it { is_expected.to be_versioned }
|
5
5
|
|
6
6
|
let(:gadget) { Gadget.create!(:name => 'Wrench', :brand => 'Acme') }
|
7
7
|
|
@@ -22,16 +22,16 @@ describe Gadget do
|
|
22
22
|
describe "Methods" do
|
23
23
|
describe "Instance", :versioning => true do
|
24
24
|
describe "private" do
|
25
|
-
describe
|
25
|
+
describe '#changed_notably?' do
|
26
26
|
subject { Gadget.new(:created_at => Time.now) }
|
27
27
|
|
28
28
|
# apparently the private methods list in Ruby18 is different than in Ruby19+
|
29
29
|
if RUBY_VERSION.to_f >= 1.9
|
30
|
-
|
30
|
+
it { expect(subject.private_methods).to include(:changed_notably?) }
|
31
31
|
end
|
32
32
|
|
33
33
|
context "create events" do
|
34
|
-
it { subject.send(:changed_notably?).
|
34
|
+
it { expect(subject.send(:changed_notably?)).to be true }
|
35
35
|
end
|
36
36
|
|
37
37
|
context "update events" do
|
@@ -40,24 +40,24 @@ describe Gadget do
|
|
40
40
|
context "without update timestamps" do
|
41
41
|
it "should only acknowledge non-ignored attrs" do
|
42
42
|
subject.name = 'Wrench'
|
43
|
-
subject.send(:changed_notably?).
|
43
|
+
expect(subject.send(:changed_notably?)).to be true
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should not acknowledge ignored attrs and timestamps only" do
|
47
47
|
subject.brand = 'Acme'
|
48
|
-
subject.send(:changed_notably?).
|
48
|
+
expect(subject.send(:changed_notably?)).to be false
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
context "with update timestamps" do
|
53
53
|
it "should only acknowledge non-ignored attrs" do
|
54
54
|
subject.name, subject.updated_at = 'Wrench', Time.now
|
55
|
-
subject.send(:changed_notably?).
|
55
|
+
expect(subject.send(:changed_notably?)).to be true
|
56
56
|
end
|
57
57
|
|
58
58
|
it "should not acknowledge ignored attrs and timestamps only" do
|
59
59
|
subject.brand, subject.updated_at = 'Acme', Time.now
|
60
|
-
subject.send(:changed_notably?).
|
60
|
+
expect(subject.send(:changed_notably?)).to be false
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -1,32 +1,32 @@
|
|
1
|
-
require '
|
1
|
+
require 'rails_helper'
|
2
2
|
|
3
|
-
describe JoinedVersion, :versioning => true do
|
4
|
-
it { JoinedVersion.superclass.
|
3
|
+
describe JoinedVersion, :type => :model, :versioning => true do
|
4
|
+
it { expect(JoinedVersion.superclass).to be PaperTrail::Version }
|
5
5
|
|
6
6
|
let(:widget) { Widget.create!(:name => Faker::Name.name) }
|
7
7
|
let(:version) { JoinedVersion.first }
|
8
8
|
|
9
9
|
describe "Scopes" do
|
10
10
|
describe "default_scope" do
|
11
|
-
it { JoinedVersion.default_scopes.
|
11
|
+
it { expect(JoinedVersion.default_scopes).not_to be_empty }
|
12
12
|
end
|
13
13
|
|
14
14
|
describe "VersionConcern::ClassMethods" do
|
15
15
|
before { widget } # persist a widget
|
16
16
|
|
17
|
-
describe
|
17
|
+
describe '#subsequent' do
|
18
18
|
it "shouldn't error out when there is a default_scope that joins" do
|
19
19
|
JoinedVersion.subsequent(version).first
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
describe
|
23
|
+
describe '#preceding' do
|
24
24
|
it "shouldn't error out when there is a default scope that joins" do
|
25
25
|
JoinedVersion.preceding(version).first
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
describe
|
29
|
+
describe '#between' do
|
30
30
|
it "shouldn't error out when there is a default scope that joins" do
|
31
31
|
JoinedVersion.between(Time.now, 1.minute.from_now).first
|
32
32
|
end
|
@@ -35,8 +35,8 @@ describe JoinedVersion, :versioning => true do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
describe "Methods" do
|
38
|
-
describe
|
39
|
-
it {
|
38
|
+
describe '#index' do
|
39
|
+
it { is_expected.to respond_to(:index) }
|
40
40
|
|
41
41
|
it "shouldn't error out when there is a default scope that joins" do
|
42
42
|
widget # persist a widget
|