Commit 2e7d2cf5eefd5635526050900ed9aa126457e70b
Exists in
master
and in
28 other branches
changing the position of the comment actions and adding hotspot for comment plugins
Showing
12 changed files
with
289 additions
and
52 deletions
Show diff stats
app/controllers/public/comment_controller.rb
... | ... | @@ -160,6 +160,15 @@ class CommentController < ApplicationController |
160 | 160 | end |
161 | 161 | end |
162 | 162 | end |
163 | + | |
164 | + #FIXME make this test | |
165 | + def check_actions | |
166 | + comment = profile.comments_received.find(params[:id]) | |
167 | + ids = @plugins.dispatch(:check_comment_actions, comment).collect do |action| | |
168 | + action.kind_of?(Proc) ? self.instance_eval(&action) : action | |
169 | + end.flatten.compact | |
170 | + render :json => {:ids => ids} | |
171 | + end | |
163 | 172 | |
164 | 173 | protected |
165 | 174 | ... | ... |
app/helpers/application_helper.rb
app/helpers/comment_helper.rb
... | ... | @@ -21,5 +21,48 @@ module CommentHelper |
21 | 21 | end |
22 | 22 | title |
23 | 23 | end |
24 | + | |
25 | + def comment_actions(comment) | |
26 | + url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id) | |
27 | + links = links_for_comment_actions(comment) | |
28 | + content_tag(:li, link_to(content_tag(:span, _('Contents menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger comment-trigger', :url => url), :class=> 'vcard') unless links.empty? | |
29 | + end | |
30 | + | |
31 | + private | |
32 | + | |
33 | + def links_for_comment_actions(comment) | |
34 | + actions = [link_for_report_abuse(comment), link_for_spam(comment), link_for_edit(comment), link_for_remove(comment)] | |
35 | + @plugins.dispatch(:comment_actions, comment).collect do |action| | |
36 | + actions << (action.kind_of?(Proc) ? self.instance_eval(&action) : action) | |
37 | + end | |
38 | + actions.flatten.compact | |
39 | + end | |
40 | + | |
41 | + def link_for_report_abuse(comment) | |
42 | + if comment.author | |
43 | + report_abuse_link = report_abuse(comment.author, :comment_link, comment) | |
44 | + {:link => report_abuse_link} if report_abuse_link | |
45 | + end | |
46 | + end | |
47 | + | |
48 | + def link_for_spam(comment) | |
49 | + if comment.spam? | |
50 | + {:link => link_to_function(_('Mark as NOT SPAM'), 'remove_comment(this, %s); return false;' % url_for(:profile => profile.identifier, :mark_comment_as_ham => comment.id).to_json, :class => 'comment-footer comment-footer-link comment-footer-hide')} | |
51 | + elsif (logged_in? && (user == profile || user.has_permission?(:moderate_comments, profile))) | |
52 | + {:link => link_to_function(_('Mark as SPAM'), 'remove_comment(this, %s, %s); return false;' % [url_for(:profile => profile.identifier, :controller => 'comment', :action => :mark_as_spam, :id => comment.id).to_json, _('Are you sure you want to mark this comment as SPAM?').to_json], :class => 'comment-footer comment-footer-link comment-footer-hide')} | |
53 | + end | |
54 | + end | |
55 | + | |
56 | + def link_for_edit(comment) | |
57 | + if comment.author && comment.author == user | |
58 | + {:link => expirable_comment_link(comment, :edit, _('Edit'), url_for(:profile => profile.identifier, :controller => :comment, :action => :edit, :id => comment.id),:class => 'colorbox')} | |
59 | + end | |
60 | + end | |
61 | + | |
62 | + def link_for_remove(comment) | |
63 | + if logged_in? && (user == profile || user == comment.author || user.has_permission?(:moderate_comments, profile)) | |
64 | + {:link => link_to_function(_('Remove'), 'remove_comment(this, %s, %s); return false ;' % [url_for(:profile => profile.identifier, :controller => 'comment', :action => :destroy, :id => comment.id).to_json, _('Are you sure you want to remove this comment and all its replies?').to_json], :class => 'comment-footer comment-footer-link comment-footer-hide remove-children')} | |
65 | + end | |
66 | + end | |
24 | 67 | |
25 | 68 | end | ... | ... |
app/views/comment/_comment.rhtml
... | ... | @@ -31,6 +31,21 @@ |
31 | 31 | <% comment_balloon do %> |
32 | 32 | |
33 | 33 | <div class="comment-details"> |
34 | + <div class="comment-header"> | |
35 | + <ul> | |
36 | + <div class="comment-actions"> | |
37 | + <%= comment_actions(comment) %> | |
38 | + </div> | |
39 | + </ul> | |
40 | + <% unless comment.spam? %> | |
41 | + <%= link_to_function '', | |
42 | + "var f = add_comment_reply_form(this, %s); f.find('comment_title, textarea').val(''); return false" % comment.id, | |
43 | + :class => 'comment-footer comment-footer-link comment-footer-hide comment-actions-reply button', | |
44 | + :id => 'comment-reply-to-' + comment.id.to_s | |
45 | + %> | |
46 | + <% end %> | |
47 | + </div> | |
48 | + | |
34 | 49 | <div class="comment-created-at"> |
35 | 50 | <%= show_time(comment.created_at) %> |
36 | 51 | </div> |
... | ... | @@ -41,7 +56,7 @@ |
41 | 56 | </div> |
42 | 57 | </div> |
43 | 58 | |
44 | - <div class="comment_reply post_comment_box closed"> | |
59 | + <div class="comment_reply post_comment_box closed" id="comment_reply_to_<%= comment.id %>"> | |
45 | 60 | <% if @comment && @comment.errors.any? && @comment.reply_of_id.to_i == comment.id %> |
46 | 61 | <%= error_messages_for :comment %> |
47 | 62 | <script type="text/javascript"> |
... | ... | @@ -51,36 +66,6 @@ |
51 | 66 | }); |
52 | 67 | </script> |
53 | 68 | <% end %> |
54 | - <%= report_abuse(comment.author, :comment_link, comment) if comment.author %> | |
55 | - | |
56 | - <% if comment.spam? %> | |
57 | - | |
58 | - <%= link_to_function(_('Mark as NOT SPAM'), 'remove_comment(this, %s); return false;' % url_for(:profile => profile.identifier, :mark_comment_as_ham => comment.id).to_json, :class => 'comment-footer comment-footer-link comment-footer-hide') %> | |
59 | - <% else %> | |
60 | - <% if (logged_in? && (user == profile || user.has_permission?(:moderate_comments, profile))) %> | |
61 | - | |
62 | - <%= link_to_function(_('Mark as SPAM'), 'remove_comment(this, %s, %s); return false;' % [url_for(:profile => profile.identifier, :controller => 'comment', :action => :mark_as_spam, :id => comment.id).to_json, _('Are you sure you want to mark this comment as SPAM?').to_json], :class => 'comment-footer comment-footer-link comment-footer-hide') %> | |
63 | - <% end %> | |
64 | - <% end %> | |
65 | - | |
66 | - <% if comment.author && comment.author == user %> | |
67 | - | |
68 | - <%= expirable_comment_link comment, :edit, _('Edit'), url_for(:profile => profile.identifier, :controller => :comment, :action => :edit, :id => comment.id),:class => 'colorbox' %> | |
69 | - <% end %> | |
70 | - | |
71 | - <% if logged_in? && (user == profile || user == comment.author || user.has_permission?(:moderate_comments, profile)) %> | |
72 | - | |
73 | - <%= link_to_function(_('Remove'), 'remove_comment(this, %s, %s); return false ;' % [url_for(:profile => profile.identifier, :controller => 'comment', :action => :destroy, :id => comment.id).to_json, _('Are you sure you want to remove this comment and all its replies?').to_json], :class => 'comment-footer comment-footer-link comment-footer-hide remove-children') %> | |
74 | - <% end %> | |
75 | - | |
76 | - <% unless comment.spam? %> | |
77 | - | |
78 | - <%= link_to_function _('Reply'), | |
79 | - "var f = add_comment_reply_form(this, %s); f.find('comment_title, textarea').val(''); return false" % comment.id, | |
80 | - :class => 'comment-footer comment-footer-link comment-footer-hide', | |
81 | - :id => 'comment-reply-to-' + comment.id.to_s | |
82 | - %> | |
83 | - <% end %> | |
84 | 69 | </div> |
85 | 70 | |
86 | 71 | <% end %> | ... | ... |
lib/noosfero/plugin.rb
... | ... | @@ -320,6 +320,30 @@ class Noosfero::Plugin |
320 | 320 | def comment_marked_as_ham(comment) |
321 | 321 | end |
322 | 322 | |
323 | + # Adds extra actions for comments | |
324 | + # returns = list of hashes or lambda block that creates a list of hashes | |
325 | + # example: | |
326 | + # | |
327 | + # def comment_actions(comment) | |
328 | + # [{:link => link_to_function(...)}] | |
329 | + # end | |
330 | + # | |
331 | + def comment_actions(comment) | |
332 | + nil | |
333 | + end | |
334 | + | |
335 | + # This method is called when the user click on comment actions menu. | |
336 | + # returns = list or lambda block that return ids of enabled menu items for comments | |
337 | + # example: | |
338 | + # | |
339 | + # def check_comment_actions(comment) | |
340 | + # ['#action1', '#action2'] | |
341 | + # end | |
342 | + # | |
343 | + def check_comment_actions(comment) | |
344 | + [] | |
345 | + end | |
346 | + | |
323 | 347 | # -> Adds fields to the signup form |
324 | 348 | # returns = lambda block that creates html code |
325 | 349 | def signup_extra_contents | ... | ... |
public/javascripts/add-and-join.js
... | ... | @@ -100,4 +100,24 @@ jQuery(function($) { |
100 | 100 | clicked.parent().find(".send-an-email").fadeOut(); |
101 | 101 | }) |
102 | 102 | }) |
103 | + | |
104 | + $(".comment-trigger").live('click', function(){ | |
105 | + clicked = $(this); | |
106 | + url = clicked.attr("url"); | |
107 | + $.get(url, function(data){ | |
108 | + ids = []; | |
109 | + if(data && data.ids) { | |
110 | + for(var i=0; i<data.ids.length; i++) { | |
111 | + clicked.parent().find(data.ids[i]).fadeIn(); | |
112 | + ids.push(data.ids[i]); | |
113 | + } | |
114 | + } | |
115 | + clicked.parent().find('.comment-action-extra').each(function() { | |
116 | + if($.inArray('#'+$(this).attr('id'), ids)) | |
117 | + $(this).fadeOut(); | |
118 | + }); | |
119 | + }) | |
120 | + return false; | |
121 | + }) | |
122 | + | |
103 | 123 | }); | ... | ... |
public/javascripts/application.js
... | ... | @@ -314,11 +314,17 @@ function toggleSubmenu(trigger, title, link_list) { |
314 | 314 | content.append('<h4>' + title + '</h4>'); |
315 | 315 | jQuery.each(link_list, function(index, link_hash) { |
316 | 316 | for (label in link_hash) { |
317 | - options = ""; | |
318 | - jQuery.each(link_hash[label], function(option, value){ | |
319 | - options += option +'="'+ value + '" '; | |
320 | - }) | |
321 | - list.append('<li><a '+ options +'>' + label + '</a></li>'); | |
317 | + if(link_hash[label]!=null) { | |
318 | + if(label=='link' && jQuery.type(link_hash[label])=="string") { | |
319 | + list.append('<li>' + link_hash[label] + '</li>'); | |
320 | + } else { | |
321 | + options = ""; | |
322 | + jQuery.each(link_hash[label], function(option, value){ | |
323 | + options += option +'="'+ value + '" '; | |
324 | + }) | |
325 | + list.append('<li><a '+ options +'>' + label + '</a></li>'); | |
326 | + } | |
327 | + } | |
322 | 328 | } |
323 | 329 | }); |
324 | 330 | content.append(list); |
... | ... | @@ -342,9 +348,9 @@ function hideAllSubmenus() { |
342 | 348 | // Hide visible ballons when clicked outside them |
343 | 349 | jQuery(document).ready(function() { |
344 | 350 | jQuery('body').live('click', function() { hideAllSubmenus(); }); |
345 | - jQuery('.menu-submenu-trigger').click(function(e) { e.stopPropagation(); }); | |
346 | - jQuery('.simplemenu-trigger').click(function(e) { e.stopPropagation(); }); | |
347 | - jQuery('#chat-online-users').click(function(e) { e.stopPropagation(); }); | |
351 | + jQuery('.menu-submenu-trigger').live('click', function(e) { e.stopPropagation(); }); | |
352 | + jQuery('.simplemenu-trigger').live('click', function(e) { e.stopPropagation(); }); | |
353 | + jQuery('#chat-online-users').live('click', function(e) { e.stopPropagation(); }); | |
348 | 354 | }); |
349 | 355 | |
350 | 356 | function input_javascript_ordering_stuff() { |
... | ... | @@ -710,8 +716,8 @@ jQuery(function($) { |
710 | 716 | }); |
711 | 717 | |
712 | 718 | function add_comment_reply_form(button, comment_id) { |
713 | - var container = jQuery(button).parents('.comment_reply'); | |
714 | - | |
719 | + //var container = jQuery(button).parents('.comment_reply'); | |
720 | + var container = jQuery('#comment_reply_to_'+comment_id); | |
715 | 721 | var f = container.find('.comment_form'); |
716 | 722 | if (f.length == 0) { |
717 | 723 | comments_div = jQuery(button).parents('.comments'); | ... | ... |
public/stylesheets/application.css
... | ... | @@ -1802,13 +1802,32 @@ a.button.disabled, input.disabled { |
1802 | 1802 | #content .profile-list-block ul { |
1803 | 1803 | width: 200px; |
1804 | 1804 | } |
1805 | -#content .common-profile-list-block li { | |
1806 | - margin: 0px; | |
1805 | +#content .comment-header .comment-actions-reply { | |
1806 | + float: right; | |
1807 | + background-image: url(/designs/icons/tango/Tango/16x16/actions/go-jump.png); | |
1808 | + height: 12px; | |
1809 | +} | |
1810 | +#content .comment-header ul { | |
1811 | + float: right; | |
1812 | + margin: 1px 0px 14px 0px; | |
1813 | +} | |
1814 | +#content .comment-actions .menu-submenu-header, #content .comment-actions .menu-submenu-footer, #content .comment-actions .menu-submenu h4 { | |
1815 | + display: none; | |
1816 | +} | |
1817 | +#content .comment-actions .menu-submenu ul { | |
1818 | + border: 1px solid #888a85; | |
1819 | + background-color: #efefef; | |
1820 | + padding-right: 2px; | |
1821 | + height: auto; | |
1822 | + display: block; | |
1823 | +} | |
1824 | +#content .common-profile-list-block li, #content .comment-actions li { | |
1825 | + margin: 0px !important; | |
1807 | 1826 | padding: 0px; |
1808 | 1827 | list-style: none; |
1809 | 1828 | position: relative; |
1810 | 1829 | } |
1811 | -.common-profile-list-block .vcard a { | |
1830 | +.common-profile-list-block .vcard a, .comment-actions .vcard a { | |
1812 | 1831 | display: block; |
1813 | 1832 | height: 112px; |
1814 | 1833 | max-height: 112px; |
... | ... | @@ -1819,7 +1838,7 @@ a.button.disabled, input.disabled { |
1819 | 1838 | text-align: center; |
1820 | 1839 | overflow: hidden; |
1821 | 1840 | font-size: 11px; |
1822 | - text-decoration: none; | |
1841 | + text-decoration: none !important; | |
1823 | 1842 | color: #000; |
1824 | 1843 | position: relative; |
1825 | 1844 | cursor: pointer; /* work arround bug for MSIE */ |
... | ... | @@ -4575,11 +4594,17 @@ h1#agenda-title { |
4575 | 4594 | } |
4576 | 4595 | /* Profile balloon */ |
4577 | 4596 | |
4578 | -.common-profile-list-block .vcard { | |
4597 | +.common-profile-list-block .vcard, .comment-actions .vcard { | |
4579 | 4598 | position: relative !important; |
4580 | 4599 | float: left; |
4581 | 4600 | } |
4582 | -.common-profile-list-block .vcard .menu-submenu-trigger, .menu-submenu-trigger { | |
4601 | +#content .comment-actions .vcard { | |
4602 | + padding-right: 20px; | |
4603 | +} | |
4604 | +#content .comment-actions .vcard .menu-submenu-trigger { | |
4605 | + display: block; | |
4606 | +} | |
4607 | +.common-profile-list-block .vcard .menu-submenu-trigger, .menu-submenu-trigger, .comment-actions .vcard .menu-submenu-trigger { | |
4583 | 4608 | display: none; |
4584 | 4609 | width: 16px; |
4585 | 4610 | height: 16px; |
... | ... | @@ -4593,7 +4618,7 @@ h1#agenda-title { |
4593 | 4618 | -moz-border-radius: 5px; |
4594 | 4619 | -webkit-border-radius: 5px; |
4595 | 4620 | } |
4596 | -.common-profile-list-block .vcard .menu-submenu-trigger:hover, .menu-submenu-trigger:hover { | |
4621 | +.common-profile-list-block .vcard .menu-submenu-trigger:hover, .menu-submenu-trigger:hover, .comment-actions .vcard .menu-submenu-trigger:hover { | |
4597 | 4622 | background: #fff url(/images/top-arrow.png) center center no-repeat; |
4598 | 4623 | border: 1px solid #ccc; |
4599 | 4624 | } |
... | ... | @@ -4612,6 +4637,10 @@ h1#agenda-title { |
4612 | 4637 | padding: 0; |
4613 | 4638 | text-align: left; |
4614 | 4639 | } |
4640 | +.comment-details .menu-submenu { | |
4641 | + bottom: 0px; | |
4642 | + right: -134px; | |
4643 | +} | |
4615 | 4644 | .box-2 .menu-submenu, .box-3 .menu-submenu { |
4616 | 4645 | bottom: 78px; |
4617 | 4646 | right: -44px; |
... | ... | @@ -4646,7 +4675,7 @@ h1#agenda-title { |
4646 | 4675 | .msie7 #search-results .menu-submenu-trigger { |
4647 | 4676 | width: 20px !important; |
4648 | 4677 | } |
4649 | -.common-profile-list-block .vcard .menu-submenu a { | |
4678 | +.common-profile-list-block .vcard .menu-submenu a, .comment-actions .vcard .menu-submenu a { | |
4650 | 4679 | float: none; |
4651 | 4680 | display: block; |
4652 | 4681 | height: auto; | ... | ... |
test/functional/comment_controller_test.rb
... | ... | @@ -501,7 +501,7 @@ class CommentControllerTest < ActionController::TestCase |
501 | 501 | assert_equal 'Comment edited', Comment.find(comment.id).body |
502 | 502 | end |
503 | 503 | |
504 | - should 'not crash on update comment if comment does not exist' do | |
504 | + should 'not crash on update comment if comment does not exist' do | |
505 | 505 | login_as profile.identifier |
506 | 506 | page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text') |
507 | 507 | |
... | ... | @@ -509,4 +509,18 @@ class CommentControllerTest < ActionController::TestCase |
509 | 509 | assert_response 404 |
510 | 510 | end |
511 | 511 | |
512 | + should 'returns ids of menu items that has to be displayed' do | |
513 | + class TestActionPlugin < Noosfero::Plugin | |
514 | + def check_comment_actions(c) | |
515 | + ['action1', 'action2'] | |
516 | + end | |
517 | + end | |
518 | + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestActionPlugin.new]) | |
519 | + login_as profile.identifier | |
520 | + page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text') | |
521 | + comment = fast_create(Comment, :body => 'Original comment', :source_id => page.id, :source_type => 'Article') | |
522 | + xhr :post, :check_actions, :profile => profile.identifier, :id => comment.id | |
523 | + assert_match /\{\"ids\":\[\"action1\",\"action2\"\]\}/, @response.body | |
524 | + end | |
525 | + | |
512 | 526 | end | ... | ... |
test/functional/content_viewer_controller_test.rb
... | ... | @@ -1047,7 +1047,7 @@ class ContentViewerControllerTest < ActionController::TestCase |
1047 | 1047 | comment.save! |
1048 | 1048 | login_as 'testuser' |
1049 | 1049 | get :view_page, :profile => 'testuser', :page => [ 'test' ] |
1050 | - assert_tag :tag => 'a', :attributes => { :class => /comment-footer-link/ }, :content => 'Reply' | |
1050 | + assert_tag :tag => 'a', :attributes => { :class => /comment-actions-reply/ } | |
1051 | 1051 | end |
1052 | 1052 | |
1053 | 1053 | should 'display reply to comment button if not authenticated' do |
... | ... | @@ -1057,7 +1057,7 @@ class ContentViewerControllerTest < ActionController::TestCase |
1057 | 1057 | comment = article.comments.build(:author => profile, :title => 'a comment', :body => 'lalala') |
1058 | 1058 | comment.save! |
1059 | 1059 | get :view_page, :profile => 'testuser', :page => [ 'test' ] |
1060 | - assert_tag :tag => 'a', :attributes => { :class => /comment-footer-link/ }, :content => 'Reply' | |
1060 | + assert_tag :tag => 'a', :attributes => { :class => /comment-actions-reply/ } | |
1061 | 1061 | end |
1062 | 1062 | |
1063 | 1063 | should 'display replies if comment has replies' do | ... | ... |
... | ... | @@ -0,0 +1,104 @@ |
1 | +require File.dirname(__FILE__) + '/../test_helper' | |
2 | + | |
3 | +class CommentHelperTest < ActiveSupport::TestCase | |
4 | + | |
5 | + include CommentHelper | |
6 | + include ActionView::Helpers::TagHelper | |
7 | + include NoosferoTestHelper | |
8 | + | |
9 | + def setup | |
10 | + @user = create_user('usertest').person | |
11 | + @profile = @user | |
12 | + self.stubs(:logged_in?).returns(true) | |
13 | + self.stubs(:report_abuse).returns('<a href="#">link</a>') | |
14 | + self.stubs(:expirable_comment_link).returns('<a href="#">link</a>') | |
15 | + @plugins.stubs(:dispatch).returns([]) | |
16 | + end | |
17 | + | |
18 | + attr_reader :user, :profile | |
19 | + | |
20 | + should 'show menu if it has links for actions' do | |
21 | + comment = Comment.new | |
22 | + menu = comment_actions(comment) | |
23 | + assert menu | |
24 | + end | |
25 | + | |
26 | + should 'do not show menu if it has no actions' do | |
27 | + comment = Comment.new | |
28 | + self.stubs(:links_for_comment_actions).returns([]) | |
29 | + menu = comment_actions(comment) | |
30 | + assert !menu | |
31 | + end | |
32 | + | |
33 | + should 'do not show menu if it has nil actions only' do | |
34 | + comment = Comment.new | |
35 | + self.stubs(:link_for_report_abuse).returns(nil) | |
36 | + self.stubs(:link_for_spam).returns(nil) | |
37 | + self.stubs(:link_for_edit).returns(nil) | |
38 | + self.stubs(:link_for_remove).returns(nil) | |
39 | + menu = comment_actions(comment) | |
40 | + assert !menu | |
41 | + end | |
42 | + | |
43 | + should 'include actions of plugins in menu' do | |
44 | + comment = Comment.new | |
45 | + plugin_action = {:link => 'plugin_action'} | |
46 | + @plugins.stubs(:dispatch).returns([plugin_action]) | |
47 | + links = links_for_comment_actions(comment) | |
48 | + assert_includes links, plugin_action | |
49 | + end | |
50 | + | |
51 | + should 'include lambda actions of plugins in menu' do | |
52 | + comment = Comment.new | |
53 | + plugin_action = lambda{[{:link => 'plugin_action'}, {:link => 'plugin_action2'}]} | |
54 | + @plugins.stubs(:dispatch).returns([plugin_action]) | |
55 | + links = links_for_comment_actions(comment) | |
56 | + assert_includes links, {:link => 'plugin_action'} | |
57 | + assert_includes links, {:link => 'plugin_action2'} | |
58 | + end | |
59 | + | |
60 | + should 'return link for report abuse action when comment has a author' do | |
61 | + comment = Comment.new | |
62 | + comment.author = user | |
63 | + link = link_for_report_abuse(comment) | |
64 | + assert link | |
65 | + end | |
66 | + | |
67 | + should 'do not return link for report abuse action when comment has no author' do | |
68 | + comment = Comment.new | |
69 | + link = link_for_report_abuse(comment) | |
70 | + assert !link | |
71 | + end | |
72 | + | |
73 | + should 'return link for mark comment as spam' do | |
74 | + comment = Comment.new | |
75 | + link = link_for_spam(comment) | |
76 | + assert_match /Mark as SPAM/, link[:link] | |
77 | + end | |
78 | + | |
79 | + should 'return link for mark comment as not spam' do | |
80 | + comment = Comment.new | |
81 | + comment.spam = true | |
82 | + link = link_for_spam(comment) | |
83 | + assert_match /Mark as NOT SPAM/, link[:link] | |
84 | + end | |
85 | + | |
86 | + should 'do not return link for edit comment' do | |
87 | + comment = Comment.new | |
88 | + link = link_for_edit(comment) | |
89 | + assert !link | |
90 | + end | |
91 | + | |
92 | + should 'return link for edit comment' do | |
93 | + comment = Comment.new | |
94 | + comment.author = user | |
95 | + link = link_for_edit(comment) | |
96 | + assert link | |
97 | + end | |
98 | + | |
99 | + def link_to_function(content, url, options = {}) | |
100 | + link_to(content, url, options) | |
101 | + end | |
102 | + | |
103 | +end | |
104 | + | ... | ... |