Commit c916579e2ebfddba26d985c3dff642dac103561b
Exists in
master
and in
29 other branches
Merge branch 'ActionItem2562' into ActionItem2520
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
| ... | ... | @@ -339,6 +339,30 @@ class Noosfero::Plugin |
| 339 | 339 | def comment_marked_as_ham(comment) |
| 340 | 340 | end |
| 341 | 341 | |
| 342 | + # Adds extra actions for comments | |
| 343 | + # returns = list of hashes or lambda block that creates a list of hashes | |
| 344 | + # example: | |
| 345 | + # | |
| 346 | + # def comment_actions(comment) | |
| 347 | + # [{:link => link_to_function(...)}] | |
| 348 | + # end | |
| 349 | + # | |
| 350 | + def comment_actions(comment) | |
| 351 | + nil | |
| 352 | + end | |
| 353 | + | |
| 354 | + # This method is called when the user click on comment actions menu. | |
| 355 | + # returns = list or lambda block that return ids of enabled menu items for comments | |
| 356 | + # example: | |
| 357 | + # | |
| 358 | + # def check_comment_actions(comment) | |
| 359 | + # ['#action1', '#action2'] | |
| 360 | + # end | |
| 361 | + # | |
| 362 | + def check_comment_actions(comment) | |
| 363 | + [] | |
| 364 | + end | |
| 365 | + | |
| 342 | 366 | # -> Adds fields to the signup form |
| 343 | 367 | # returns = lambda block that creates html code |
| 344 | 368 | 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
| ... | ... | @@ -493,7 +493,7 @@ class CommentControllerTest < ActionController::TestCase |
| 493 | 493 | assert_equal 'Comment edited', Comment.find(comment.id).body |
| 494 | 494 | end |
| 495 | 495 | |
| 496 | - should 'not crash on update comment if comment does not exist' do | |
| 496 | + should 'not crash on update comment if comment does not exist' do | |
| 497 | 497 | login_as profile.identifier |
| 498 | 498 | page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text') |
| 499 | 499 | |
| ... | ... | @@ -501,4 +501,18 @@ class CommentControllerTest < ActionController::TestCase |
| 501 | 501 | assert_response 404 |
| 502 | 502 | end |
| 503 | 503 | |
| 504 | + should 'returns ids of menu items that has to be displayed' do | |
| 505 | + class TestActionPlugin < Noosfero::Plugin | |
| 506 | + def check_comment_actions(c) | |
| 507 | + ['action1', 'action2'] | |
| 508 | + end | |
| 509 | + end | |
| 510 | + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([TestActionPlugin.new]) | |
| 511 | + login_as profile.identifier | |
| 512 | + page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text') | |
| 513 | + comment = fast_create(Comment, :body => 'Original comment', :source_id => page.id, :source_type => 'Article') | |
| 514 | + xhr :post, :check_actions, :profile => profile.identifier, :id => comment.id | |
| 515 | + assert_match /\{\"ids\":\[\"action1\",\"action2\"\]\}/, @response.body | |
| 516 | + end | |
| 517 | + | |
| 504 | 518 | 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 | + | ... | ... |