adva_comments 0.1.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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/adva_comments.gemspec +20 -0
- data/app/assets/javascripts/adva_comments/jquery.comments.js +41 -0
- data/app/assets/stylesheets/adva_comments/admin/comments.scss +34 -0
- data/app/assets/stylesheets/adva_comments/comments.scss +50 -0
- data/app/controllers/admin/comments_controller.rb +86 -0
- data/app/controllers/comments_controller.rb +109 -0
- data/app/helpers/admin/comments_helper.rb +32 -0
- data/app/helpers/comments_helper.rb +71 -0
- data/app/mailers/comment_mailer.rb +8 -0
- data/app/models/comment.rb +94 -0
- data/app/views/admin/articles/_comments_settings.html.erb +1 -0
- data/app/views/admin/comments/_form.html.erb +12 -0
- data/app/views/admin/comments/edit.html.erb +9 -0
- data/app/views/admin/comments/index.html.erb +43 -0
- data/app/views/admin/sections/_comments_settings.html.erb +7 -0
- data/app/views/admin/sites/_comments_settings.html.erb +7 -0
- data/app/views/comment_mailer/comment_notification.html.erb +12 -0
- data/app/views/comments/_comment.html.erb +13 -0
- data/app/views/comments/_form.html.erb +44 -0
- data/app/views/comments/_list.html.erb +8 -0
- data/app/views/comments/comments.atom.builder +16 -0
- data/app/views/comments/preview.html.erb +3 -0
- data/app/views/comments/show.html.erb +12 -0
- data/config/initializers/article.rb +13 -0
- data/config/initializers/content.rb +17 -0
- data/config/initializers/controllers.rb +25 -0
- data/config/initializers/menus.rb +24 -0
- data/config/initializers/section.rb +15 -0
- data/config/initializers/site.rb +11 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20080401000007_create_comments_table.rb +22 -0
- data/db/migrate/20080721141112_add_comment_board_id.rb +9 -0
- data/lib/action_controller/acts_as_commentable.rb +43 -0
- data/lib/active_record/has_many_comments.rb +49 -0
- data/lib/adva_comments/version.rb +3 -0
- data/lib/adva_comments.rb +19 -0
- data/lib/format.rb +3 -0
- data/test/contexts.rb +29 -0
- data/test/functional/admin/comments_controller_test.rb +200 -0
- data/test/functional/comments_controller_test.rb +133 -0
- data/test/functional/comments_routes_test.rb +17 -0
- data/test/test_helper.rb +4 -0
- data/test/unit/helpers/admin/comments_helper_test.rb +23 -0
- data/test/unit/helpers/comments_helper_test.rb +147 -0
- data/test/unit/models/comment_test.rb +150 -0
- data/test/unit/models/commentable_test.rb +30 -0
- data/test/unit/observers/activities_comment_observer_test.rb +45 -0
- metadata +132 -0
@@ -0,0 +1,200 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../test_helper")
|
2
|
+
|
3
|
+
class AdminCommentsControllerTest < ActionController::TestCase
|
4
|
+
include ContentHelper, ResourceHelper, BlogHelper
|
5
|
+
tests Admin::CommentsController
|
6
|
+
attr_reader :controller
|
7
|
+
|
8
|
+
with_common [:a_page, :a_blog], :a_published_article, [:an_approved_comment, :an_unapproved_comment], :is_superuser
|
9
|
+
|
10
|
+
def default_params
|
11
|
+
{ :site_id => @site.id, :return_to => 'return/to/here' }
|
12
|
+
end
|
13
|
+
|
14
|
+
view :comment do
|
15
|
+
has_text @comment.body
|
16
|
+
|
17
|
+
comment_path = show_path(@article, :anchor => "comment_#{@comment.id}", :namespace => nil)
|
18
|
+
has_tag 'a[href=?]', comment_path, 'View' # displays a link to the comment on the frontend view
|
19
|
+
has_tag 'a', 'Edit' # displays a link to edit the comment
|
20
|
+
has_tag 'a', 'Delete' # displays a link to delete the comment
|
21
|
+
has_tag 'a', 'Approve' if within :unapproved_comment # displays a link to approve comment
|
22
|
+
has_tag 'a', 'Unapprove' if within :approved_comment # displays a link to unapprove comment
|
23
|
+
# has_tag 'a', 'Reply' if with? :approved_comment # displays a link to reply to the comment
|
24
|
+
end
|
25
|
+
|
26
|
+
test "is an Admin::BaseController" do
|
27
|
+
@controller.should be_kind_of(Admin::BaseController)
|
28
|
+
end
|
29
|
+
|
30
|
+
# FIXME in theory the admin comments controller should also work with scoping
|
31
|
+
# to a content or a section (currently only tested scoping to a site)
|
32
|
+
|
33
|
+
describe "routing" do
|
34
|
+
with_options :path_prefix => '/admin/sites/1/', :site_id => '1' do |r|
|
35
|
+
r.it_maps :get, 'comments', :action => 'index'
|
36
|
+
# r.it_maps :get, 'comments/new', :action => 'new'
|
37
|
+
# r.it_maps :post, 'comments', :action => 'create'
|
38
|
+
r.it_maps :get, 'comments/1', :action => 'show', :id => '1'
|
39
|
+
r.it_maps :get, 'comments/1/edit', :action => 'edit', :id => '1'
|
40
|
+
r.it_maps :put, 'comments/1', :action => 'update', :id => '1'
|
41
|
+
r.it_maps :delete, 'comments/1', :action => 'destroy', :id => '1'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "GET to :index" do
|
46
|
+
action { get :index, default_params }
|
47
|
+
it_guards_permissions :show, :comment
|
48
|
+
|
49
|
+
with :access_granted do
|
50
|
+
it_assigns :comments
|
51
|
+
it_renders :template, :index do
|
52
|
+
# has_tag 'select[id=filter_list]' # displays a filter for filtering the comments list
|
53
|
+
has_tag 'ul[id=comments_list]' # displays a list of comments
|
54
|
+
shows :comment
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# describe "GET to :show" do
|
60
|
+
# action { get :show, default_params.merge(:id => @comment.id) }
|
61
|
+
# it_guards_permissions :show, :comment
|
62
|
+
#
|
63
|
+
# with :access_granted do
|
64
|
+
# it_assigns :comment
|
65
|
+
# it_renders :template, :show do
|
66
|
+
# has_tag 'h3', 'Comment'
|
67
|
+
# has_text @comment.body
|
68
|
+
# shows :comment
|
69
|
+
# # FIXME shows a reply form
|
70
|
+
# end
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
|
74
|
+
# FIXME ... implement these
|
75
|
+
#
|
76
|
+
# describe "GET to :new" do
|
77
|
+
# action { get :new, default_params }
|
78
|
+
# it_guards_permissions :create, :comment
|
79
|
+
# with :access_granted do
|
80
|
+
# it_assigns :comment
|
81
|
+
# it_renders :template, :new
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# describe "POST to :create" do
|
86
|
+
# action { post :create, @params }
|
87
|
+
# it_guards_permissions :create, :comment
|
88
|
+
#
|
89
|
+
# with :valid_comment_params do
|
90
|
+
# it_changes '@site.reload.comments.count' => 1
|
91
|
+
# it_redirects_to admin_comment_url(@site, assigns(:comment))
|
92
|
+
# it_assigns_flash_cookie :notice => :not_nil
|
93
|
+
# end
|
94
|
+
#
|
95
|
+
# with :invalid_comment_params do
|
96
|
+
# it_does_not_change '@site.reload.comments.count'
|
97
|
+
# it_renders :template, :new
|
98
|
+
# it_assigns_flash_cookie :error => :not_nil
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
|
102
|
+
describe "GET to :edit" do
|
103
|
+
action { get :edit, default_params.merge(:id => @comment.id) }
|
104
|
+
it_guards_permissions :update, :comment
|
105
|
+
|
106
|
+
with :access_granted do
|
107
|
+
it_assigns :comment
|
108
|
+
it_renders :template, :edit do
|
109
|
+
# FIXME assert form rendered
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "PUT to :update" do
|
115
|
+
action { put :update, default_params.merge(:id => @comment.id).merge(@params || {}) }
|
116
|
+
it_guards_permissions :update, :comment
|
117
|
+
|
118
|
+
with :access_granted do
|
119
|
+
it_assigns :comment
|
120
|
+
|
121
|
+
with "valid comment params" do
|
122
|
+
before { @params = { :comment => { :body => 'updated comment body' } } }
|
123
|
+
it_updates :comment
|
124
|
+
it_redirects_to 'return/to/here'
|
125
|
+
it_assigns_flash_cookie :notice => :not_nil
|
126
|
+
it_triggers_event :comment_updated
|
127
|
+
end
|
128
|
+
|
129
|
+
with "invalid comment params" do
|
130
|
+
before { @params = { :comment => { :body => '' } } }
|
131
|
+
it_does_not_update :comment
|
132
|
+
it_assigns_flash_cookie :error => :not_nil
|
133
|
+
it_does_not_trigger_any_event
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "DELETE to :destroy" do
|
139
|
+
action { delete :destroy, default_params.merge(:id => @comment.id) }
|
140
|
+
it_guards_permissions :destroy, :comment
|
141
|
+
|
142
|
+
with :access_granted do
|
143
|
+
it_assigns :comment
|
144
|
+
it_destroys :comment
|
145
|
+
it_redirects_to 'return/to/here'
|
146
|
+
it_assigns_flash_cookie :notice => :not_nil
|
147
|
+
it_triggers_event :comment_deleted
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# def filter_conditions
|
152
|
+
# @controller.send(:filter_options)[:conditions]
|
153
|
+
# end
|
154
|
+
#
|
155
|
+
# describe "filter_options" do
|
156
|
+
# before { @controller.instance_variable_set :@section, @section }
|
157
|
+
#
|
158
|
+
# it "sets :order, :per_page and :page parameters defaults" do
|
159
|
+
# @controller.params = { :filter => 'all' }
|
160
|
+
# @controller.send(:filter_options).should == { :per_page => nil, :page => 1, :order => 'created_at DESC' }
|
161
|
+
# assert_nothing_raised { @controller.send :set_comments }
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
# it "fetches approved comments when :filter == state and :state == approved" do
|
165
|
+
# @controller.params = { :filter => 'state', :state => 'approved' }
|
166
|
+
# filter_conditions.should == "approved = '1'"
|
167
|
+
# assert_nothing_raised { @controller.send :set_comments }
|
168
|
+
# end
|
169
|
+
#
|
170
|
+
# it "fetches unapproved comments when :filter == state and :state == unapproved" do
|
171
|
+
# @controller.params = { :filter => 'state', :state => 'unapproved' }
|
172
|
+
# filter_conditions.should == "approved = '0'"
|
173
|
+
# assert_nothing_raised { @controller.send :set_comments }
|
174
|
+
# end
|
175
|
+
#
|
176
|
+
# it "fetches comments by matching the body when :filter == body" do
|
177
|
+
# @controller.params = { :filter => 'body', :query => 'foo' }
|
178
|
+
# filter_conditions.should == "LOWER(body) LIKE '%foo%'"
|
179
|
+
# assert_nothing_raised { @controller.send :set_comments }
|
180
|
+
# end
|
181
|
+
#
|
182
|
+
# it "fetches comments by matching the author name when :filter == author_name" do
|
183
|
+
# @controller.params = { :filter => 'author_name', :query => 'foo' }
|
184
|
+
# filter_conditions.should == "LOWER(author_name) LIKE '%foo%'"
|
185
|
+
# assert_nothing_raised { @controller.send :set_comments }
|
186
|
+
# end
|
187
|
+
#
|
188
|
+
# it "fetches comments by matching the author email when :filter == author_email" do
|
189
|
+
# @controller.params = { :filter => 'author_email', :query => 'foo@bar.baz' }
|
190
|
+
# filter_conditions.should == "LOWER(author_email) LIKE '%foo@bar.baz%'"
|
191
|
+
# assert_nothing_raised { @controller.send :set_comments }
|
192
|
+
# end
|
193
|
+
#
|
194
|
+
# it "fetches comments by matching the author homepage when :filter == author_homepage" do
|
195
|
+
# @controller.params = { :filter => 'author_homepage', :query => 'homepage.com' }
|
196
|
+
# filter_conditions.should == "LOWER(author_homepage) LIKE '%homepage.com%'"
|
197
|
+
# assert_nothing_raised { @controller.send :set_comments }
|
198
|
+
# end
|
199
|
+
# end
|
200
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
|
2
|
+
|
3
|
+
# FIXME should also test comments on section articles and wikipages
|
4
|
+
|
5
|
+
class CommentsControllerTest < ActionController::TestCase
|
6
|
+
with_common :a_blog, :a_published_article, :an_approved_comment, :is_superuser
|
7
|
+
|
8
|
+
def default_params
|
9
|
+
{ :comment => { :commentable_type => 'Article', :commentable_id => @article.id } }
|
10
|
+
end
|
11
|
+
|
12
|
+
test "is a BaseController" do
|
13
|
+
@controller.should be_kind_of(BaseController)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "routing" do
|
17
|
+
it_maps :get, 'comments', :action => 'index'
|
18
|
+
it_maps :get, 'comments/new', :action => 'new'
|
19
|
+
it_maps :post, 'comments/preview', :action => 'preview'
|
20
|
+
it_maps :post, 'comments', :action => 'create'
|
21
|
+
it_maps :get, 'comments/1', :action => 'show', :id => '1'
|
22
|
+
it_maps :get, 'comments/1/edit', :action => 'edit', :id => '1'
|
23
|
+
it_maps :put, 'comments/1', :action => 'update', :id => '1'
|
24
|
+
it_maps :delete, 'comments/1', :action => 'destroy', :id => '1'
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "GET to :show" do
|
28
|
+
action { get :show, :id => @comment.id }
|
29
|
+
# it_guards_permissions :show, :comment do # FIXME
|
30
|
+
it_assigns :section, :comment, :commentable
|
31
|
+
it_renders :template, :show do
|
32
|
+
has_text @comment.body
|
33
|
+
end
|
34
|
+
|
35
|
+
# FIXME displays a message when the comment is not approved yet: /under review/
|
36
|
+
# end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "POST to preview" do
|
40
|
+
action { post :preview, default_params.merge(@params || {}) }
|
41
|
+
it_guards_permissions :create, :comment do
|
42
|
+
with :valid_comment_params do
|
43
|
+
it_assigns :comment => :not_nil
|
44
|
+
it_renders :template, :preview do
|
45
|
+
has_text 'the comment body'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# FIXME
|
50
|
+
# with "invalid comment params" do
|
51
|
+
# end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "POST to :create" do
|
56
|
+
action do
|
57
|
+
Comment.with_observers :comment_sweeper do
|
58
|
+
post :create, default_params.merge(@params || {})
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it_guards_permissions :create, :comment do
|
63
|
+
with :valid_comment_params do
|
64
|
+
it_assigns :commentable => :article, :comment => :not_nil
|
65
|
+
it_saves :comment
|
66
|
+
it_assigns_flash_cookie :notice => :not_nil
|
67
|
+
it_triggers_event :comment_created
|
68
|
+
it_sweeps_page_cache :by_reference => :article
|
69
|
+
it_redirects_to { comment_url(assigns(:comment)) }
|
70
|
+
|
71
|
+
# FIXME
|
72
|
+
# it "checks the comment's spaminess" do
|
73
|
+
# expect do
|
74
|
+
# url = "http://test.host/sections/1/articles/an-article"
|
75
|
+
# mock(@comment).check_approval(:permalink => url, :authenticated => false)
|
76
|
+
# mock(Article).find { @article }
|
77
|
+
# mock(@article).comments.build { @comment }
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
end
|
81
|
+
|
82
|
+
with :invalid_comment_params do
|
83
|
+
it_renders :template, :show
|
84
|
+
it_assigns_flash_cookie :error => :not_nil
|
85
|
+
it_does_not_trigger_any_event
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "PUT to :update" do
|
91
|
+
action do
|
92
|
+
Comment.with_observers :comment_sweeper do
|
93
|
+
post :update, (@params || {}).merge(:id => @comment.id)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it_guards_permissions :update, :comment do
|
98
|
+
with "valid comment params" do
|
99
|
+
before { @params = { :comment => { :body => 'the updated comment body' } } }
|
100
|
+
|
101
|
+
it_updates :comment
|
102
|
+
it_redirects_to { comment_url(assigns(:comment)) }
|
103
|
+
it_assigns_flash_cookie :notice => :not_nil
|
104
|
+
it_triggers_event :comment_updated
|
105
|
+
it_sweeps_page_cache :by_reference => :article
|
106
|
+
end
|
107
|
+
|
108
|
+
with :invalid_comment_params do
|
109
|
+
it_does_not_update :comment
|
110
|
+
it_renders_template :show
|
111
|
+
it_assigns_flash_cookie :error => :not_nil
|
112
|
+
it_does_not_trigger_any_event
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "DELETE to :destroy" do
|
118
|
+
action do
|
119
|
+
Comment.with_observers :comment_sweeper do
|
120
|
+
delete :destroy,:id => @comment.id
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
it_guards_permissions :destroy, :comment do
|
125
|
+
it_assigns :comment
|
126
|
+
it_destroys :comment
|
127
|
+
it_triggers_event :comment_deleted
|
128
|
+
it_redirects_to { '/' }
|
129
|
+
it_assigns_flash_cookie :notice => :not_nil
|
130
|
+
it_sweeps_page_cache :by_reference => :article
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
|
2
|
+
|
3
|
+
class CommentsRoutesTest < ActionController::TestCase
|
4
|
+
tests CommentsController
|
5
|
+
|
6
|
+
paths = %W( /comments
|
7
|
+
/comments/1 )
|
8
|
+
|
9
|
+
paths.each do |path|
|
10
|
+
test "regenerates the original path from the recognized params for #{path}" do
|
11
|
+
without_routing_filters do
|
12
|
+
params = ActionController::Routing::Routes.recognize_path(path, :method => :get)
|
13
|
+
assert_equal path, @controller.url_for(params.merge(:only_path => true))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
+
|
3
|
+
class AdminCommentsHelperTest < ActionView::TestCase
|
4
|
+
include Admin::CommentsHelper
|
5
|
+
|
6
|
+
test "translates comment_expiration_options" do
|
7
|
+
expected = [ ['Are not allowed', -1],
|
8
|
+
['Never expire', 0],
|
9
|
+
['Expire 24 hours after publishing', 1],
|
10
|
+
['Expire 1 week after publishing', 7],
|
11
|
+
['Expire 1 month after publishing', 30],
|
12
|
+
['Expire 3 months after publishing', 90] ]
|
13
|
+
comment_expiration_options.should == expected
|
14
|
+
end
|
15
|
+
|
16
|
+
test "translates comments_filter_options" do
|
17
|
+
lambda { comments_filter_options }.should_not raise_error
|
18
|
+
end
|
19
|
+
|
20
|
+
test "translates comments_state_options" do
|
21
|
+
lambda { comments_state_options }.should_not raise_error
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
class CommentsHelperTest < ActionView::TestCase
|
4
|
+
include CommentsHelper
|
5
|
+
|
6
|
+
attr_accessor :request
|
7
|
+
|
8
|
+
def setup
|
9
|
+
super
|
10
|
+
@section = Section.first
|
11
|
+
@article = @section.articles.first
|
12
|
+
@site = @section.site
|
13
|
+
|
14
|
+
stub(self).protect_against_forgery?.returns false
|
15
|
+
|
16
|
+
TestController.send :include, CommentsHelper
|
17
|
+
@controller = TestController.new
|
18
|
+
@request = ActionController::TestRequest.new
|
19
|
+
end
|
20
|
+
|
21
|
+
test '#comments_feed_title joins the titles of site, section and commentable' do
|
22
|
+
comments_feed_title(@site, @section, @article).should ==
|
23
|
+
"Comments: #{@site.title} » #{@section.title} » #{@article.title}"
|
24
|
+
end
|
25
|
+
|
26
|
+
# test '#link_to_remote_comment_preview returns a rote link to preview_comments_path' do
|
27
|
+
# mock(self).preview_comments_path.returns '/path/to/comments/preview'
|
28
|
+
# link_to_remote_comment_preview.should =~ /Ajax.Updater/
|
29
|
+
# end
|
30
|
+
|
31
|
+
# comment_form_hidden_fields
|
32
|
+
|
33
|
+
test '#comment_form_hidden_fields includes a hidden return_to field' do
|
34
|
+
result = comment_form_hidden_fields(@article)
|
35
|
+
result.should have_tag('input[type=?][name=?]', 'hidden', 'return_to')
|
36
|
+
end
|
37
|
+
|
38
|
+
test 'including comment[commentable_type]' do
|
39
|
+
result = comment_form_hidden_fields(@article)
|
40
|
+
result.should have_tag('input[type=?][name=?]', 'hidden', 'comment[commentable_type]')
|
41
|
+
end
|
42
|
+
|
43
|
+
test 'including comment[commentable_id]' do
|
44
|
+
result = comment_form_hidden_fields(@article)
|
45
|
+
result.should have_tag('input[type=?][name=?]', 'hidden', 'comment[commentable_id]')
|
46
|
+
end
|
47
|
+
|
48
|
+
test "#admin_comment_path with no :section_id param given and with no :content_id param given
|
49
|
+
it returns the admin_site_comment_path with no further params" do
|
50
|
+
@controller.params = { :site_id => 1 }
|
51
|
+
@controller.admin_comments_path(@site).should_not have_url_params
|
52
|
+
end
|
53
|
+
|
54
|
+
test "#admin_comment_path with no :section_id param given and with a :content_id param given
|
55
|
+
it returns the admin_site_comment_path with the :content_id param" do
|
56
|
+
@controller.params = { :site_id => 1, :content_id => 1 }
|
57
|
+
@controller.admin_comments_path(@site).should have_url_params(:content_id)
|
58
|
+
end
|
59
|
+
|
60
|
+
test "#admin_comment_path with a :section_id param given and with no :content_id param given
|
61
|
+
it returns the admin_site_comment_path with the :section_id param" do
|
62
|
+
@controller.params = { :site_id => 1, :section_id => 1 }
|
63
|
+
@controller.admin_comments_path(@site).should have_url_params(:section_id)
|
64
|
+
end
|
65
|
+
|
66
|
+
test "#admin_comment_path with a :section_id param given and with a :content_id param given
|
67
|
+
it returns the admin_site_comment_path with the :content_id param" do
|
68
|
+
@controller.params = { :site_id => 1, :section_id => 1, :content_id => 1 }
|
69
|
+
@controller.admin_comments_path(@site).should have_url_params(:content_id)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class LinkToCommentsHelperTest < ActionView::TestCase
|
74
|
+
include ContentHelper, ResourceHelper
|
75
|
+
tests CommentsHelper
|
76
|
+
|
77
|
+
def setup
|
78
|
+
super
|
79
|
+
@section = Section.first
|
80
|
+
@article = @section.articles.find_by_title 'a page article'
|
81
|
+
@category = @section.categories.first
|
82
|
+
@tag = Tag.new :name => 'foo'
|
83
|
+
|
84
|
+
stub(self).current_controller_namespace.returns(nil) # yuck
|
85
|
+
@article_path = show_path(@article)
|
86
|
+
end
|
87
|
+
|
88
|
+
# link_to_content_comments_count
|
89
|
+
|
90
|
+
test "#link_to_content_comments_count returns a link_to_content_comments" do
|
91
|
+
link_to_content_comments_count(@article).should have_tag('a[href=?]', "#{@article_path}#comments")
|
92
|
+
end
|
93
|
+
|
94
|
+
test "#link_to_content_comments_count given the option :total is set
|
95
|
+
it returns a link_to_content_comments with the approved and total comments counts as a link text" do
|
96
|
+
link_to_content_comments_count(@article, :total => true).should =~ /\d{2} \(\d{2}\)/
|
97
|
+
end
|
98
|
+
|
99
|
+
test "#link_to_content_comments_count given the option :total is not set
|
100
|
+
it returns a link_to_content_comments with the total comments count as a link text" do
|
101
|
+
link_to_content_comments_count(@article).should =~ /\d{2}/
|
102
|
+
end
|
103
|
+
|
104
|
+
test "#link_to_content_comments_count given the content has no comments
|
105
|
+
it returns the option :alt as plain text" do
|
106
|
+
stub(@article).approved_comments_count.returns 0
|
107
|
+
link_to_content_comments_count(@article, :alt => 'no comments').should == 'no comments'
|
108
|
+
end
|
109
|
+
|
110
|
+
test "#link_to_content_comments_count given the content has no comments and no option :alt was passed
|
111
|
+
it returns 'none' as plain text" do
|
112
|
+
stub(@article).approved_comments_count.returns 0
|
113
|
+
link_to_content_comments_count(@article).should == 'none'
|
114
|
+
end
|
115
|
+
|
116
|
+
# link_to_content_comments
|
117
|
+
|
118
|
+
test "#link_to_content_comments given a content it returns a link to show_path" do
|
119
|
+
link_to_content_comments(@article).should have_tag('a[href=?]', "#{@article_path}#comments", '1 Comment')
|
120
|
+
end
|
121
|
+
|
122
|
+
test "#link_to_content_comments given a content and a comment it returns a link to show_path + comment anchor" do
|
123
|
+
comment = @article.comments.first
|
124
|
+
anchor = dom_id(comment)
|
125
|
+
link_to_content_comments(@article, comment).should == %(<a href="#{@article_path}##{anchor}">1 Comment</a>)
|
126
|
+
end
|
127
|
+
|
128
|
+
test "#link_to_content_comments given the first arg is a String it uses the String as link text" do
|
129
|
+
path = show_path(@article)
|
130
|
+
link_to_content_comments('link text', @article).should == %(<a href="#{path}#comments">link text</a>)
|
131
|
+
end
|
132
|
+
|
133
|
+
test "#link_to_content_comments given the content has no approved comments and the content does not accept comments
|
134
|
+
it returns nil" do
|
135
|
+
mock(@article).approved_comments_count.returns 0
|
136
|
+
mock(@article).accept_comments?.returns false
|
137
|
+
link_to_content_comments(@article).should be_nil
|
138
|
+
end
|
139
|
+
|
140
|
+
# link_to_content_comment
|
141
|
+
|
142
|
+
test "#link_to_content_comment inserts the comment's commentable to the args and calls link_to_content_comments" do
|
143
|
+
comment = @article.comments.first
|
144
|
+
anchor = dom_id(comment)
|
145
|
+
link_to_content_comment(comment).should == %(<a href="#{@article_path}##{anchor}">1 Comment</a>)
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
class CommentTest < ActiveSupport::TestCase
|
4
|
+
def setup
|
5
|
+
super
|
6
|
+
@section = Section.first
|
7
|
+
@article = @section.articles.first
|
8
|
+
@comment = @article.comments.first
|
9
|
+
end
|
10
|
+
|
11
|
+
test 'acts as a role context for the author role' do
|
12
|
+
Comment.should act_as_role_context(:roles => :author)
|
13
|
+
end
|
14
|
+
|
15
|
+
test 'sanitizes the body_html attribute' do
|
16
|
+
Comment.should filter_attributes(:sanitize => :body_html)
|
17
|
+
end
|
18
|
+
|
19
|
+
test "filters the body column" do
|
20
|
+
@comment.should filter_column(:body)
|
21
|
+
end
|
22
|
+
|
23
|
+
# ASSOCIATIONS
|
24
|
+
|
25
|
+
test "belongs to a site" do
|
26
|
+
@comment.should belong_to(:site)
|
27
|
+
end
|
28
|
+
|
29
|
+
test "belongs to a section" do
|
30
|
+
@comment.should belong_to(:section)
|
31
|
+
end
|
32
|
+
|
33
|
+
test "belongs to a commentable" do
|
34
|
+
@comment.should belong_to(:commentable)
|
35
|
+
end
|
36
|
+
|
37
|
+
# VALIDATIONS
|
38
|
+
|
39
|
+
test "validates presence of author (through belongs_to_author)" do
|
40
|
+
@comment.should validate_presence_of(:author)
|
41
|
+
end
|
42
|
+
|
43
|
+
test "validates presence of body" do
|
44
|
+
@comment.should validate_presence_of(:body)
|
45
|
+
end
|
46
|
+
|
47
|
+
test "validates presence of commentable" do
|
48
|
+
@comment.should validate_presence_of(:commentable)
|
49
|
+
end
|
50
|
+
|
51
|
+
# CALLBACKS
|
52
|
+
|
53
|
+
test 'sets owners (site + section) before validation' do
|
54
|
+
Comment.before_validation.should include(:set_owners)
|
55
|
+
end
|
56
|
+
|
57
|
+
test 'authorizes commenting before create' do
|
58
|
+
Comment.before_create.should include(:authorize_commenting)
|
59
|
+
end
|
60
|
+
|
61
|
+
# INSTANCE METHODS
|
62
|
+
|
63
|
+
test '#owner returns the commentable' do
|
64
|
+
@comment.owner.should == @article
|
65
|
+
end
|
66
|
+
|
67
|
+
test '#filter returns the comment_filter attribute of the commentable' do
|
68
|
+
mock(@comment.commentable.target).comment_filter.returns :filter
|
69
|
+
@comment.filter.should == :filter
|
70
|
+
end
|
71
|
+
|
72
|
+
# approved?
|
73
|
+
|
74
|
+
test '#approved? returns true if the approved attribute is not 0' do
|
75
|
+
@comment.approved = 1
|
76
|
+
@comment.should be_approved
|
77
|
+
end
|
78
|
+
|
79
|
+
test '#approved? returns true if the approved attribute is 0' do
|
80
|
+
@comment.approved = 0
|
81
|
+
@comment.should_not be_approved
|
82
|
+
end
|
83
|
+
|
84
|
+
# state_changes
|
85
|
+
|
86
|
+
test "#state_changes returns :updated, :approved when the comment was just approved" do
|
87
|
+
@comment.approved = 0
|
88
|
+
@comment.clear_changes!
|
89
|
+
@comment.approved = 1
|
90
|
+
@comment.state_changes.should == [:updated, :approved]
|
91
|
+
end
|
92
|
+
|
93
|
+
test "#state_changes returns :updated, :unapproved when the comment was just unapproved" do
|
94
|
+
@comment.approved = 1
|
95
|
+
@comment.clear_changes!
|
96
|
+
@comment.approved = 0
|
97
|
+
@comment.state_changes.should == [:updated, :unapproved]
|
98
|
+
end
|
99
|
+
|
100
|
+
# authorize_commenting
|
101
|
+
|
102
|
+
test '#authorize_commenting checks if the commentable accepts comments' do
|
103
|
+
mock(@comment.commentable.target).accept_comments?.returns(true)
|
104
|
+
@comment.send(:authorize_commenting)
|
105
|
+
end
|
106
|
+
|
107
|
+
test '#authorize_commenting raises CommentNotAllowed if the commentable does not accept comments' do
|
108
|
+
mock(@comment.commentable.target).accept_comments?.returns(false)
|
109
|
+
lambda { @comment.send(:authorize_commenting) }.should raise_error
|
110
|
+
end
|
111
|
+
|
112
|
+
# set_owners
|
113
|
+
|
114
|
+
test '#set_owners sets site and section from the commentable' do
|
115
|
+
@comment.site, @comment.section = nil, nil
|
116
|
+
@comment.send(:set_owners)
|
117
|
+
@comment.site.should == @comment.commentable.site
|
118
|
+
@comment.section.should == @comment.commentable.section
|
119
|
+
end
|
120
|
+
|
121
|
+
# author_link
|
122
|
+
|
123
|
+
test "#author_link returns a link when author_url is present" do
|
124
|
+
stub(@comment).author_homepage.returns 'http://somewhere.com'
|
125
|
+
@comment.author_link.should == %(<a href="http://somewhere.com">#{@comment.author.name}</a>)
|
126
|
+
end
|
127
|
+
|
128
|
+
test "#author_link returns author_name when author_url is not present" do
|
129
|
+
stub(@comment).author_homepage.returns nil
|
130
|
+
@comment.author_link.should == @comment.author.name
|
131
|
+
end
|
132
|
+
|
133
|
+
# comment creation
|
134
|
+
|
135
|
+
test "raises Comment::CommentNotAllowed when commentable.accept_comments? returns false" do
|
136
|
+
mock(@article).accept_comments?.returns(false)
|
137
|
+
comment = Comment.new(:body => 'body', :author => User.first, :commentable => @article)
|
138
|
+
lambda { comment.save! }.should raise_error(Comment::CommentNotAllowed)
|
139
|
+
end
|
140
|
+
|
141
|
+
# filtering
|
142
|
+
|
143
|
+
test "it does not allow html in the comment body" do
|
144
|
+
@article.site.comment_filter = 'textile_filter'
|
145
|
+
html = 'p{position:absolute; top:50px; left:10px; width:150px; height:150px}. secure html'
|
146
|
+
@comment = Comment.new(:body => html, :commentable => @article)
|
147
|
+
@comment.save(false)
|
148
|
+
@comment.body_html.should == %(<p>secure html</p>)
|
149
|
+
end
|
150
|
+
end
|