adva_comments 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|