drafter 0.2.8 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|