diff --git a/app/helpers/comment_helper.rb b/app/helpers/comment_helper.rb index 6311169..4c8760d 100644 --- a/app/helpers/comment_helper.rb +++ b/app/helpers/comment_helper.rb @@ -22,6 +22,12 @@ module CommentHelper title end + def comment_extra_contents(comment) + @plugins.dispatch(:comment_extra_contents, comment).collect do |extra_content| + extra_content.kind_of?(Proc) ? self.instance_eval(&extra_content) : extra_content + end.join('\n') + end + def comment_actions(comment) url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id) links = links_for_comment_actions(comment) diff --git a/app/views/content_viewer/view_page.rhtml b/app/views/content_viewer/view_page.rhtml index f3f83dc..f57ea88 100644 --- a/app/views/content_viewer/view_page.rhtml +++ b/app/views/content_viewer/view_page.rhtml @@ -84,6 +84,8 @@ <%= display_source_info(@page) %> +<%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_eval(&content) }.join("") %> +
<% if @page.accept_comments? || @comments_count > 0 %> diff --git a/lib/noosfero/plugin.rb b/lib/noosfero/plugin.rb index eed5ac5..4927c87 100644 --- a/lib/noosfero/plugin.rb +++ b/lib/noosfero/plugin.rb @@ -349,6 +349,12 @@ class Noosfero::Plugin [] end + # -> Adds adicional content to article + # returns = lambda block that creates html code + def article_extra_contents(article) + nil + end + # -> Adds fields to the signup form # returns = lambda block that creates html code def signup_extra_contents diff --git a/plugins/mark_comment_as_read/controllers/mark_comment_as_read_plugin_profile_controller.rb b/plugins/mark_comment_as_read/controllers/mark_comment_as_read_plugin_profile_controller.rb new file mode 100644 index 0000000..9f2fde9 --- /dev/null +++ b/plugins/mark_comment_as_read/controllers/mark_comment_as_read_plugin_profile_controller.rb @@ -0,0 +1,17 @@ +class MarkCommentAsReadPluginProfileController < ProfileController + + append_view_path File.join(File.dirname(__FILE__) + '/../views') + + def mark_as_read + comment = Comment.find(params[:id]) + comment.mark_as_read(user) + render :text => {'ok' => true}.to_json, :content_type => 'application/json' + end + + def mark_as_not_read + comment = Comment.find(params[:id]) + comment.mark_as_not_read(user) + render :text => {'ok' => true}.to_json, :content_type => 'application/json' + end + +end diff --git a/plugins/mark_comment_as_read/db/migrate/20130509184338_create_mark_comment_as_read_plugin.rb b/plugins/mark_comment_as_read/db/migrate/20130509184338_create_mark_comment_as_read_plugin.rb new file mode 100644 index 0000000..7d8f789 --- /dev/null +++ b/plugins/mark_comment_as_read/db/migrate/20130509184338_create_mark_comment_as_read_plugin.rb @@ -0,0 +1,13 @@ +class CreateMarkCommentAsReadPlugin < ActiveRecord::Migration + def self.up + create_table :mark_comment_as_read_plugin do |t| + t.integer :comment_id + t.integer :person_id + end + add_index :mark_comment_as_read_plugin, [:comment_id, :person_id], :unique => true + end + + def self.down + drop_table :mark_comment_as_read_plugin + end +end diff --git a/plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin.rb b/plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin.rb new file mode 100644 index 0000000..a816e21 --- /dev/null +++ b/plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin.rb @@ -0,0 +1,45 @@ +require_dependency 'mark_comment_as_read_plugin/ext/comment' + +class MarkCommentAsReadPlugin < Noosfero::Plugin + + def self.plugin_name + "MarkCommentAsReadPlugin" + end + + def self.plugin_description + _("Provide a button to mark a comment as read.") + end + + def js_files + 'mark_comment_as_read.js' + end + + def stylesheet? + true + end + + def comment_actions(comment) + lambda do + [{:link => link_to_function(_('Mark as not read'), 'toggle_comment_read(this, %s, false);' % url_for(:controller => 'mark_comment_as_read_plugin_profile', :profile => profile.identifier, :action => 'mark_as_not_read', :id => comment.id).to_json, :class => 'comment-footer comment-footer-link comment-footer-hide comment-action-extra', :style => 'display: none', :id => "comment-action-mark-as-not-read-#{comment.id}")}, + {:link => link_to_function(_('Mark as read'), 'toggle_comment_read(this, %s, true);' % url_for(:controller => 'mark_comment_as_read_plugin_profile', :profile => profile.identifier, :action => 'mark_as_read', :id => comment.id).to_json, :class => 'comment-footer comment-footer-link comment-footer-hide comment-action-extra', :style => 'display: none', :id => "comment-action-mark-as-read-#{comment.id}")}] if user + end + end + + def check_comment_actions(comment) + lambda do + if user + comment.marked_as_read?(user) ? "#comment-action-mark-as-not-read-#{comment.id}" : "#comment-action-mark-as-read-#{comment.id}" + end + end + end + + def article_extra_contents(article) + lambda do + if user + ids = article.comments.marked_as_read(user).collect { |comment| comment.id} + "" if !ids.empty? + end + end + end + +end diff --git a/plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin/ext/comment.rb b/plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin/ext/comment.rb new file mode 100644 index 0000000..15ec814 --- /dev/null +++ b/plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin/ext/comment.rb @@ -0,0 +1,24 @@ +require_dependency 'comment' + +class Comment + + has_many :read_comments, :class_name => 'MarkCommentAsReadPlugin::ReadComments' + has_many :people, :through => :read_comments + + def mark_as_read(person) + people << person + end + + def mark_as_not_read(person) + people.delete(person) + end + + def marked_as_read?(person) + person && people.find(:first, :conditions => {:id => person.id}) + end + + def self.marked_as_read(person) + find(:all, :joins => [:read_comments], :conditions => {:author_id => person.id}) + end + +end diff --git a/plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin/read_comments.rb b/plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin/read_comments.rb new file mode 100644 index 0000000..9ce10b7 --- /dev/null +++ b/plugins/mark_comment_as_read/lib/mark_comment_as_read_plugin/read_comments.rb @@ -0,0 +1,7 @@ +class MarkCommentAsReadPlugin::ReadComments < Noosfero::Plugin::ActiveRecord + set_table_name 'mark_comment_as_read_plugin' + belongs_to :comment + belongs_to :person + + validates_presence_of :comment, :person +end diff --git a/plugins/mark_comment_as_read/public/mark_comment_as_read.js b/plugins/mark_comment_as_read/public/mark_comment_as_read.js new file mode 100644 index 0000000..16cfc4f --- /dev/null +++ b/plugins/mark_comment_as_read/public/mark_comment_as_read.js @@ -0,0 +1,28 @@ +function mark_comments_as_read(comments) { + jQuery(document).ready(function($) { + for(var i=0; i @profile, :name => 'An article') + @comment = Comment.new(:source => @article, :author => @profile, :body => 'test') + @comment.save! + login_as(@profile.identifier) + environment = Environment.default + environment.enable_plugin(MarkCommentAsReadPlugin) + self.stubs(:user).returns(@profile) + end + + attr_reader :profile, :comment + + should 'mark comment as read' do + xhr :post, :mark_as_read, :profile => profile.identifier, :id => comment.id + assert_match /\{\"ok\":true\}/, @response.body + end + + should 'mark comment as not read' do + xhr :post, :mark_as_not_read, :profile => profile.identifier, :id => comment.id + assert_match /\{\"ok\":true\}/, @response.body + end +end diff --git a/plugins/mark_comment_as_read/test/unit/mark_comment_as_read_plugin/comment_test.rb b/plugins/mark_comment_as_read/test/unit/mark_comment_as_read_plugin/comment_test.rb new file mode 100644 index 0000000..8c41450 --- /dev/null +++ b/plugins/mark_comment_as_read/test/unit/mark_comment_as_read_plugin/comment_test.rb @@ -0,0 +1,38 @@ +require File.dirname(__FILE__) + '/../../../../../test/test_helper' + +class MarkCommentAsReadPlugin::CommentTest < ActiveSupport::TestCase + + def setup + @person = create_user('user').person + @article = TinyMceArticle.create!(:profile => @person, :name => 'An article') + @comment = Comment.create!(:title => 'title', :body => 'body', :author_id => @person.id, :source => @article) + end + + should 'mark comment as read' do + assert !@comment.marked_as_read?(@person) + @comment.mark_as_read(@person) + assert @comment.marked_as_read?(@person) + end + + should 'do not mark a comment as read again' do + @comment.mark_as_read(@person) + assert_raise ActiveRecord::StatementInvalid do + @comment.mark_as_read(@person) + end + end + + should 'mark comment as not read' do + @comment.mark_as_read(@person) + assert @comment.marked_as_read?(@person) + @comment.mark_as_not_read(@person) + assert !@comment.marked_as_read?(@person) + end + + should 'return comments marked as read for a user' do + person2 = create_user('user2').person + @comment.mark_as_read(@person) + assert_equal [], @article.comments.marked_as_read(@person) - [@comment] + assert_equal [], @article.comments.marked_as_read(person2) + end + +end diff --git a/plugins/mark_comment_as_read/test/unit/mark_comment_as_read_test.rb b/plugins/mark_comment_as_read/test/unit/mark_comment_as_read_test.rb new file mode 100644 index 0000000..5a1c8fd --- /dev/null +++ b/plugins/mark_comment_as_read/test/unit/mark_comment_as_read_test.rb @@ -0,0 +1,87 @@ +require File.dirname(__FILE__) + '/../../../../test/test_helper' + +class MarkCommentAsReadPluginTest < ActiveSupport::TestCase + + include ActionView::Helpers::TagHelper + include NoosferoTestHelper + + def setup + @plugin = MarkCommentAsReadPlugin.new + @person = create_user('user').person + @article = TinyMceArticle.create!(:profile => @person, :name => 'An article') + @comment = Comment.create!(:source => @article, :author => @person, :body => 'test') + self.stubs(:user).returns(@person) + self.stubs(:profile).returns(@person) + end + + attr_reader :plugin, :comment + + should 'show link when person is logged in' do + action = @plugin.comment_actions(@comment) + link = self.instance_eval(&action) + assert link + end + + should 'do not show link when person is not logged in' do + self.stubs(:user).returns(nil) + action = @plugin.comment_actions(@comment) + link = self.instance_eval(&action) + assert !link + end + + should 'return actions when comment is not read' do + action = @plugin.comment_actions(@comment) + links = self.instance_eval(&action) + assert_equal 2, links.size + end + + should 'return actions when comment is read' do + @comment.mark_as_read(@person) + action = @plugin.comment_actions(@comment) + links = self.instance_eval(&action) + assert_equal 2, links.size + end + + should 'do not return any id when user is not logged in' do + self.stubs(:user).returns(nil) + action = @plugin.check_comment_actions(@comment) + id = self.instance_eval(&action) + assert !id + end + + should 'return id of mark as not read link when comment is read' do + @comment.mark_as_read(@person) + action = @plugin.check_comment_actions(@comment) + id = self.instance_eval(&action) + assert_equal "#comment-action-mark-as-not-read-#{@comment.id}", id + end + + should 'return id of mark as read link when comment is not read' do + action = @plugin.check_comment_actions(@comment) + id = self.instance_eval(&action) + assert_equal "#comment-action-mark-as-read-#{@comment.id}", id + end + + should 'return javascript to mark comment as read' do + @comment.mark_as_read(@person) + content = @plugin.article_extra_contents(@article) + assert self.instance_eval(&content) + end + + should 'do not return extra content if comment is not marked as read' do + content = @plugin.article_extra_contents(@article) + assert !self.instance_eval(&content) + end + + should 'do not return extra content if user is not logged in' do + @comment.mark_as_read(@person) + self.stubs(:user).returns(nil) + content = @plugin.article_extra_contents(@article) + assert !self.instance_eval(&content) + end + + def link_to_function(content, url, options = {}) + link_to(content, url, options) + end + +end diff --git a/test/unit/plugin_test.rb b/test/unit/plugin_test.rb index 80b38e7..50cc012 100644 --- a/test/unit/plugin_test.rb +++ b/test/unit/plugin_test.rb @@ -496,4 +496,29 @@ class PluginTest < ActiveSupport::TestCase end end + should 'comment_actions be nil if the comment is nil' do + class SomePlugin < Noosfero::Plugin; end + plugin = SomePlugin.new + assert_nil plugin.comment_actions(nil) + end + + should 'comment_actions be nil by default' do + class SomePlugin < Noosfero::Plugin; end + plugin = SomePlugin.new + assert_nil plugin.comment_actions(Comment.new) + end + + should 'check_comment_actions be an empty array if the comment is nil' do + class SomePlugin < Noosfero::Plugin; end + plugin = SomePlugin.new + assert_equal [], plugin.check_comment_actions(nil) + end + + + should 'check_comment_actions be an empty array by default' do + class SomePlugin < Noosfero::Plugin; end + plugin = SomePlugin.new + assert_equal [], plugin.check_comment_actions(Comment.new) + end + end -- libgit2 0.21.2