Commit 3900d7ac8e0f66e4b45a389b6740bf154c09989f
1 parent
31323dca
Exists in
theme-brasil-digital-from-staging
and in
9 other branches
Needs adaptation to detect paragraphs
Showing
22 changed files
with
573 additions
and
0 deletions
Show diff stats
plugins/comment_paragraph/controllers/profile/comment_paragraph_plugin_profile_controller.rb
0 → 100644
@@ -0,0 +1,22 @@ | @@ -0,0 +1,22 @@ | ||
1 | +class CommentParagraphPluginProfileController < ProfileController | ||
2 | + append_view_path File.join(File.dirname(__FILE__) + '/../../views') | ||
3 | + | ||
4 | + def view_comments | ||
5 | + @article_id = params[:article_id] | ||
6 | + @paragraph_id = params[:paragraph_id] | ||
7 | + | ||
8 | + article = profile.articles.find(@article_id) | ||
9 | + @paragraph_comment_page = (params[:paragraph_comment_page] || 1).to_i | ||
10 | + | ||
11 | + @comments = article.comments.without_spam.in_paragraph(@paragraph_id) | ||
12 | + @comments_count = @comments.count | ||
13 | + @comments = @comments.without_reply.paginate(:per_page => per_page, :page => @paragraph_comment_page ) | ||
14 | + | ||
15 | + @no_more_pages = @comments_count <= @paragraph_comment_page * per_page | ||
16 | + end | ||
17 | + | ||
18 | + def per_page | ||
19 | + 3 | ||
20 | + end | ||
21 | + | ||
22 | +end |
plugins/comment_paragraph/controllers/public/comment_paragraph_plugin_public_controller.rb
0 → 100644
plugins/comment_paragraph/db/migrate/20140715201629_add_paragraph_id_to_comment.rb
0 → 100644
plugins/comment_paragraph/lib/comment_paragraph_plugin.rb
0 → 100644
@@ -0,0 +1,34 @@ | @@ -0,0 +1,34 @@ | ||
1 | +class CommentParagraphPlugin < Noosfero::Plugin | ||
2 | + | ||
3 | + def self.plugin_name | ||
4 | + "Comment Paragraph" | ||
5 | + end | ||
6 | + | ||
7 | + def self.plugin_description | ||
8 | + _("A plugin that display comments divided by paragraphs.") | ||
9 | + end | ||
10 | + | ||
11 | + def unavailable_comments(scope) | ||
12 | + scope.without_paragraph | ||
13 | + end | ||
14 | + | ||
15 | + def comment_form_extra_contents(args) | ||
16 | + comment = args[:comment] | ||
17 | + paragraph_id = comment.paragraph_id || args[:paragraph_id] | ||
18 | + proc { | ||
19 | + hidden_field_tag('comment[paragraph_id]', paragraph_id) if paragraph_id | ||
20 | + } | ||
21 | + end | ||
22 | + | ||
23 | + def js_files | ||
24 | + 'comment_paragraph_macro.js' | ||
25 | + end | ||
26 | + | ||
27 | + def stylesheet? | ||
28 | + true | ||
29 | + end | ||
30 | + | ||
31 | + | ||
32 | +end | ||
33 | + | ||
34 | +require_dependency 'comment_paragraph_plugin/macros/allow_comment' |
plugins/comment_paragraph/lib/comment_paragraph_plugin/macros/allow_comment.rb
0 → 100644
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +#FIXME See a better way to generalize this parameter. | ||
2 | +ActionView::Base.sanitized_allowed_attributes += ['data-macro', 'data-macro-paragraph_id'] | ||
3 | + | ||
4 | +class CommentParagraphPlugin::AllowComment < Noosfero::Plugin::Macro | ||
5 | + def self.configuration | ||
6 | + { :params => [], | ||
7 | + :skip_dialog => true, | ||
8 | + :generator => 'makeCommentable();', | ||
9 | + :js_files => 'comment_paragraph.js', | ||
10 | + :icon_path => '/designs/icons/tango/Tango/16x16/emblems/emblem-system.png', | ||
11 | + :css_files => 'comment_paragraph.css' } | ||
12 | + end | ||
13 | + | ||
14 | + def parse(params, inner_html, source) | ||
15 | + paragraph_id = params[:paragraph_id].to_i | ||
16 | + article = source | ||
17 | + count = article.paragraph_comments.without_spam.in_paragraph(paragraph_id).count | ||
18 | + | ||
19 | + proc { | ||
20 | + render :partial => 'comment_paragraph_plugin_profile/comment_paragraph', | ||
21 | + :locals => {:paragraph_id => paragraph_id, :article_id => article.id, :inner_html => inner_html, :count => count, :profile_identifier => article.profile.identifier } | ||
22 | + } | ||
23 | + end | ||
24 | +end |
@@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
1 | +require_dependency 'article' | ||
2 | + | ||
3 | +class Article | ||
4 | + | ||
5 | + has_many :paragraph_comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc', :conditions => [ 'paragraph_id IS NOT NULL'] | ||
6 | + | ||
7 | + validate :not_empty_paragraph_comments_removed | ||
8 | + | ||
9 | + def not_empty_paragraph_comments_removed | ||
10 | + if body && body_changed? | ||
11 | + paragraphs_with_comments = Comment.find(:all, :select => 'distinct paragraph_id', :conditions => {:source_id => self.id}).map(&:paragraph_id).compact | ||
12 | + paragraphs = Hpricot(body.to_s).search('.macro').collect{|element| element['data-macro-paragraph_id'].to_i} | ||
13 | + errors[:base] << (N_('Not empty paragraph comment cannot be removed')) unless (paragraphs_with_comments-paragraphs).empty? | ||
14 | + end | ||
15 | + end | ||
16 | + | ||
17 | +end | ||
18 | + |
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +require_dependency 'comment' | ||
2 | + | ||
3 | +class Comment | ||
4 | + | ||
5 | + scope :without_paragraph, :conditions => {:paragraph_id => nil } | ||
6 | + | ||
7 | + scope :in_paragraph, proc { |paragraph_id| { | ||
8 | + :conditions => ['paragraph_id = ?', paragraph_id] | ||
9 | + } | ||
10 | + } | ||
11 | + | ||
12 | + attr_accessible :paragraph_id | ||
13 | + | ||
14 | +end |
@@ -0,0 +1,47 @@ | @@ -0,0 +1,47 @@ | ||
1 | +function getNextParagraphId() { | ||
2 | + max = -1; | ||
3 | + paragraphs = jQuery('#article_body_ifr').contents().find('.article_comments'); | ||
4 | + paragraphs.each(function(key, value) { | ||
5 | + value = jQuery(value).attr('data-macro-paragraph_id'); | ||
6 | + if(value>max) max = parseInt(value); | ||
7 | + }); | ||
8 | + return max+1; | ||
9 | +} | ||
10 | + | ||
11 | +function makeCommentable() { | ||
12 | + tinyMCE.activeEditor.focus(); | ||
13 | + start = jQuery(tinyMCE.activeEditor.selection.getStart()).closest('p'); | ||
14 | + end = jQuery(tinyMCE.activeEditor.selection.getEnd()).closest('p'); | ||
15 | + | ||
16 | + //text = start.parent().children(); | ||
17 | + text = jQuery('#article_body_ifr').contents().find('*'); | ||
18 | + selection = text.slice(text.index(start), text.index(end)+1); | ||
19 | + | ||
20 | + hasTag = false; | ||
21 | + selection.each(function(key, value) { | ||
22 | + commentTag = jQuery(value).closest('.article_comments'); | ||
23 | + if(commentTag.length) { | ||
24 | + commentTag.children().unwrap('<div class=\"article_comments\"/>'); | ||
25 | + hasTag = true; | ||
26 | + } | ||
27 | + }); | ||
28 | + | ||
29 | + if(!hasTag) { | ||
30 | + tags = start.siblings().add(start); | ||
31 | + tags = tags.slice(tags.index(start), tags.index(end)>=0?tags.index(end)+1:tags.index(start)+1); | ||
32 | + tags.wrapAll('<div class=\"macro article_comments\" data-macro=\"comment_paragraph_plugin/allow_comment\" data-macro-paragraph_id=\"'+getNextParagraphId()+'\"/>'); | ||
33 | + | ||
34 | + contents = jQuery('#article_body_ifr').contents(); | ||
35 | + lastP = contents.find('p.article_comments_last_paragraph'); | ||
36 | + if(lastP.text().trim().length > 0) { | ||
37 | + lastP.removeClass('article_comments_last_paragraph'); | ||
38 | + } else { | ||
39 | + lastP.remove(); | ||
40 | + } | ||
41 | + lastDiv = contents.find('div.article_comments').last(); | ||
42 | + if(lastDiv.next().length==0) { | ||
43 | + lastDiv.after("<p class='article_comments_last_paragraph'> </p>"); | ||
44 | + } | ||
45 | + } | ||
46 | +} | ||
47 | + |
plugins/comment_paragraph/public/comment_paragraph_macro.js
0 → 100644
@@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
1 | +var comment_paragraph_anchor; | ||
2 | +jQuery(document).ready(function($) { | ||
3 | + var anchor = window.location.hash; | ||
4 | + if(anchor.length==0) return; | ||
5 | + | ||
6 | + var val = anchor.split('-'); //anchor format = #comment-\d+ | ||
7 | + if(val.length!=2 || val[0]!='#comment') return; | ||
8 | + if($('div[data-macro=comment_paragraph_plugin/allow_comment]').length==0) return; //comment_paragraph_plugin/allow_comment div must exists | ||
9 | + var comment_id = val[1]; | ||
10 | + if(!/^\d+$/.test(comment_id)) return; //test for integer | ||
11 | + | ||
12 | + comment_paragraph_anchor = anchor; | ||
13 | + var url = '/plugin/comment_paragraph/public/comment_paragraph/'+comment_id; | ||
14 | + $.getJSON(url, function(data) { | ||
15 | + if(data.paragraph_id!=null) { | ||
16 | + var button = $('div.comment_paragraph_'+ data.paragraph_id + ' a'); | ||
17 | + button.click(); | ||
18 | + $.scrollTo(button); | ||
19 | + } | ||
20 | + }); | ||
21 | +}); | ||
22 | + | ||
23 | +function toggleParagraph(paragraph) { | ||
24 | + var div = jQuery('div.comments_list_toggle_paragraph_'+paragraph); | ||
25 | + var visible = div.is(':visible'); | ||
26 | + if(!visible) | ||
27 | + jQuery('div.comment-paragraph-loading-'+paragraph).addClass('comment-button-loading'); | ||
28 | + | ||
29 | + div.toggle('fast'); | ||
30 | + return visible; | ||
31 | +} | ||
32 | + | ||
33 | +function loadCompleted(paragraph) { | ||
34 | + jQuery('div.comment-paragraph-loading-'+paragraph).removeClass('comment-button-loading') | ||
35 | + if(comment_paragraph_anchor) { | ||
36 | + jQuery.scrollTo(jQuery(comment_paragraph_anchor)); | ||
37 | + comment_paragraph_anchor = null; | ||
38 | + } | ||
39 | +} |
1.66 KB
plugins/comment_paragraph/test/functional/comment_group_plugin_profile_controller_test.rb
0 → 100644
@@ -0,0 +1,72 @@ | @@ -0,0 +1,72 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | +require File.dirname(__FILE__) + '/../../controllers/profile/comment_paragraph_plugin_profile_controller' | ||
3 | + | ||
4 | +# Re-raise errors caught by the controller. | ||
5 | +class CommentParagraphPluginProfileController; def rescue_action(e) raise e end; end | ||
6 | + | ||
7 | +class CommentParagraphPluginProfileControllerTest < ActionController::TestCase | ||
8 | + | ||
9 | + def setup | ||
10 | + @controller = CommentParagraphPluginProfileController.new | ||
11 | + @request = ActionController::TestRequest.new | ||
12 | + @response = ActionController::TestResponse.new | ||
13 | + | ||
14 | + @profile = create_user('testuser').person | ||
15 | + @article = profile.articles.build(:name => 'test') | ||
16 | + @article.save! | ||
17 | + end | ||
18 | + attr_reader :article | ||
19 | + attr_reader :profile | ||
20 | + | ||
21 | + should 'be able to show paragraph comments' do | ||
22 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_id => 0) | ||
23 | + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_id => 0 | ||
24 | + assert_template 'comment_paragraph_plugin_profile/view_comments' | ||
25 | + assert_match /comments_list_paragraph_0/, @response.body | ||
26 | + assert_match /\"comment-count-0\", \"1\"/, @response.body | ||
27 | + end | ||
28 | + | ||
29 | + should 'do not show global comments' do | ||
30 | + fast_create(Comment, :source_id => article, :author_id => profile, :title => 'global comment', :body => 'global', :paragraph_id => nil) | ||
31 | + fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_id => 0) | ||
32 | + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_id => 0 | ||
33 | + assert_template 'comment_paragraph_plugin_profile/view_comments' | ||
34 | + assert_match /comments_list_paragraph_0/, @response.body | ||
35 | + assert_match /\"comment-count-0\", \"1\"/, @response.body | ||
36 | + end | ||
37 | + | ||
38 | + should 'show first page comments only' do | ||
39 | + comment1 = fast_create(Comment, :created_at => Time.now - 1.days, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'secondpage', :paragraph_id => 0) | ||
40 | + comment2 = fast_create(Comment, :created_at => Time.now - 2.days, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 1', :paragraph_id => 0) | ||
41 | + comment3 = fast_create(Comment, :created_at => Time.now - 3.days, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 2', :paragraph_id => 0) | ||
42 | + comment4 = fast_create(Comment, :created_at => Time.now - 4.days, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 3', :paragraph_id => 0) | ||
43 | + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_id => 0 | ||
44 | + assert_match /firstpage 1/, @response.body | ||
45 | + assert_match /firstpage 2/, @response.body | ||
46 | + assert_match /firstpage 3/, @response.body | ||
47 | + assert_no_match /secondpage/, @response.body | ||
48 | + end | ||
49 | + | ||
50 | + should 'show link to display more comments' do | ||
51 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_id => 0) | ||
52 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_id => 0) | ||
53 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_id => 0) | ||
54 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'secondpage', :body => 'secondpage', :paragraph_id => 0) | ||
55 | + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_id => 0 | ||
56 | + assert_match /paragraph_comment_page=2/, @response.body | ||
57 | + end | ||
58 | + | ||
59 | + should 'do not show link to display more comments if do not have more pages' do | ||
60 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_id => 0) | ||
61 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_id => 0) | ||
62 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_id => 0) | ||
63 | + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_id => 0 | ||
64 | + assert_no_match /paragraph_comment_page/, @response.body | ||
65 | + end | ||
66 | + | ||
67 | + should 'do not show link to display more comments if do not have any comments' do | ||
68 | + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_id => 0 | ||
69 | + assert_no_match /paragraph_comment_page/, @response.body | ||
70 | + end | ||
71 | + | ||
72 | +end |
plugins/comment_paragraph/test/functional/comment_group_plugin_public_controller_test.rb
0 → 100644
@@ -0,0 +1,33 @@ | @@ -0,0 +1,33 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | +require File.dirname(__FILE__) + '/../../controllers/public/comment_paragraph_plugin_public_controller' | ||
3 | + | ||
4 | +# Re-raise errors caught by the controller. | ||
5 | +class CommentParagraphPluginPublicController; def rescue_action(e) raise e end; end | ||
6 | + | ||
7 | +class CommentParagraphPluginPublicControllerTest < ActionController::TestCase | ||
8 | + | ||
9 | + def setup | ||
10 | + @controller = CommentParagraphPluginPublicController.new | ||
11 | + @request = ActionController::TestRequest.new | ||
12 | + @response = ActionController::TestResponse.new | ||
13 | + | ||
14 | + @profile = create_user('testuser').person | ||
15 | + @article = profile.articles.build(:name => 'test') | ||
16 | + @article.save! | ||
17 | + end | ||
18 | + attr_reader :article | ||
19 | + attr_reader :profile | ||
20 | + | ||
21 | + should 'be able to return paragraph_id for a comment' do | ||
22 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_id => 0) | ||
23 | + xhr :get, :comment_paragraph, :id => comment.id | ||
24 | + assert_match /\{\"paragraph_id\":0\}/, @response.body | ||
25 | + end | ||
26 | + | ||
27 | + should 'return paragraph_id=null for a global comment' do | ||
28 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala' ) | ||
29 | + xhr :get, :comment_paragraph, :id => comment.id | ||
30 | + assert_match /\{\"paragraph_id\":null\}/, @response.body | ||
31 | + end | ||
32 | + | ||
33 | +end |
plugins/comment_paragraph/test/functional/content_viewer_controller_test.rb
0 → 100644
@@ -0,0 +1,28 @@ | @@ -0,0 +1,28 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class ContentViewerController | ||
4 | + append_view_path File.join(File.dirname(__FILE__) + '/../../views') | ||
5 | + def rescue_action(e) | ||
6 | + raise e | ||
7 | + end | ||
8 | +end | ||
9 | + | ||
10 | +class ContentViewerControllerTest < ActionController::TestCase | ||
11 | + | ||
12 | + def setup | ||
13 | + @profile = fast_create(Community) | ||
14 | + @page = fast_create(Article, :profile_id => @profile.id, :body => "<div class=\"macro\" data-macro-paragraph_id=\"1\" data-macro='comment_paragraph_plugin/allow_comment' ></div>") | ||
15 | + @environment = Environment.default | ||
16 | + @environment.enable_plugin(CommentParagraphPlugin) | ||
17 | + end | ||
18 | + | ||
19 | + attr_reader :page | ||
20 | + | ||
21 | + should 'parse article body and render comment paragraph view' do | ||
22 | + comment1 = fast_create(Comment, :paragraph_id => 1, :source_id => page.id) | ||
23 | + get :view_page, @page.url | ||
24 | + assert_tag 'div', :attributes => {:class => 'comment_paragraph_1'} | ||
25 | + assert_tag 'div', :attributes => {:id => 'comments_paragraph_count_1'} | ||
26 | + end | ||
27 | + | ||
28 | +end |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../test/test_helper' |
plugins/comment_paragraph/test/unit/allow_comment_test.rb
0 → 100644
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class AllowCommentTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + @macro = CommentParagraphPlugin::AllowComment.new | ||
7 | + end | ||
8 | + | ||
9 | + attr_reader :macro | ||
10 | + | ||
11 | + should 'have a configuration' do | ||
12 | + assert CommentParagraphPlugin::AllowComment.configuration | ||
13 | + end | ||
14 | + | ||
15 | + should 'parse contents to include comment paragraph view' do | ||
16 | + profile = fast_create(Community) | ||
17 | + article = fast_create(Article, :profile_id => profile.id) | ||
18 | + comment = fast_create(Comment, :paragraph_id => 1, :source_id => article.id) | ||
19 | + inner_html = 'inner' | ||
20 | + content = macro.parse({:paragraph_id => comment.paragraph_id}, inner_html, article) | ||
21 | + | ||
22 | + expects(:render).with({:partial => 'comment_paragraph_plugin_profile/comment_paragraph', :locals => {:paragraph_id => comment.paragraph_id, :article_id => article.id, :inner_html => inner_html, :count => 1, :profile_identifier => profile.identifier} }) | ||
23 | + instance_eval(&content) | ||
24 | + end | ||
25 | + | ||
26 | +end |
@@ -0,0 +1,56 @@ | @@ -0,0 +1,56 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | +require 'benchmark' | ||
3 | + | ||
4 | +class ArticleTest < ActiveSupport::TestCase | ||
5 | + | ||
6 | + def setup | ||
7 | + profile = fast_create(Community) | ||
8 | + @article = fast_create(Article, :profile_id => profile.id) | ||
9 | + end | ||
10 | + | ||
11 | + attr_reader :article | ||
12 | + | ||
13 | + should 'return paragraph comments from article' do | ||
14 | + comment1 = fast_create(Comment, :paragraph_id => 1, :source_id => article.id) | ||
15 | + comment2 = fast_create(Comment, :paragraph_id => nil, :source_id => article.id) | ||
16 | + assert_equal [comment1], article.paragraph_comments | ||
17 | + end | ||
18 | + | ||
19 | + should 'do not allow a exclusion of a paragraph comment macro if this paragraph has comments' do | ||
20 | + article.body = "<div class=\"macro\" data-macro-paragraph_id=2></div>" | ||
21 | + comment1 = fast_create(Comment, :paragraph_id => 1, :source_id => article.id) | ||
22 | + assert !article.save | ||
23 | + assert_equal ['Not empty paragraph comment cannot be removed'], article.errors[:base] | ||
24 | + end | ||
25 | + | ||
26 | + should 'allow save if comment paragraph macro is not removed for paragraph with comments' do | ||
27 | + article.body = "<div class=\"macro\" data-macro-paragraph_id=1></div>" | ||
28 | + comment1 = fast_create(Comment, :paragraph_id => 1, :source_id => article.id) | ||
29 | + assert article.save | ||
30 | + end | ||
31 | + | ||
32 | + should 'do not validate empty paragraph if article body is not changed' do | ||
33 | + article.body = "<div class=\"macro\" data-macro-paragraph_id=2></div>" | ||
34 | + assert article.save | ||
35 | + comment1 = fast_create(Comment, :paragraph_id => 1, :source_id => article.id) | ||
36 | + article.name = article.name + 'changed' | ||
37 | + assert article.save | ||
38 | + end | ||
39 | + | ||
40 | + should 'improve performance checking changes in body' do | ||
41 | + i = 1 | ||
42 | + time0 = (Benchmark.measure { 50.times { | ||
43 | + i = i + 1 | ||
44 | + article.body = "i = #{i}" | ||
45 | + assert article.save | ||
46 | + }}) | ||
47 | + i = 1 | ||
48 | + time1 = (Benchmark.measure { 50.times { | ||
49 | + i = i + 1 | ||
50 | + article.body = "i = 1" | ||
51 | + assert article.save | ||
52 | + }}) | ||
53 | + assert time0.total > time1.total | ||
54 | + end | ||
55 | + | ||
56 | +end |
plugins/comment_paragraph/test/unit/comment_paragraph_plugin_test.rb
0 → 100644
@@ -0,0 +1,60 @@ | @@ -0,0 +1,60 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class CommentParagraphPluginTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + @environment = Environment.default | ||
7 | + @plugin = CommentParagraphPlugin.new | ||
8 | + end | ||
9 | + | ||
10 | + attr_reader :environment, :plugin | ||
11 | + | ||
12 | + should 'have a name' do | ||
13 | + assert_not_equal Noosfero::Plugin.plugin_name, CommentParagraphPlugin::plugin_name | ||
14 | + end | ||
15 | + | ||
16 | + should 'describe yourself' do | ||
17 | + assert_not_equal Noosfero::Plugin.plugin_description, CommentParagraphPlugin::plugin_description | ||
18 | + end | ||
19 | + | ||
20 | + should 'have a js file' do | ||
21 | + assert !plugin.js_files.blank? | ||
22 | + end | ||
23 | + | ||
24 | + should 'have stylesheet' do | ||
25 | + assert plugin.stylesheet? | ||
26 | + end | ||
27 | + | ||
28 | + should 'have extra contents for comment form' do | ||
29 | + comment = fast_create(Comment, :paragraph_id => 1) | ||
30 | + content = plugin.comment_form_extra_contents({:comment => comment}) | ||
31 | + expects(:hidden_field_tag).with('comment[paragraph_id]', comment.paragraph_id).once | ||
32 | + instance_eval(&content) | ||
33 | + end | ||
34 | + | ||
35 | + should 'do not have extra contents for comments without paragraph' do | ||
36 | + comment = fast_create(Comment, :paragraph_id => nil) | ||
37 | + content = plugin.comment_form_extra_contents({:comment => comment}) | ||
38 | + assert_equal nil, instance_eval(&content) | ||
39 | + end | ||
40 | + | ||
41 | + should 'call without_paragraph for scope passed as parameter to unavailable_comments' do | ||
42 | + article = fast_create(Article) | ||
43 | + article.expects(:without_paragraph).once | ||
44 | + plugin.unavailable_comments(article) | ||
45 | + end | ||
46 | + | ||
47 | +#FIXME Obsolete test | ||
48 | +# | ||
49 | +# should 'filter_comments returns all the comments wihout paragraph of an article passed as parameter' do | ||
50 | +# article = fast_create(Article) | ||
51 | +# c1 = fast_create(Comment, :source_id => article.id, :paragraph_id => 1) | ||
52 | +# c2 = fast_create(Comment, :source_id => article.id) | ||
53 | +# c3 = fast_create(Comment, :source_id => article.id) | ||
54 | +# | ||
55 | +# plugin = CommentParagraphPlugin.new | ||
56 | +# assert_equal [], [c2, c3] - plugin.filter_comments(article.comments) | ||
57 | +# assert_equal [], plugin.filter_comments(article.comments) - [c2, c3] | ||
58 | +# end | ||
59 | + | ||
60 | +end |
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class CommentTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + profile = fast_create(Community) | ||
7 | + @article = fast_create(Article, :profile_id => profile.id) | ||
8 | + end | ||
9 | + | ||
10 | + attr_reader :article | ||
11 | + | ||
12 | + should 'return comments that belongs to a specified paragraph' do | ||
13 | + comment1 = fast_create(Comment, :paragraph_id => 1, :source_id => article.id) | ||
14 | + comment2 = fast_create(Comment, :paragraph_id => nil, :source_id => article.id) | ||
15 | + comment3 = fast_create(Comment, :paragraph_id => 2, :source_id => article.id) | ||
16 | + assert_equal [comment1], article.comments.in_paragraph(1) | ||
17 | + end | ||
18 | + | ||
19 | + should 'return comments that do not belongs to any paragraph' do | ||
20 | + comment1 = fast_create(Comment, :paragraph_id => 1, :source_id => article.id) | ||
21 | + comment2 = fast_create(Comment, :paragraph_id => nil, :source_id => article.id) | ||
22 | + comment3 = fast_create(Comment, :paragraph_id => 2, :source_id => article.id) | ||
23 | + assert_equal [comment2], article.comments.without_paragraph | ||
24 | + end | ||
25 | + | ||
26 | +end |
plugins/comment_paragraph/views/comment_paragraph_plugin_profile/_comment_paragraph.html.erb
0 → 100644
@@ -0,0 +1,31 @@ | @@ -0,0 +1,31 @@ | ||
1 | +<div class="comments"> | ||
2 | + <div class="comment_paragraph_<%= paragraph_id %>" style="float: left"> | ||
3 | + <div style="float: left"> | ||
4 | + <%= link_to_remote(image_tag("/plugins/comment_paragraph/images/comments.gif"), | ||
5 | + :url => { :profile => profile_identifier, :controller => 'comment_paragraph_plugin_profile', :action => 'view_comments', :paragraph_id => paragraph_id, :article_id => article_id}, | ||
6 | + :method => :post, | ||
7 | + :condition => "!toggleParagraph(#{paragraph_id})", | ||
8 | + :complete => "loadCompleted(#{paragraph_id})")%> | ||
9 | + </div> | ||
10 | + <!-- FIXME: css file --> | ||
11 | + <div id="comments_paragraph_count_<%= paragraph_id %>" style="float: right; vertical-align: middle; padding-left: 3px; padding-right: 5px; color: #5AC1FC"><span id="comment-count-<%= paragraph_id %>" class='comment-count'><%= count %></span></div> | ||
12 | + | ||
13 | + </div> | ||
14 | + | ||
15 | + <div> | ||
16 | + <%= inner_html %> | ||
17 | + </div> | ||
18 | + | ||
19 | + <div class="comment-paragraph-loading-<%= paragraph_id %>"/> | ||
20 | + | ||
21 | + <div class="comments_list_toggle_paragraph_<%= paragraph_id %>" style="display:none"> | ||
22 | + <div class="article-comments-list" id="comments_list_paragraph_<%= paragraph_id %>"> | ||
23 | + </div> | ||
24 | + <div class ="article-comments-list-more" id="comments_list_paragraph_<%= paragraph_id %>_more"> | ||
25 | + </div> | ||
26 | + <div id="page-comment-form-<%= paragraph_id %>" class='post_comment_box closed'> | ||
27 | + <%= render :partial => 'comment/comment_form', :locals => {:comment => Comment.new, :display_link => true, :cancel_triggers_hide => true, :paragraph_id => paragraph_id}%> | ||
28 | + </div> | ||
29 | + | ||
30 | + </div> | ||
31 | +</div> |
plugins/comment_paragraph/views/comment_paragraph_plugin_profile/view_comments.rjs
0 → 100644
@@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
1 | +if @paragraph_comment_page == 1 | ||
2 | + page.replace_html "comments_list_paragraph_#{@paragraph_id}", :partial => 'comment/comment.html.erb', :collection => @comments | ||
3 | +else | ||
4 | + page.insert_html :bottom, "comments_list_paragraph_#{@paragraph_id}", :partial => 'comment/comment.html.erb', :collection => @comments | ||
5 | +end | ||
6 | +page.replace_html "comment-count-#{@paragraph_id}", @comments_count | ||
7 | + | ||
8 | +if @no_more_pages | ||
9 | + page.replace_html "comments_list_paragraph_#{@paragraph_id}_more", "" | ||
10 | +else | ||
11 | + page.replace_html "comments_list_paragraph_#{@paragraph_id}_more", link_to_remote(_('More'), :url => { :profile => profile.identifier, :controller => 'comment_paragraph_plugin_profile', :action => 'view_comments', :paragraph_id => @paragraph_id, :article_id => @article_id, :paragraph_comment_page => @paragraph_comment_page + 1}, :loaded => visual_effect(:highlight, "comments_list_paragraph_#{@paragraph_id}"), :method => :post, :complete => "loadCompleted(#{@paragraph_id})") | ||
12 | +end |