@@ -0,0 +1,6 | |||||
|
1 | <h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> » <%=h @message.subject %></h2> | |||
|
2 | ||||
|
3 | <% form_for :message, @message, :url => {:action => 'edit'}, :html => {:multipart => true} do |f| %> | |||
|
4 | <%= render :partial => 'form', :locals => {:f => f} %> | |||
|
5 | <%= submit_tag l(:button_save) %> | |||
|
6 | <% end %> |
@@ -0,0 +1,9 | |||||
|
1 | class AddMessagesLocked < ActiveRecord::Migration | |||
|
2 | def self.up | |||
|
3 | add_column :messages, :locked, :boolean, :default => false | |||
|
4 | end | |||
|
5 | ||||
|
6 | def self.down | |||
|
7 | remove_column :messages, :locked | |||
|
8 | end | |||
|
9 | end |
@@ -0,0 +1,9 | |||||
|
1 | class AddMessagesSticky < ActiveRecord::Migration | |||
|
2 | def self.up | |||
|
3 | add_column :messages, :sticky, :integer, :default => 0 | |||
|
4 | end | |||
|
5 | ||||
|
6 | def self.down | |||
|
7 | remove_column :messages, :sticky | |||
|
8 | end | |||
|
9 | end |
1 | NO CONTENT: new file 100644, binary diff hidden |
|
NO CONTENT: new file 100644, binary diff hidden |
@@ -0,0 +1,50 | |||||
|
1 | # redMine - project management software | |||
|
2 | # Copyright (C) 2006-2007 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 | ||||
|
18 | require File.dirname(__FILE__) + '/../test_helper' | |||
|
19 | require 'boards_controller' | |||
|
20 | ||||
|
21 | # Re-raise errors caught by the controller. | |||
|
22 | class BoardsController; def rescue_action(e) raise e end; end | |||
|
23 | ||||
|
24 | class BoardsControllerTest < Test::Unit::TestCase | |||
|
25 | fixtures :projects, :users, :members, :roles, :boards, :messages, :enabled_modules | |||
|
26 | ||||
|
27 | def setup | |||
|
28 | @controller = BoardsController.new | |||
|
29 | @request = ActionController::TestRequest.new | |||
|
30 | @response = ActionController::TestResponse.new | |||
|
31 | User.current = nil | |||
|
32 | end | |||
|
33 | ||||
|
34 | def test_index | |||
|
35 | get :index, :project_id => 1 | |||
|
36 | assert_response :success | |||
|
37 | assert_template 'index' | |||
|
38 | assert_not_nil assigns(:boards) | |||
|
39 | assert_not_nil assigns(:project) | |||
|
40 | end | |||
|
41 | ||||
|
42 | def test_show | |||
|
43 | get :show, :project_id => 1, :id => 1 | |||
|
44 | assert_response :success | |||
|
45 | assert_template 'show' | |||
|
46 | assert_not_nil assigns(:board) | |||
|
47 | assert_not_nil assigns(:project) | |||
|
48 | assert_not_nil assigns(:topics) | |||
|
49 | end | |||
|
50 | end |
@@ -0,0 +1,49 | |||||
|
1 | # redMine - project management software | |||
|
2 | # Copyright (C) 2006-2007 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 | ||||
|
18 | require File.dirname(__FILE__) + '/../test_helper' | |||
|
19 | require 'messages_controller' | |||
|
20 | ||||
|
21 | # Re-raise errors caught by the controller. | |||
|
22 | class MessagesController; def rescue_action(e) raise e end; end | |||
|
23 | ||||
|
24 | class MessagesControllerTest < Test::Unit::TestCase | |||
|
25 | fixtures :projects, :users, :members, :roles, :boards, :messages, :enabled_modules | |||
|
26 | ||||
|
27 | def setup | |||
|
28 | @controller = MessagesController.new | |||
|
29 | @request = ActionController::TestRequest.new | |||
|
30 | @response = ActionController::TestResponse.new | |||
|
31 | User.current = nil | |||
|
32 | end | |||
|
33 | ||||
|
34 | def test_show | |||
|
35 | get :show, :board_id => 1, :id => 1 | |||
|
36 | assert_response :success | |||
|
37 | assert_template 'show' | |||
|
38 | assert_not_nil assigns(:board) | |||
|
39 | assert_not_nil assigns(:project) | |||
|
40 | assert_not_nil assigns(:topic) | |||
|
41 | end | |||
|
42 | ||||
|
43 | def test_reply | |||
|
44 | @request.session[:user_id] = 2 | |||
|
45 | post :reply, :board_id => 1, :id => 1, :reply => { :content => 'This is a test reply', :subject => 'Test reply' } | |||
|
46 | assert_redirected_to 'messages/show' | |||
|
47 | assert Message.find_by_subject('Test reply') | |||
|
48 | end | |||
|
49 | end |
@@ -41,7 +41,7 class BoardsController < ApplicationController | |||||
41 |
|
41 | |||
42 | @topic_count = @board.topics.count |
|
42 | @topic_count = @board.topics.count | |
43 | @topic_pages = Paginator.new self, @topic_count, 25, params['page'] |
|
43 | @topic_pages = Paginator.new self, @topic_count, 25, params['page'] | |
44 | @topics = @board.topics.find :all, :order => sort_clause, |
|
44 | @topics = @board.topics.find :all, :order => "#{Message.table_name}.sticky DESC, #{sort_clause}", | |
45 | :include => [:author, {:last_reply => :author}], |
|
45 | :include => [:author, {:last_reply => :author}], | |
46 | :limit => @topic_pages.items_per_page, |
|
46 | :limit => @topic_pages.items_per_page, | |
47 | :offset => @topic_pages.current.offset |
|
47 | :offset => @topic_pages.current.offset |
@@ -17,22 +17,30 | |||||
17 |
|
17 | |||
18 | class MessagesController < ApplicationController |
|
18 | class MessagesController < ApplicationController | |
19 | layout 'base' |
|
19 | layout 'base' | |
20 |
before_filter :find_ |
|
20 | before_filter :find_board, :only => :new | |
|
21 | before_filter :find_message, :except => :new | |||
|
22 | before_filter :authorize | |||
21 |
|
23 | |||
22 | verify :method => :post, :only => [ :reply, :destroy ], :redirect_to => { :action => :show } |
|
24 | verify :method => :post, :only => [ :reply, :destroy ], :redirect_to => { :action => :show } | |
23 |
|
25 | |||
24 | helper :attachments |
|
26 | helper :attachments | |
25 | include AttachmentsHelper |
|
27 | include AttachmentsHelper | |
26 |
|
28 | |||
|
29 | # Show a topic and its replies | |||
27 | def show |
|
30 | def show | |
28 | @reply = Message.new(:subject => "RE: #{@message.subject}") |
|
31 | @reply = Message.new(:subject => "RE: #{@message.subject}") | |
29 | render :action => "show", :layout => false if request.xhr? |
|
32 | render :action => "show", :layout => false if request.xhr? | |
30 | end |
|
33 | end | |
31 |
|
34 | |||
|
35 | # Create a new topic | |||
32 | def new |
|
36 | def new | |
33 | @message = Message.new(params[:message]) |
|
37 | @message = Message.new(params[:message]) | |
34 | @message.author = User.current |
|
38 | @message.author = User.current | |
35 |
@message.board = @board |
|
39 | @message.board = @board | |
|
40 | if params[:message] && User.current.allowed_to?(:edit_messages, @project) | |||
|
41 | @message.locked = params[:message]['locked'] | |||
|
42 | @message.sticky = params[:message]['sticky'] | |||
|
43 | end | |||
36 | if request.post? && @message.save |
|
44 | if request.post? && @message.save | |
37 | params[:attachments].each { |file| |
|
45 | params[:attachments].each { |file| | |
38 | Attachment.create(:container => @message, :file => file, :author => User.current) if file.size > 0 |
|
46 | Attachment.create(:container => @message, :file => file, :author => User.current) if file.size > 0 | |
@@ -41,24 +49,55 class MessagesController < ApplicationController | |||||
41 | end |
|
49 | end | |
42 | end |
|
50 | end | |
43 |
|
51 | |||
|
52 | # Reply to a topic | |||
44 | def reply |
|
53 | def reply | |
45 | @reply = Message.new(params[:reply]) |
|
54 | @reply = Message.new(params[:reply]) | |
46 | @reply.author = User.current |
|
55 | @reply.author = User.current | |
47 | @reply.board = @board |
|
56 | @reply.board = @board | |
48 |
@ |
|
57 | @topic.children << @reply | |
49 | if !@reply.new_record? |
|
58 | if !@reply.new_record? | |
50 | params[:attachments].each { |file| |
|
59 | params[:attachments].each { |file| | |
51 | Attachment.create(:container => @reply, :file => file, :author => User.current) if file.size > 0 |
|
60 | Attachment.create(:container => @reply, :file => file, :author => User.current) if file.size > 0 | |
52 | } if params[:attachments] and params[:attachments].is_a? Array |
|
61 | } if params[:attachments] and params[:attachments].is_a? Array | |
53 | end |
|
62 | end | |
54 |
redirect_to :action => 'show', :id => @ |
|
63 | redirect_to :action => 'show', :id => @topic | |
|
64 | end | |||
|
65 | ||||
|
66 | # Edit a message | |||
|
67 | def edit | |||
|
68 | if params[:message] && User.current.allowed_to?(:edit_messages, @project) | |||
|
69 | @message.locked = params[:message]['locked'] | |||
|
70 | @message.sticky = params[:message]['sticky'] | |||
|
71 | end | |||
|
72 | if request.post? && @message.update_attributes(params[:message]) | |||
|
73 | params[:attachments].each { |file| | |||
|
74 | Attachment.create(:container => @message, :file => file, :author => User.current) if file.size > 0 | |||
|
75 | } if params[:attachments] and params[:attachments].is_a? Array | |||
|
76 | flash[:notice] = l(:notice_successful_update) | |||
|
77 | redirect_to :action => 'show', :id => @topic | |||
|
78 | end | |||
|
79 | end | |||
|
80 | ||||
|
81 | # Delete a messages | |||
|
82 | def destroy | |||
|
83 | @message.destroy | |||
|
84 | redirect_to @message.parent.nil? ? | |||
|
85 | { :controller => 'boards', :action => 'show', :project_id => @project, :id => @board } : | |||
|
86 | { :action => 'show', :id => @message.parent } | |||
55 | end |
|
87 | end | |
56 |
|
88 | |||
57 | private |
|
89 | private | |
58 |
def find_ |
|
90 | def find_message | |
|
91 | find_board | |||
|
92 | @message = @board.messages.find(params[:id], :include => :parent) | |||
|
93 | @topic = @message.root | |||
|
94 | rescue ActiveRecord::RecordNotFound | |||
|
95 | render_404 | |||
|
96 | end | |||
|
97 | ||||
|
98 | def find_board | |||
59 | @board = Board.find(params[:board_id], :include => :project) |
|
99 | @board = Board.find(params[:board_id], :include => :project) | |
60 | @project = @board.project |
|
100 | @project = @board.project | |
61 | @message = @board.topics.find(params[:id]) if params[:id] |
|
|||
62 | rescue ActiveRecord::RecordNotFound |
|
101 | rescue ActiveRecord::RecordNotFound | |
63 | render_404 |
|
102 | render_404 | |
64 | end |
|
103 | end |
@@ -34,7 +34,7 module ApplicationHelper | |||||
34 |
|
34 | |||
35 | # Display a link to user's account page |
|
35 | # Display a link to user's account page | |
36 | def link_to_user(user) |
|
36 | def link_to_user(user) | |
37 |
link_to |
|
37 | user ? link_to(user, :controller => 'account', :action => 'show', :id => user) : 'Anonymous' | |
38 | end |
|
38 | end | |
39 |
|
39 | |||
40 | def link_to_issue(issue) |
|
40 | def link_to_issue(issue) | |
@@ -92,7 +92,7 module ApplicationHelper | |||||
92 |
|
92 | |||
93 | def authoring(created, author) |
|
93 | def authoring(created, author) | |
94 | time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created)) |
|
94 | time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created)) | |
95 |
l(:label_added_time_by, author |
|
95 | l(:label_added_time_by, author || 'Anonymous', time_tag) | |
96 | end |
|
96 | end | |
97 |
|
97 | |||
98 | def day_name(day) |
|
98 | def day_name(day) |
@@ -30,9 +30,15 class Message < ActiveRecord::Base | |||||
30 | :description => :content, |
|
30 | :description => :content, | |
31 | :url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id, :id => o.id}} |
|
31 | :url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id, :id => o.id}} | |
32 |
|
32 | |||
|
33 | attr_protected :locked, :sticky | |||
33 | validates_presence_of :subject, :content |
|
34 | validates_presence_of :subject, :content | |
34 | validates_length_of :subject, :maximum => 255 |
|
35 | validates_length_of :subject, :maximum => 255 | |
35 |
|
36 | |||
|
37 | def validate_on_create | |||
|
38 | # Can not reply to a locked topic | |||
|
39 | errors.add_to_base 'Topic is locked' if root.locked? | |||
|
40 | end | |||
|
41 | ||||
36 | def after_create |
|
42 | def after_create | |
37 | board.update_attribute(:last_message_id, self.id) |
|
43 | board.update_attribute(:last_message_id, self.id) | |
38 | board.increment! :messages_count |
|
44 | board.increment! :messages_count | |
@@ -43,6 +49,18 class Message < ActiveRecord::Base | |||||
43 | end |
|
49 | end | |
44 | end |
|
50 | end | |
45 |
|
51 | |||
|
52 | def after_destroy | |||
|
53 | # The following line is required so that the previous counter | |||
|
54 | # updates (due to children removal) are not overwritten | |||
|
55 | board.reload | |||
|
56 | board.decrement! :messages_count | |||
|
57 | board.decrement! :topics_count unless parent | |||
|
58 | end | |||
|
59 | ||||
|
60 | def sticky? | |||
|
61 | sticky == 1 | |||
|
62 | end | |||
|
63 | ||||
46 | def project |
|
64 | def project | |
47 | board.project |
|
65 | board.project | |
48 | end |
|
66 | end |
@@ -19,7 +19,7 | |||||
19 | <td> |
|
19 | <td> | |
20 | <small> |
|
20 | <small> | |
21 | <% if board.last_message %> |
|
21 | <% if board.last_message %> | |
22 |
<%= board.last_message.author |
|
22 | <%= authoring board.last_message.created_on, board.last_message.author %><br /> | |
23 | <%= link_to_message board.last_message %> |
|
23 | <%= link_to_message board.last_message %> | |
24 | <% end %> |
|
24 | <% end %> | |
25 | </small> |
|
25 | </small> |
@@ -18,7 +18,7 | |||||
18 | <h2><%=h @board.name %></h2> |
|
18 | <h2><%=h @board.name %></h2> | |
19 |
|
19 | |||
20 | <% if @topics.any? %> |
|
20 | <% if @topics.any? %> | |
21 | <table class="list"> |
|
21 | <table class="list messages"> | |
22 | <thead><tr> |
|
22 | <thead><tr> | |
23 | <th><%= l(:field_subject) %></th> |
|
23 | <th><%= l(:field_subject) %></th> | |
24 | <th><%= l(:field_author) %></th> |
|
24 | <th><%= l(:field_author) %></th> | |
@@ -28,18 +28,16 | |||||
28 | </tr></thead> |
|
28 | </tr></thead> | |
29 | <tbody> |
|
29 | <tbody> | |
30 | <% @topics.each do |topic| %> |
|
30 | <% @topics.each do |topic| %> | |
31 | <tr class="<%= cycle 'odd', 'even' %>"> |
|
31 | <tr class="message <%= cycle 'odd', 'even' %> <%= topic.sticky? ? 'sticky' : '' %> <%= topic.locked? ? 'locked' : '' %>"> | |
32 | <td><%= link_to h(topic.subject), :controller => 'messages', :action => 'show', :board_id => @board, :id => topic %></td> |
|
32 | <td class="subject"><%= link_to h(topic.subject), { :controller => 'messages', :action => 'show', :board_id => @board, :id => topic }, :class => 'icon' %></td> | |
33 |
<td align="center"><%= |
|
33 | <td class="author" align="center"><%= topic.author %></td> | |
34 | <td align="center"><%= format_time(topic.created_on) %></td> |
|
34 | <td class="created_on" align="center"><%= format_time(topic.created_on) %></td> | |
35 | <td align="center"><%= topic.replies_count %></td> |
|
35 | <td class="replies" align="center"><%= topic.replies_count %></td> | |
36 | <td> |
|
36 | <td class="last_message"> | |
37 | <small> |
|
|||
38 | <% if topic.last_reply %> |
|
37 | <% if topic.last_reply %> | |
39 |
<%= topic.last_reply.author |
|
38 | <%= authoring topic.last_reply.created_on, topic.last_reply.author %><br /> | |
40 | <%= link_to_message topic.last_reply %> |
|
39 | <%= link_to_message topic.last_reply %> | |
41 | <% end %> |
|
40 | <% end %> | |
42 | </small> |
|
|||
43 | </td> |
|
41 | </td> | |
44 | </tr> |
|
42 | </tr> | |
45 | <% end %> |
|
43 | <% end %> |
@@ -3,7 +3,13 | |||||
3 | <div class="box"> |
|
3 | <div class="box"> | |
4 | <!--[form:message]--> |
|
4 | <!--[form:message]--> | |
5 | <p><label><%= l(:field_subject) %></label><br /> |
|
5 | <p><label><%= l(:field_subject) %></label><br /> | |
6 |
<%= f.text_field :subject, :required => true, :size => 120 %> |
|
6 | <%= f.text_field :subject, :required => true, :size => 120 %> | |
|
7 | ||||
|
8 | <% if User.current.allowed_to?(:edit_messages, @project) %> | |||
|
9 | <label><%= f.check_box :sticky %> Sticky</label> | |||
|
10 | <label><%= f.check_box :locked %> Locked</label> | |||
|
11 | <% end %> | |||
|
12 | </p> | |||
7 |
|
13 | |||
8 | <p><%= f.text_area :content, :required => true, :cols => 80, :rows => 15, :class => 'wiki-edit', :id => 'message_content' %></p> |
|
14 | <p><%= f.text_area :content, :required => true, :cols => 80, :rows => 15, :class => 'wiki-edit', :id => 'message_content' %></p> | |
9 | <%= wikitoolbar_for 'message_content' %> |
|
15 | <%= wikitoolbar_for 'message_content' %> |
@@ -1,28 +1,37 | |||||
1 | <h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> » <%=h @message.subject %></h2> |
|
1 | <div class="contextual"> | |
|
2 | <%= link_to_if_authorized l(:button_edit), {:action => 'edit', :id => @topic}, :class => 'icon icon-edit' %> | |||
|
3 | <%= link_to_if_authorized l(:button_delete), {:action => 'destroy', :id => @topic}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del' %> | |||
|
4 | </div> | |||
|
5 | ||||
|
6 | <h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> » <%=h @topic.subject %></h2> | |||
2 |
|
7 | |||
3 | <div class="message"> |
|
8 | <div class="message"> | |
4 |
<p><span class="author"><%= authoring @ |
|
9 | <p><span class="author"><%= authoring @topic.created_on, @topic.author %></span></p> | |
5 | <div class="wiki"> |
|
10 | <div class="wiki"> | |
6 |
<%= textilizable(@ |
|
11 | <%= textilizable(@topic.content, :attachments => @topic.attachments) %> | |
7 | </div> |
|
12 | </div> | |
8 |
<%= link_to_attachments @ |
|
13 | <%= link_to_attachments @topic.attachments, :no_author => true %> | |
9 | </div> |
|
14 | </div> | |
10 | <br /> |
|
15 | <br /> | |
11 |
|
16 | |||
12 | <div class="message reply"> |
|
|||
13 | <h3 class="icon22 icon22-comment"><%= l(:label_reply_plural) %></h3> |
|
17 | <h3 class="icon22 icon22-comment"><%= l(:label_reply_plural) %></h3> | |
14 |
<% @ |
|
18 | <% @topic.children.each do |message| %> | |
15 | <a name="<%= "message-#{message.id}" %>"></a> |
|
19 | <a name="<%= "message-#{message.id}" %>"></a> | |
|
20 | <div class="contextual"> | |||
|
21 | <%= link_to_if_authorized l(:button_edit), {:action => 'edit', :id => message}, :class => 'icon icon-edit' %> | |||
|
22 | <%= link_to_if_authorized l(:button_delete), {:action => 'destroy', :id => message}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del' %> | |||
|
23 | </div> | |||
|
24 | <div class="message reply"> | |||
16 | <h4><%=h message.subject %> - <%= authoring message.created_on, message.author %></h4> |
|
25 | <h4><%=h message.subject %> - <%= authoring message.created_on, message.author %></h4> | |
17 | <div class="wiki"><%= textilizable message.content %></div> |
|
26 | <div class="wiki"><%= textilizable message.content %></div> | |
18 | <%= link_to_attachments message.attachments, :no_author => true %> |
|
27 | <%= link_to_attachments message.attachments, :no_author => true %> | |
|
28 | </div> | |||
19 | <% end %> |
|
29 | <% end %> | |
20 | </div> |
|
|||
21 |
|
30 | |||
22 | <% if authorize_for('messages', 'reply') %> |
|
31 | <% if !@topic.locked? && authorize_for('messages', 'reply') %> | |
23 | <p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %></p> |
|
32 | <p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %></p> | |
24 | <div id="reply" style="display:none;"> |
|
33 | <div id="reply" style="display:none;"> | |
25 |
<% form_for :reply, @reply, :url => {:action => 'reply', :id => @ |
|
34 | <% form_for :reply, @reply, :url => {:action => 'reply', :id => @topic}, :html => {:multipart => true} do |f| %> | |
26 | <%= render :partial => 'form', :locals => {:f => f} %> |
|
35 | <%= render :partial => 'form', :locals => {:f => f} %> | |
27 | <%= submit_tag l(:button_submit) %> |
|
36 | <%= submit_tag l(:button_submit) %> | |
28 | <% end %> |
|
37 | <% end %> |
@@ -84,6 +84,8 Redmine::AccessControl.map do |map| | |||||
84 | map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member |
|
84 | map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member | |
85 | map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true |
|
85 | map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true | |
86 | map.permission :add_messages, {:messages => [:new, :reply]} |
|
86 | map.permission :add_messages, {:messages => [:new, :reply]} | |
|
87 | map.permission :edit_messages, {:messages => :edit}, :require => :member | |||
|
88 | map.permission :delete_messages, {:messages => :destroy}, :require => :member | |||
87 | end |
|
89 | end | |
88 | end |
|
90 | end | |
89 |
|
91 |
@@ -77,6 +77,11 tr.issue td.subject, tr.issue td.category { white-space: normal; } | |||||
77 | tr.issue td.subject { text-align: left; } |
|
77 | tr.issue td.subject { text-align: left; } | |
78 | tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;} |
|
78 | tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;} | |
79 |
|
79 | |||
|
80 | tr.message { height: 2.6em; } | |||
|
81 | tr.message td.last_message { font-size: 80%; } | |||
|
82 | tr.message.locked td.subject a { background-image: url(../images/locked.png); } | |||
|
83 | tr.message.sticky td.subject a { background-image: url(../images/sticky.png); font-weight: bold; } | |||
|
84 | ||||
80 | table.list tbody tr:hover { background-color:#ffffdd; } |
|
85 | table.list tbody tr:hover { background-color:#ffffdd; } | |
81 | table td {padding:2px;} |
|
86 | table td {padding:2px;} | |
82 | table p {margin:0;} |
|
87 | table p {margin:0;} |
@@ -2,12 +2,12 | |||||
2 | boards_001: |
|
2 | boards_001: | |
3 | name: Help |
|
3 | name: Help | |
4 | project_id: 1 |
|
4 | project_id: 1 | |
5 |
topics_count: |
|
5 | topics_count: 2 | |
6 | id: 1 |
|
6 | id: 1 | |
7 | description: Help board |
|
7 | description: Help board | |
8 | position: 1 |
|
8 | position: 1 | |
9 |
last_message_id: |
|
9 | last_message_id: 5 | |
10 |
messages_count: |
|
10 | messages_count: 5 | |
11 | boards_002: |
|
11 | boards_002: | |
12 | name: Discussion |
|
12 | name: Discussion | |
13 | project_id: 1 |
|
13 | project_id: 1 |
@@ -4,8 +4,8 messages_001: | |||||
4 | updated_on: 2007-05-12 17:15:32 +02:00 |
|
4 | updated_on: 2007-05-12 17:15:32 +02:00 | |
5 | subject: First post |
|
5 | subject: First post | |
6 | id: 1 |
|
6 | id: 1 | |
7 |
replies_count: |
|
7 | replies_count: 2 | |
8 |
last_reply_id: |
|
8 | last_reply_id: 3 | |
9 | content: "This is the very first post\n\ |
|
9 | content: "This is the very first post\n\ | |
10 | in the forum" |
|
10 | in the forum" | |
11 | author_id: 1 |
|
11 | author_id: 1 | |
@@ -22,4 +22,36 messages_002: | |||||
22 | author_id: 1 |
|
22 | author_id: 1 | |
23 | parent_id: 1 |
|
23 | parent_id: 1 | |
24 | board_id: 1 |
|
24 | board_id: 1 | |
25 | No newline at end of file |
|
25 | messages_003: | |
|
26 | created_on: 2007-05-12 17:18:02 +02:00 | |||
|
27 | updated_on: 2007-05-12 17:18:02 +02:00 | |||
|
28 | subject: "RE: First post" | |||
|
29 | id: 3 | |||
|
30 | replies_count: 0 | |||
|
31 | last_reply_id: | |||
|
32 | content: "An other reply" | |||
|
33 | author_id: | |||
|
34 | parent_id: 1 | |||
|
35 | board_id: 1 | |||
|
36 | messages_004: | |||
|
37 | created_on: 2007-08-12 17:15:32 +02:00 | |||
|
38 | updated_on: 2007-08-12 17:15:32 +02:00 | |||
|
39 | subject: Post 2 | |||
|
40 | id: 4 | |||
|
41 | replies_count: 1 | |||
|
42 | last_reply_id: 5 | |||
|
43 | content: "This is an other post" | |||
|
44 | author_id: | |||
|
45 | parent_id: | |||
|
46 | board_id: 1 | |||
|
47 | messages_005: | |||
|
48 | created_on: 2007-09-12 17:18:00 +02:00 | |||
|
49 | updated_on: 2007-09-12 17:18:00 +02:00 | |||
|
50 | subject: 'RE: post 2' | |||
|
51 | id: 5 | |||
|
52 | replies_count: 0 | |||
|
53 | last_reply_id: | |||
|
54 | content: "Reply to the second post" | |||
|
55 | author_id: 1 | |||
|
56 | parent_id: 4 | |||
|
57 | board_id: 1 |
@@ -41,4 +41,30 class MessageTest < Test::Unit::TestCase | |||||
41 | assert_equal replies_count+1, @message[:replies_count] |
|
41 | assert_equal replies_count+1, @message[:replies_count] | |
42 | assert_equal reply, @message.last_reply |
|
42 | assert_equal reply, @message.last_reply | |
43 | end |
|
43 | end | |
|
44 | ||||
|
45 | def test_destroy_topic | |||
|
46 | message = Message.find(1) | |||
|
47 | board = message.board | |||
|
48 | topics_count, messages_count = board.topics_count, board.messages_count | |||
|
49 | assert message.destroy | |||
|
50 | board.reload | |||
|
51 | ||||
|
52 | # Replies deleted | |||
|
53 | assert Message.find_all_by_parent_id(1).empty? | |||
|
54 | # Checks counters | |||
|
55 | assert_equal topics_count - 1, board.topics_count | |||
|
56 | assert_equal messages_count - 3, board.messages_count | |||
|
57 | end | |||
|
58 | ||||
|
59 | def test_destroy_reply | |||
|
60 | message = Message.find(5) | |||
|
61 | board = message.board | |||
|
62 | topics_count, messages_count = board.topics_count, board.messages_count | |||
|
63 | assert message.destroy | |||
|
64 | board.reload | |||
|
65 | ||||
|
66 | # Checks counters | |||
|
67 | assert_equal topics_count, board.topics_count | |||
|
68 | assert_equal messages_count - 1, board.messages_count | |||
|
69 | end | |||
44 | end |
|
70 | end |
General Comments 0
You need to be logged in to leave comments.
Login now