##// END OF EJS Templates
Adds a News#commentable? method to easily specific additional rules....
Jean-Philippe Lang -
r8734:8ddcc4caf51c
parent child
Show More
@@ -1,36 +1,54
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
1 18 class CommentsController < ApplicationController
2 19 default_search_scope :news
3 20 model_object News
4 21 before_filter :find_model_object
5 22 before_filter :find_project_from_association
6 23 before_filter :authorize
7 24
8 25 verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
9 26 def create
27 raise Unauthorized unless @news.commentable?
28
10 29 @comment = Comment.new(params[:comment])
11 30 @comment.author = User.current
12 31 if @news.comments << @comment
13 32 flash[:notice] = l(:label_comment_added)
14 33 end
15 34
16 35 redirect_to :controller => 'news', :action => 'show', :id => @news
17 36 end
18 37
19 38 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
20 39 def destroy
21 40 @news.comments.find(params[:comment_id]).destroy
22 41 redirect_to :controller => 'news', :action => 'show', :id => @news
23 42 end
24 43
25 44 private
26 45
27 46 # ApplicationController's find_model_object sets it based on the controller
28 47 # name so it needs to be overriden and set to @news instead
29 48 def find_model_object
30 49 super
31 50 @news = @object
32 51 @comment = nil
33 52 @news
34 53 end
35
36 54 end
@@ -1,58 +1,63
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class News < ActiveRecord::Base
19 19 belongs_to :project
20 20 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
21 21 has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
22 22
23 23 validates_presence_of :title, :description
24 24 validates_length_of :title, :maximum => 60
25 25 validates_length_of :summary, :maximum => 255
26 26
27 27 acts_as_attachable :delete_permission => :manage_news
28 28 acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"], :include => :project
29 29 acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}}
30 30 acts_as_activity_provider :find_options => {:include => [:project, :author]},
31 31 :author_key => :author_id
32 32 acts_as_watchable
33 33
34 34 after_create :add_author_as_watcher
35 35
36 36 named_scope :visible, lambda {|*args| {
37 37 :include => :project,
38 38 :conditions => Project.allowed_to_condition(args.shift || User.current, :view_news, *args)
39 39 }}
40 40
41 41 def visible?(user=User.current)
42 42 !user.nil? && user.allowed_to?(:view_news, project)
43 43 end
44 44
45 # Returns true if the news can be commented by user
46 def commentable?(user=User.current)
47 user.allowed_to?(:comment_news, project)
48 end
49
45 50 # returns latest news for projects visible by user
46 51 def self.latest(user = User.current, count = 5)
47 52 find(:all, :limit => count,
48 53 :conditions => Project.allowed_to_condition(user, :view_news),
49 54 :include => [ :author, :project ],
50 55 :order => "#{News.table_name}.created_on DESC")
51 56 end
52 57
53 58 private
54 59
55 60 def add_author_as_watcher
56 61 Watcher.create(:watchable => self, :user => author)
57 62 end
58 63 end
@@ -1,71 +1,71
1 1 <div class="contextual">
2 2 <%= watcher_tag(@news, User.current) %>
3 3 <%= link_to(l(:button_edit),
4 4 edit_news_path(@news),
5 5 :class => 'icon icon-edit',
6 6 :accesskey => accesskey(:edit),
7 7 :onclick => 'Element.show("edit-news"); return false;') if User.current.allowed_to?(:manage_news, @project) %>
8 8 <%= link_to(l(:button_delete),
9 9 news_path(@news),
10 10 :confirm => l(:text_are_you_sure),
11 11 :method => :delete,
12 12 :class => 'icon icon-del') if User.current.allowed_to?(:manage_news, @project) %>
13 13 </div>
14 14
15 15 <h2><%= avatar(@news.author, :size => "24") %><%=h @news.title %></h2>
16 16
17 17 <% if authorize_for('news', 'edit') %>
18 18 <div id="edit-news" style="display:none;">
19 19 <% labelled_form_for :news, @news, :url => news_path(@news),
20 20 :html => { :id => 'news-form', :multipart => true, :method => :put } do |f| %>
21 21 <%= render :partial => 'form', :locals => { :f => f } %>
22 22 <%= submit_tag l(:button_save) %>
23 23 <%= link_to_remote l(:label_preview),
24 24 { :url => preview_news_path(:project_id => @project),
25 25 :method => 'get',
26 26 :update => 'preview',
27 27 :with => "Form.serialize('news-form')"
28 28 }, :accesskey => accesskey(:preview) %> |
29 29 <%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("edit-news"); return false;' %>
30 30 <% end %>
31 31 <div id="preview" class="wiki"></div>
32 32 </div>
33 33 <% end %>
34 34
35 35 <p><% unless @news.summary.blank? %><em><%=h @news.summary %></em><br /><% end %>
36 36 <span class="author"><%= authoring @news.created_on, @news.author %></span></p>
37 37 <div class="wiki">
38 38 <%= textilizable(@news, :description) %>
39 39 </div>
40 40 <%= link_to_attachments @news %>
41 41 <br />
42 42
43 43 <div id="comments" style="margin-bottom:16px;">
44 44 <h3 class="comments"><%= l(:label_comment_plural) %></h3>
45 45 <% @comments.each do |comment| %>
46 46 <% next if comment.new_record? %>
47 47 <div class="contextual">
48 48 <%= link_to_if_authorized image_tag('delete.png'), {:controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment},
49 49 :confirm => l(:text_are_you_sure), :method => :delete, :title => l(:button_delete) %>
50 50 </div>
51 51 <h4><%= avatar(comment.author, :size => "24") %><%= authoring comment.created_on, comment.author %></h4>
52 52 <%= textilizable(comment.comments) %>
53 53 <% end if @comments.any? %>
54 54 </div>
55 55
56 <% if authorize_for 'comments', 'create' %>
56 <% if @news.commentable? %>
57 57 <p><%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %></p>
58 58 <% form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %>
59 59 <div class="box">
60 60 <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %>
61 61 <%= wikitoolbar_for 'comment_comments' %>
62 62 </div>
63 63 <p><%= submit_tag l(:button_add) %></p>
64 64 <% end %>
65 65 <% end %>
66 66
67 67 <% html_title @news.title -%>
68 68
69 69 <% content_for :header_tags do %>
70 70 <%= stylesheet_link_tag 'scm' %>
71 71 <% end %>
@@ -1,55 +1,64
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class CommentsControllerTest < ActionController::TestCase
21 21 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :news, :comments
22 22
23 23 def setup
24 24 User.current = nil
25 25 end
26 26
27 27 def test_add_comment
28 28 @request.session[:user_id] = 2
29 29 post :create, :id => 1, :comment => { :comments => 'This is a test comment' }
30 30 assert_redirected_to '/news/1'
31 31
32 32 comment = News.find(1).comments.find(:first, :order => 'created_on DESC')
33 33 assert_not_nil comment
34 34 assert_equal 'This is a test comment', comment.comments
35 35 assert_equal User.find(2), comment.author
36 36 end
37 37
38 38 def test_empty_comment_should_not_be_added
39 39 @request.session[:user_id] = 2
40 40 assert_no_difference 'Comment.count' do
41 41 post :create, :id => 1, :comment => { :comments => '' }
42 42 assert_response :redirect
43 43 assert_redirected_to '/news/1'
44 44 end
45 45 end
46 46
47 def test_create_should_be_denied_if_news_is_not_commentable
48 News.any_instance.stubs(:commentable?).returns(false)
49 @request.session[:user_id] = 2
50 assert_no_difference 'Comment.count' do
51 post :create, :id => 1, :comment => { :comments => 'This is a test comment' }
52 assert_response 403
53 end
54 end
55
47 56 def test_destroy_comment
48 57 comments_count = News.find(1).comments.size
49 58 @request.session[:user_id] = 2
50 59 delete :destroy, :id => 1, :comment_id => 2
51 60 assert_redirected_to '/news/1'
52 61 assert_nil Comment.find_by_id(2)
53 62 assert_equal comments_count - 1, News.find(1).comments.size
54 63 end
55 64 end
General Comments 0
You need to be logged in to leave comments. Login now