drafter 0.2.8 → 0.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.
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/VERSION +1 -1
- data/drafter.gemspec +9 -2
- data/lib/drafter/apply.rb +56 -1
- data/lib/drafter/creation.rb +48 -18
- data/lib/drafter/diffing.rb +1 -1
- data/lib/drafter/draft.rb +15 -0
- data/lib/drafter/draftable.rb +4 -0
- data/lib/drafter/id_hash.rb +46 -0
- data/lib/drafter/subdrafts.rb +23 -0
- data/lib/drafter.rb +19 -3
- data/test/drafter/test_apply.rb +94 -2
- data/test/drafter/test_creation.rb +41 -1
- data/test/drafter/test_diffing.rb +5 -1
- data/test/drafter/test_draft.rb +188 -16
- data/test/drafter/test_draftable.rb +1 -15
- data/test/drafter/test_id_hash.rb +79 -0
- data/test/drafter/test_subdrafts.rb +178 -0
- data/test/helper.rb +13 -8
- data/test/support/models.rb +32 -6
- data/test/support/schema.rb +23 -13
- data/test/test_drafter.rb +1 -1
- metadata +40 -25
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -35,6 +35,7 @@ GEM
|
|
35
35
|
activemodel (>= 3.2.0)
|
36
36
|
activesupport (>= 3.2.0)
|
37
37
|
columnize (0.3.6)
|
38
|
+
database_cleaner (0.7.1)
|
38
39
|
debugger (1.1.1)
|
39
40
|
columnize (>= 0.3.1)
|
40
41
|
debugger-linecache (~> 1.1)
|
@@ -119,6 +120,7 @@ DEPENDENCIES
|
|
119
120
|
activerecord
|
120
121
|
bundler (~> 1.0.0)
|
121
122
|
carrierwave
|
123
|
+
database_cleaner
|
122
124
|
debugger
|
123
125
|
diffy
|
124
126
|
jeweler (~> 1.6.4)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/drafter.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "drafter"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["futurechimp"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-09-05"
|
13
13
|
s.description = "A"
|
14
14
|
s.email = "dave.hrycyszyn@headlondon.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -33,12 +33,16 @@ Gem::Specification.new do |s|
|
|
33
33
|
"lib/drafter/draft_upload.rb",
|
34
34
|
"lib/drafter/draft_uploader.rb",
|
35
35
|
"lib/drafter/draftable.rb",
|
36
|
+
"lib/drafter/id_hash.rb",
|
37
|
+
"lib/drafter/subdrafts.rb",
|
36
38
|
"test/drafter/test_apply.rb",
|
37
39
|
"test/drafter/test_creation.rb",
|
38
40
|
"test/drafter/test_diffing.rb",
|
39
41
|
"test/drafter/test_draft.rb",
|
40
42
|
"test/drafter/test_draft_upload.rb",
|
41
43
|
"test/drafter/test_draftable.rb",
|
44
|
+
"test/drafter/test_id_hash.rb",
|
45
|
+
"test/drafter/test_subdrafts.rb",
|
42
46
|
"test/fixtures/bar.txt",
|
43
47
|
"test/fixtures/foo.txt",
|
44
48
|
"test/helper.rb",
|
@@ -62,6 +66,7 @@ Gem::Specification.new do |s|
|
|
62
66
|
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
63
67
|
s.add_runtime_dependency(%q<diffy>, [">= 0"])
|
64
68
|
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
69
|
+
s.add_development_dependency(%q<database_cleaner>, [">= 0"])
|
65
70
|
s.add_development_dependency(%q<debugger>, [">= 0"])
|
66
71
|
s.add_development_dependency(%q<minitest>, [">= 0"])
|
67
72
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
@@ -74,6 +79,7 @@ Gem::Specification.new do |s|
|
|
74
79
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
75
80
|
s.add_dependency(%q<diffy>, [">= 0"])
|
76
81
|
s.add_dependency(%q<sqlite3>, [">= 0"])
|
82
|
+
s.add_dependency(%q<database_cleaner>, [">= 0"])
|
77
83
|
s.add_dependency(%q<debugger>, [">= 0"])
|
78
84
|
s.add_dependency(%q<minitest>, [">= 0"])
|
79
85
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
@@ -87,6 +93,7 @@ Gem::Specification.new do |s|
|
|
87
93
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
88
94
|
s.add_dependency(%q<diffy>, [">= 0"])
|
89
95
|
s.add_dependency(%q<sqlite3>, [">= 0"])
|
96
|
+
s.add_dependency(%q<database_cleaner>, [">= 0"])
|
90
97
|
s.add_dependency(%q<debugger>, [">= 0"])
|
91
98
|
s.add_dependency(%q<minitest>, [">= 0"])
|
92
99
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
data/lib/drafter/apply.rb
CHANGED
@@ -4,11 +4,12 @@ module Drafter
|
|
4
4
|
module Apply
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
|
-
# Apply the draft data to the draftable, without saving it
|
7
|
+
# Apply the draft data to the draftable, without saving it.
|
8
8
|
def apply_draft
|
9
9
|
if draft
|
10
10
|
restore_attrs
|
11
11
|
restore_files
|
12
|
+
restore_subdrafts
|
12
13
|
end
|
13
14
|
self
|
14
15
|
end
|
@@ -36,6 +37,60 @@ module Drafter
|
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
40
|
+
# It's possible to easily restore subdrafts except in one case we've
|
41
|
+
# run into so far: the case where you try to restore a subdraft which
|
42
|
+
# is defined using Single Table Inheritance (STI) and which also has a
|
43
|
+
# polymorphic belongs_to relationship with the draftable class.
|
44
|
+
#
|
45
|
+
# In those edge cases, we need to do a dirty little hack, using the
|
46
|
+
# :polymorphic_as option from the class's draftable method to manually
|
47
|
+
# set the association.
|
48
|
+
#
|
49
|
+
# This won't be clear enough to make sense 5 minutes from now, so here are
|
50
|
+
# the details spelled out more concretely. Let's say you've got these
|
51
|
+
# classes:
|
52
|
+
#
|
53
|
+
# class Article < ActiveRecord::Base
|
54
|
+
# draftable
|
55
|
+
# has_many :likes, :as => :likeable
|
56
|
+
# has_many :really_likes
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# class Like < ActiveRecord::Base
|
60
|
+
# draftable
|
61
|
+
# belongs_to :likeable, :polymorphic => true
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# class ReallyLike < Like
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# This setup will actually work fine for subdraft restoration, right up
|
68
|
+
# until you add "validates_presence_of :likeable" to Like. At that point,
|
69
|
+
# you'll be told that really_likes is invalid whenever you try to approve
|
70
|
+
# something, because the polymorphic STI "really_likable" won't be able
|
71
|
+
# to figure out what its likeable id is when it saves during the approval
|
72
|
+
# process.
|
73
|
+
#
|
74
|
+
# The hack basically involves explicitly telling draftable in the Like
|
75
|
+
# class what its polymorph relation is:
|
76
|
+
#
|
77
|
+
# class Like < ActiveRecord::Base
|
78
|
+
# draftable :polymorphic_as => :likeable
|
79
|
+
# ...
|
80
|
+
#
|
81
|
+
# See the models setup at tests/support/models.rb for the working setup.
|
82
|
+
#
|
83
|
+
def restore_subdrafts
|
84
|
+
draft.subdrafts.each_with_index do |subdraft, index|
|
85
|
+
inflated_object = subdraft.build_draftable
|
86
|
+
self.send(subdraft.parent_association_name.to_sym) << inflated_object
|
87
|
+
# THE HACK
|
88
|
+
if inflated_object.class.polymorphic_as
|
89
|
+
inflated_object.send("#{inflated_object.class.polymorphic_as}=", self)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
39
94
|
# We don't want to copy all the draft's columns into the draftable
|
40
95
|
# objects attributes.
|
41
96
|
#
|
data/lib/drafter/creation.rb
CHANGED
@@ -11,37 +11,54 @@ module Drafter
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# Build and save the draft when told to do so.
|
14
|
-
def save_draft
|
15
|
-
if
|
16
|
-
|
17
|
-
|
18
|
-
draft.data = attrs
|
19
|
-
else
|
20
|
-
self.build_draft(:data => attrs)
|
21
|
-
end
|
22
|
-
# https://github.com/rails/rails/issues/617
|
23
|
-
draft.draftable_type = self.class.to_s
|
24
|
-
self.draft.save!
|
25
|
-
uploads = build_draft_uploads(attrs)
|
26
|
-
self.draft
|
14
|
+
def save_draft(parent_draft=nil, parent_association_name=nil)
|
15
|
+
if valid?
|
16
|
+
do_create_draft(parent_draft, parent_association_name)
|
17
|
+
create_subdrafts
|
27
18
|
end
|
19
|
+
return self.draft.reload if self.draft
|
28
20
|
end
|
29
21
|
|
30
22
|
private
|
31
23
|
|
24
|
+
def do_create_draft(parent_draft=nil, parent_association_name=nil)
|
25
|
+
serialize_attributes_to_draft
|
26
|
+
attach_to_parent_draft(parent_draft, parent_association_name)
|
27
|
+
unfuck_sti
|
28
|
+
draft.save!
|
29
|
+
build_draft_uploads
|
30
|
+
draft
|
31
|
+
end
|
32
|
+
|
33
|
+
# https://github.com/rails/rails/issues/617
|
34
|
+
def unfuck_sti
|
35
|
+
draft.draftable_type = self.class.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
# Set up the draft object, setting its :data attribute to the serialized
|
39
|
+
# hash of this object's attributes.
|
40
|
+
#
|
41
|
+
def serialize_attributes_to_draft
|
42
|
+
if self.draft
|
43
|
+
draft.data = self.attributes
|
44
|
+
else
|
45
|
+
self.build_draft(:data => self.attributes)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
32
49
|
# Loop through and create DraftUpload objects for any Carrierwave
|
33
50
|
# uploaders mounted on this draftable object.
|
34
51
|
#
|
35
52
|
# @param [Hash] attrs the attributes to loop through
|
36
53
|
# @return [Array<DraftUpload>] an array of unsaved DraftUpload objects.
|
37
|
-
def build_draft_uploads
|
38
|
-
|
39
|
-
|
40
|
-
|
54
|
+
def build_draft_uploads
|
55
|
+
self.attributes.keys.each do |key|
|
56
|
+
if (self.respond_to?(key) &&
|
57
|
+
self.send(key).is_a?(CarrierWave::Uploader::Base) &&
|
58
|
+
self.send(key).file)
|
41
59
|
self.draft.draft_uploads << build_draft_upload(key)
|
42
60
|
end
|
43
61
|
end
|
44
|
-
draft_uploads
|
45
62
|
end
|
46
63
|
|
47
64
|
# Get a reference to the CarrierWave uploader mounted on the
|
@@ -61,5 +78,18 @@ module Drafter
|
|
61
78
|
draft_upload
|
62
79
|
end
|
63
80
|
|
81
|
+
# Attach the draft object to a parent draft object, if there is one.
|
82
|
+
# The parent_draft may be for an Article which has_many :comments,
|
83
|
+
# as an example.
|
84
|
+
#
|
85
|
+
# @param [Draft] parent_draft the draft that this draft is associated with.
|
86
|
+
# @param [Symbol] relation the name of the has_many (or has_one) association.
|
87
|
+
def attach_to_parent_draft(parent_draft, relation)
|
88
|
+
if parent_draft && relation
|
89
|
+
draft.parent = parent_draft
|
90
|
+
draft.parent_association_name = relation
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
64
94
|
end
|
65
95
|
end
|
data/lib/drafter/diffing.rb
CHANGED
@@ -9,7 +9,7 @@ module Diffing
|
|
9
9
|
# [Diffy::Diff].
|
10
10
|
def differences(attr, options={:format => :html})
|
11
11
|
if self.draft
|
12
|
-
Diffy::Diff.new(self.send(attr), self.draft(attr)).to_s(options[:format])
|
12
|
+
Diffy::Diff.new(self.send(attr), self.draft.send(attr)).to_s(options[:format])
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
data/lib/drafter/draft.rb
CHANGED
@@ -17,6 +17,15 @@ class Draft < ActiveRecord::Base
|
|
17
17
|
has_many :draft_uploads
|
18
18
|
belongs_to :draftable, :polymorphic => true
|
19
19
|
|
20
|
+
# Drafts are nestable, e.g. an Article's draft can have multiple
|
21
|
+
# Comment drafts attached, and the whole thing can be approved at once.
|
22
|
+
#
|
23
|
+
belongs_to :parent, :class_name => "Draft"
|
24
|
+
|
25
|
+
# Looked at from the other end, the parent draft should be able to address
|
26
|
+
# its subdrafts.
|
27
|
+
#
|
28
|
+
has_many :subdrafts, :class_name => "Draft", :foreign_key => "parent_id", :dependent => :destroy # << test that
|
20
29
|
|
21
30
|
# Store serialized data for the associated draftable as a Hash of
|
22
31
|
# attributes.
|
@@ -63,4 +72,10 @@ class Draft < ActiveRecord::Base
|
|
63
72
|
draftabl
|
64
73
|
end
|
65
74
|
|
75
|
+
def approve_subdrafts
|
76
|
+
subdrafts.each do |subdraft|
|
77
|
+
subdraft.approve!
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
66
81
|
end
|
data/lib/drafter/draftable.rb
CHANGED
@@ -6,6 +6,10 @@ module Drafter
|
|
6
6
|
# Overrides the +draftable+ method to define the +draftable?+ class method.
|
7
7
|
module ClassMethods
|
8
8
|
def draftable(options={})
|
9
|
+
super(options)
|
10
|
+
|
11
|
+
cattr_accessor :polymorphic_as
|
12
|
+
self.polymorphic_as = options[:polymorphic_as]
|
9
13
|
|
10
14
|
class << self
|
11
15
|
def draftable?
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module IdHash
|
2
|
+
|
3
|
+
|
4
|
+
# Checks the state of the object to see whether it's an unapproved draft
|
5
|
+
# (in which case it has no :id), or whether it's an approved object which
|
6
|
+
# is being edited or updated (in which case we can address it by :id).
|
7
|
+
#
|
8
|
+
# This is primarily useful in your controllers. Sometimes, you might want to
|
9
|
+
# identify the object by its :id; other times, you're dealing with an object
|
10
|
+
# that only has a Draft but no actual object identity, in which case you'll
|
11
|
+
# want to retrieve the Draft object by its :draft_id, and call
|
12
|
+
# @draft.build_draftable on that.
|
13
|
+
#
|
14
|
+
# @return [Hash] a hash with either :draft_id => this object's draft's id,
|
15
|
+
# or :id => this object's id.
|
16
|
+
def id_hash
|
17
|
+
if !new_record?
|
18
|
+
{ :id => self.to_param }
|
19
|
+
elsif new_record? && draft
|
20
|
+
{ :draft_id => draft.to_param }
|
21
|
+
else
|
22
|
+
raise "It's not clear what kind of id you're looking for."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# When you're attaching sub-objects to a parent object, you'll sometimes need
|
27
|
+
# to send the :id and :draft_id in another context, e.g. as :article_id and/or
|
28
|
+
# :draft_article_id.
|
29
|
+
#
|
30
|
+
#
|
31
|
+
# @param [Symbol] sym the symbol you want to inject into your id to provide
|
32
|
+
# context.
|
33
|
+
# @return [Hash] a hash with e.g. :article_id or :draft_article_id, with the
|
34
|
+
# appropriate values set (as per id_hash above).
|
35
|
+
def id_hash_as(sym)
|
36
|
+
if !new_record?
|
37
|
+
{ "#{sym}_id".to_sym => self.to_param }
|
38
|
+
elsif new_record? && draft
|
39
|
+
{ "draft_#{sym}_id".to_sym => draft.to_param }
|
40
|
+
else
|
41
|
+
raise "It's not clear what kind of id you're looking for."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Subdrafts
|
2
|
+
|
3
|
+
private
|
4
|
+
|
5
|
+
def create_subdrafts
|
6
|
+
relations = self.class.approves_drafts_for
|
7
|
+
unless relations.empty?
|
8
|
+
relations.each do |relation|
|
9
|
+
create_subdrafts_for(relation)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_subdrafts_for(relation)
|
15
|
+
objects = self.send(relation)
|
16
|
+
unless objects.empty?
|
17
|
+
objects.each do |object|
|
18
|
+
object.save_draft(self.draft, relation)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/lib/drafter.rb
CHANGED
@@ -16,6 +16,8 @@ module Drafter
|
|
16
16
|
autoload :Draft
|
17
17
|
autoload :Draftable
|
18
18
|
autoload :DraftUpload
|
19
|
+
autoload :IdHash
|
20
|
+
autoload :Subdrafts
|
19
21
|
|
20
22
|
class << self
|
21
23
|
delegate :config, :configure, :to => Draft
|
@@ -23,12 +25,26 @@ module Drafter
|
|
23
25
|
end
|
24
26
|
|
25
27
|
included do
|
26
|
-
include Apply
|
27
|
-
include Creation
|
28
|
-
include Diffing
|
29
28
|
include Draftable
|
30
29
|
end
|
31
30
|
|
31
|
+
module ClassMethods
|
32
|
+
|
33
|
+
def draftable(options={})
|
34
|
+
include Apply
|
35
|
+
include Creation
|
36
|
+
include Diffing
|
37
|
+
include Draftable
|
38
|
+
include IdHash
|
39
|
+
include Subdrafts
|
40
|
+
end
|
41
|
+
|
42
|
+
def approves_drafts_for(*associations)
|
43
|
+
cattr_accessor :approves_drafts_for
|
44
|
+
self.approves_drafts_for = associations
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
32
48
|
end
|
33
49
|
|
34
50
|
ActiveRecord::Base.class_eval{ include Drafter }
|
data/test/drafter/test_apply.rb
CHANGED
@@ -9,6 +9,42 @@ class TestCreation < Minitest::Unit::TestCase
|
|
9
9
|
:upload => file_upload)
|
10
10
|
end
|
11
11
|
|
12
|
+
describe "for an unsaved article" do
|
13
|
+
before do
|
14
|
+
@draft = @article.save_draft
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "with no comments" do
|
18
|
+
before do
|
19
|
+
@article = @draft.build_draftable
|
20
|
+
@article.apply_draft
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should restore the article, unsaved" do
|
24
|
+
assert @article.new_record?
|
25
|
+
assert_equal(Article, @article.class)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "with comments" do
|
30
|
+
before do
|
31
|
+
@article = @draft.build_draftable
|
32
|
+
@article.comments.build(:text => "I'm a comment on a draft article")
|
33
|
+
@draft = @article.save_draft
|
34
|
+
@article = @draft.build_draftable
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should restore the article, unsaved" do
|
38
|
+
assert @article.new_record?
|
39
|
+
assert_equal(Article, @article.class)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should restore the comments" do
|
43
|
+
assert_equal(1, @article.comments.length)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
12
48
|
describe "to an existing article" do
|
13
49
|
before do
|
14
50
|
@article.save!
|
@@ -38,11 +74,67 @@ class TestCreation < Minitest::Unit::TestCase
|
|
38
74
|
assert_equal("changed", @article.text)
|
39
75
|
end
|
40
76
|
|
41
|
-
|
77
|
+
it "should restore the draft upload" do
|
42
78
|
assert_equal("bar.txt", @article.upload.filename)
|
43
79
|
end
|
80
|
+
|
81
|
+
describe "which has a subdraft attached" do
|
82
|
+
before do
|
83
|
+
@article.comments.build(:text => "I'm a comment", :upload => file_upload)
|
84
|
+
@draft_count = Draft.count
|
85
|
+
@article.save_draft
|
86
|
+
@reloaded = Article.find(@article.to_param)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should not yet have any comments attached" do
|
90
|
+
assert_equal(0, @reloaded.comments.length)
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "applying the draft" do
|
94
|
+
before do
|
95
|
+
@reloaded.apply_draft
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should be able to restore the comment" do
|
99
|
+
assert_equal(1, @reloaded.comments.length)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "which has two subdrafts attached" do
|
105
|
+
before do
|
106
|
+
@article.comments.build(:text => "I'm a comment", :upload => file_upload)
|
107
|
+
@article.comments.build(:text => "I'm another comment", :upload => file_upload("bar.txt"))
|
108
|
+
@draft_count = Draft.count
|
109
|
+
@article.save_draft
|
110
|
+
@reloaded = Article.find(@article.to_param)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should not yet have any comments attached" do
|
114
|
+
assert_equal(0, @reloaded.comments.length)
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "applying the draft" do
|
118
|
+
before do
|
119
|
+
@reloaded.apply_draft
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should be able to restore the comment" do
|
123
|
+
assert_equal(2, @reloaded.comments.length)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should properly restore the first file, foo.txt" do
|
127
|
+
contents = File.new(@reloaded.comments.first.upload.path).read
|
128
|
+
assert_equal(file_upload.read, contents)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should properly restore the second file, bar.txt" do
|
132
|
+
contents = File.new(@reloaded.comments.last.upload.path).read
|
133
|
+
assert_equal(file_upload("bar.txt").read, contents)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
44
137
|
end
|
45
138
|
end
|
46
139
|
end
|
47
|
-
|
48
140
|
end
|
@@ -61,7 +61,6 @@ class TestCreation < Minitest::Unit::TestCase
|
|
61
61
|
it "should update the DraftUpload in place" do
|
62
62
|
assert_equal(@draft_upload_count, DraftUpload.count)
|
63
63
|
end
|
64
|
-
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
@@ -159,6 +158,47 @@ class TestCreation < Minitest::Unit::TestCase
|
|
159
158
|
assert_equal(1, @article.errors.count)
|
160
159
|
end
|
161
160
|
end
|
161
|
+
|
162
|
+
# We may need to save this for later.
|
163
|
+
#
|
164
|
+
# If we could get these tests working, we could call save_draft on any
|
165
|
+
# object in an association chain and have it save properly both up and
|
166
|
+
# down the chain.
|
167
|
+
#
|
168
|
+
# For the moment, it should work if you save from the top of the chain.
|
169
|
+
# Given the time constraints right now, let's use that for the moment.
|
170
|
+
#
|
171
|
+
# describe "a class which may belongs_to something else, e.g. a Comment" do
|
172
|
+
# describe "when no associated class is set, e.g. there's no Article" do
|
173
|
+
# before do
|
174
|
+
# @comment = Comment.new(:text => "foo")
|
175
|
+
# @draft_count = Draft.count
|
176
|
+
# @comment.save_draft
|
177
|
+
# end
|
178
|
+
|
179
|
+
# it "should save a draft" do
|
180
|
+
# assert_equal(@draft_count + 1, Draft.count)
|
181
|
+
# end
|
182
|
+
# end
|
183
|
+
|
184
|
+
# describe "when there's an article" do
|
185
|
+
# before do
|
186
|
+
# @article = Article.create(:text => "I'm an article")
|
187
|
+
# @comment = Comment.new(:text => "I belong to the article")
|
188
|
+
# @comment.article = @article
|
189
|
+
# @draft_count = Draft.count
|
190
|
+
# @comment.save_draft
|
191
|
+
# end
|
192
|
+
|
193
|
+
# it "should save a draft" do
|
194
|
+
# assert_equal(@draft_count + 1, Draft.count)
|
195
|
+
# end
|
196
|
+
|
197
|
+
# it "should add the @comment to the @article's subdrafts" do
|
198
|
+
# assert @article.draft.subdrafts.include? Draft.last
|
199
|
+
# end
|
200
|
+
# end
|
201
|
+
# end
|
162
202
|
end
|
163
203
|
|
164
204
|
end
|
@@ -26,9 +26,13 @@ class TestDrafter < MiniTest::Unit::TestCase
|
|
26
26
|
end
|
27
27
|
|
28
28
|
describe "for a string attribute" do
|
29
|
+
it "should not nullify the @article" do
|
30
|
+
assert @article
|
31
|
+
end
|
29
32
|
# return an html diff string for "foo" and "superfoo"
|
30
33
|
it "should return an HTML diff between the draft and live object" do
|
31
|
-
|
34
|
+
|
35
|
+
assert (@article.reload.differences(:text)).include?(%Q(<li class=\"ins\"><ins><strong>super</strong>foo</ins></li>))
|
32
36
|
end
|
33
37
|
end
|
34
38
|
end
|