##// END OF EJS Templates
Backported r11424 from trunk (#12243)....
Jean-Philippe Lang -
r11364:878e85848fb9
parent child
Show More
@@ -1,105 +1,109
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
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
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.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class BoardsController < ApplicationController
18 class BoardsController < ApplicationController
19 default_search_scope :messages
19 default_search_scope :messages
20 before_filter :find_project_by_project_id, :find_board_if_available, :authorize
20 before_filter :find_project_by_project_id, :find_board_if_available, :authorize
21 accept_rss_auth :index, :show
21 accept_rss_auth :index, :show
22
22
23 helper :sort
23 helper :sort
24 include SortHelper
24 include SortHelper
25 helper :watchers
25 helper :watchers
26
26
27 def index
27 def index
28 @boards = @project.boards.includes(:last_message => :author).all
28 @boards = @project.boards.includes(:last_message => :author).all
29 # show the board if there is only one
29 # show the board if there is only one
30 if @boards.size == 1
30 if @boards.size == 1
31 @board = @boards.first
31 @board = @boards.first
32 show
32 show
33 end
33 end
34 end
34 end
35
35
36 def show
36 def show
37 respond_to do |format|
37 respond_to do |format|
38 format.html {
38 format.html {
39 sort_init 'updated_on', 'desc'
39 sort_init 'updated_on', 'desc'
40 sort_update 'created_on' => "#{Message.table_name}.created_on",
40 sort_update 'created_on' => "#{Message.table_name}.created_on",
41 'replies' => "#{Message.table_name}.replies_count",
41 'replies' => "#{Message.table_name}.replies_count",
42 'updated_on' => "#{Message.table_name}.updated_on"
42 'updated_on' => "COALESCE(last_replies_messages.created_on, #{Message.table_name}.created_on)"
43
43
44 @topic_count = @board.topics.count
44 @topic_count = @board.topics.count
45 @topic_pages = Paginator.new self, @topic_count, per_page_option, params['page']
45 @topic_pages = Paginator.new self, @topic_count, per_page_option, params['page']
46 @topics = @board.topics.reorder("#{Message.table_name}.sticky DESC").order(sort_clause).all(
46 @topics = @board.topics.
47 :include => [:author, {:last_reply => :author}],
47 reorder("#{Message.table_name}.sticky DESC").
48 :limit => @topic_pages.items_per_page,
48 includes(:last_reply).
49 :offset => @topic_pages.current.offset)
49 limit(@topic_pages.items_per_page).
50 offset(@topic_pages.current.offset).
51 order(sort_clause).
52 preload(:author, {:last_reply => :author}).
53 all
50 @message = Message.new(:board => @board)
54 @message = Message.new(:board => @board)
51 render :action => 'show', :layout => !request.xhr?
55 render :action => 'show', :layout => !request.xhr?
52 }
56 }
53 format.atom {
57 format.atom {
54 @messages = @board.messages.find :all, :order => 'created_on DESC',
58 @messages = @board.messages.find :all, :order => 'created_on DESC',
55 :include => [:author, :board],
59 :include => [:author, :board],
56 :limit => Setting.feeds_limit.to_i
60 :limit => Setting.feeds_limit.to_i
57 render_feed(@messages, :title => "#{@project}: #{@board}")
61 render_feed(@messages, :title => "#{@project}: #{@board}")
58 }
62 }
59 end
63 end
60 end
64 end
61
65
62 def new
66 def new
63 @board = @project.boards.build
67 @board = @project.boards.build
64 @board.safe_attributes = params[:board]
68 @board.safe_attributes = params[:board]
65 end
69 end
66
70
67 def create
71 def create
68 @board = @project.boards.build
72 @board = @project.boards.build
69 @board.safe_attributes = params[:board]
73 @board.safe_attributes = params[:board]
70 if @board.save
74 if @board.save
71 flash[:notice] = l(:notice_successful_create)
75 flash[:notice] = l(:notice_successful_create)
72 redirect_to_settings_in_projects
76 redirect_to_settings_in_projects
73 else
77 else
74 render :action => 'new'
78 render :action => 'new'
75 end
79 end
76 end
80 end
77
81
78 def edit
82 def edit
79 end
83 end
80
84
81 def update
85 def update
82 @board.safe_attributes = params[:board]
86 @board.safe_attributes = params[:board]
83 if @board.save
87 if @board.save
84 redirect_to_settings_in_projects
88 redirect_to_settings_in_projects
85 else
89 else
86 render :action => 'edit'
90 render :action => 'edit'
87 end
91 end
88 end
92 end
89
93
90 def destroy
94 def destroy
91 @board.destroy
95 @board.destroy
92 redirect_to_settings_in_projects
96 redirect_to_settings_in_projects
93 end
97 end
94
98
95 private
99 private
96 def redirect_to_settings_in_projects
100 def redirect_to_settings_in_projects
97 redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'boards'
101 redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'boards'
98 end
102 end
99
103
100 def find_board_if_available
104 def find_board_if_available
101 @board = @project.boards.find(params[:id]) if params[:id]
105 @board = @project.boards.find(params[:id]) if params[:id]
102 rescue ActiveRecord::RecordNotFound
106 rescue ActiveRecord::RecordNotFound
103 render_404
107 render_404
104 end
108 end
105 end
109 end
@@ -1,201 +1,216
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
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
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.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class BoardsControllerTest < ActionController::TestCase
20 class BoardsControllerTest < ActionController::TestCase
21 fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
21 fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
22
22
23 def setup
23 def setup
24 User.current = nil
24 User.current = nil
25 end
25 end
26
26
27 def test_index
27 def test_index
28 get :index, :project_id => 1
28 get :index, :project_id => 1
29 assert_response :success
29 assert_response :success
30 assert_template 'index'
30 assert_template 'index'
31 assert_not_nil assigns(:boards)
31 assert_not_nil assigns(:boards)
32 assert_not_nil assigns(:project)
32 assert_not_nil assigns(:project)
33 end
33 end
34
34
35 def test_index_not_found
35 def test_index_not_found
36 get :index, :project_id => 97
36 get :index, :project_id => 97
37 assert_response 404
37 assert_response 404
38 end
38 end
39
39
40 def test_index_should_show_messages_if_only_one_board
40 def test_index_should_show_messages_if_only_one_board
41 Project.find(1).boards.slice(1..-1).each(&:destroy)
41 Project.find(1).boards.slice(1..-1).each(&:destroy)
42
42
43 get :index, :project_id => 1
43 get :index, :project_id => 1
44 assert_response :success
44 assert_response :success
45 assert_template 'show'
45 assert_template 'show'
46 assert_not_nil assigns(:topics)
46 assert_not_nil assigns(:topics)
47 end
47 end
48
48
49 def test_show
49 def test_show
50 get :show, :project_id => 1, :id => 1
50 get :show, :project_id => 1, :id => 1
51 assert_response :success
51 assert_response :success
52 assert_template 'show'
52 assert_template 'show'
53 assert_not_nil assigns(:board)
53 assert_not_nil assigns(:board)
54 assert_not_nil assigns(:project)
54 assert_not_nil assigns(:project)
55 assert_not_nil assigns(:topics)
55 assert_not_nil assigns(:topics)
56 end
56 end
57
57
58 def test_show_should_display_sticky_messages_first
58 def test_show_should_display_sticky_messages_first
59 Message.update_all(:sticky => 0)
59 Message.update_all(:sticky => 0)
60 Message.update_all({:sticky => 1}, {:id => 1})
60 Message.update_all({:sticky => 1}, {:id => 1})
61
61
62 get :show, :project_id => 1, :id => 1
62 get :show, :project_id => 1, :id => 1
63 assert_response :success
63 assert_response :success
64
64
65 topics = assigns(:topics)
65 topics = assigns(:topics)
66 assert_not_nil topics
66 assert_not_nil topics
67 assert topics.size > 1, "topics size was #{topics.size}"
67 assert topics.size > 1, "topics size was #{topics.size}"
68 assert topics.first.sticky?
68 assert topics.first.sticky?
69 assert topics.first.updated_on < topics.second.updated_on
69 assert topics.first.updated_on < topics.second.updated_on
70 end
70 end
71
71
72 def test_show_should_display_message_with_last_reply_first
73 Message.update_all(:sticky => 0)
74
75 # Reply to an old topic
76 old_topic = Message.where(:board_id => 1, :parent_id => nil).order('created_on ASC').first
77 reply = Message.new(:board_id => 1, :subject => 'New reply', :content => 'New reply', :author_id => 2)
78 old_topic.children << reply
79
80 get :show, :project_id => 1, :id => 1
81 assert_response :success
82 topics = assigns(:topics)
83 assert_not_nil topics
84 assert_equal old_topic, topics.first
85 end
86
72 def test_show_with_permission_should_display_the_new_message_form
87 def test_show_with_permission_should_display_the_new_message_form
73 @request.session[:user_id] = 2
88 @request.session[:user_id] = 2
74 get :show, :project_id => 1, :id => 1
89 get :show, :project_id => 1, :id => 1
75 assert_response :success
90 assert_response :success
76 assert_template 'show'
91 assert_template 'show'
77
92
78 assert_tag 'form', :attributes => {:id => 'message-form'}
93 assert_tag 'form', :attributes => {:id => 'message-form'}
79 assert_tag 'input', :attributes => {:name => 'message[subject]'}
94 assert_tag 'input', :attributes => {:name => 'message[subject]'}
80 end
95 end
81
96
82 def test_show_atom
97 def test_show_atom
83 get :show, :project_id => 1, :id => 1, :format => 'atom'
98 get :show, :project_id => 1, :id => 1, :format => 'atom'
84 assert_response :success
99 assert_response :success
85 assert_template 'common/feed'
100 assert_template 'common/feed'
86 assert_not_nil assigns(:board)
101 assert_not_nil assigns(:board)
87 assert_not_nil assigns(:project)
102 assert_not_nil assigns(:project)
88 assert_not_nil assigns(:messages)
103 assert_not_nil assigns(:messages)
89 end
104 end
90
105
91 def test_show_not_found
106 def test_show_not_found
92 get :index, :project_id => 1, :id => 97
107 get :index, :project_id => 1, :id => 97
93 assert_response 404
108 assert_response 404
94 end
109 end
95
110
96 def test_new
111 def test_new
97 @request.session[:user_id] = 2
112 @request.session[:user_id] = 2
98 get :new, :project_id => 1
113 get :new, :project_id => 1
99 assert_response :success
114 assert_response :success
100 assert_template 'new'
115 assert_template 'new'
101
116
102 assert_select 'select[name=?]', 'board[parent_id]' do
117 assert_select 'select[name=?]', 'board[parent_id]' do
103 assert_select 'option', (Project.find(1).boards.size + 1)
118 assert_select 'option', (Project.find(1).boards.size + 1)
104 assert_select 'option[value=]', :text => ''
119 assert_select 'option[value=]', :text => ''
105 assert_select 'option[value=1]', :text => 'Help'
120 assert_select 'option[value=1]', :text => 'Help'
106 end
121 end
107 end
122 end
108
123
109 def test_new_without_project_boards
124 def test_new_without_project_boards
110 Project.find(1).boards.delete_all
125 Project.find(1).boards.delete_all
111 @request.session[:user_id] = 2
126 @request.session[:user_id] = 2
112
127
113 get :new, :project_id => 1
128 get :new, :project_id => 1
114 assert_response :success
129 assert_response :success
115 assert_template 'new'
130 assert_template 'new'
116
131
117 assert_select 'select[name=?]', 'board[parent_id]', 0
132 assert_select 'select[name=?]', 'board[parent_id]', 0
118 end
133 end
119
134
120 def test_create
135 def test_create
121 @request.session[:user_id] = 2
136 @request.session[:user_id] = 2
122 assert_difference 'Board.count' do
137 assert_difference 'Board.count' do
123 post :create, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing board creation'}
138 post :create, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing board creation'}
124 end
139 end
125 assert_redirected_to '/projects/ecookbook/settings/boards'
140 assert_redirected_to '/projects/ecookbook/settings/boards'
126 board = Board.first(:order => 'id DESC')
141 board = Board.first(:order => 'id DESC')
127 assert_equal 'Testing', board.name
142 assert_equal 'Testing', board.name
128 assert_equal 'Testing board creation', board.description
143 assert_equal 'Testing board creation', board.description
129 end
144 end
130
145
131 def test_create_with_parent
146 def test_create_with_parent
132 @request.session[:user_id] = 2
147 @request.session[:user_id] = 2
133 assert_difference 'Board.count' do
148 assert_difference 'Board.count' do
134 post :create, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing', :parent_id => 2}
149 post :create, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing', :parent_id => 2}
135 end
150 end
136 assert_redirected_to '/projects/ecookbook/settings/boards'
151 assert_redirected_to '/projects/ecookbook/settings/boards'
137 board = Board.first(:order => 'id DESC')
152 board = Board.first(:order => 'id DESC')
138 assert_equal Board.find(2), board.parent
153 assert_equal Board.find(2), board.parent
139 end
154 end
140
155
141 def test_create_with_failure
156 def test_create_with_failure
142 @request.session[:user_id] = 2
157 @request.session[:user_id] = 2
143 assert_no_difference 'Board.count' do
158 assert_no_difference 'Board.count' do
144 post :create, :project_id => 1, :board => { :name => '', :description => 'Testing board creation'}
159 post :create, :project_id => 1, :board => { :name => '', :description => 'Testing board creation'}
145 end
160 end
146 assert_response :success
161 assert_response :success
147 assert_template 'new'
162 assert_template 'new'
148 end
163 end
149
164
150 def test_edit
165 def test_edit
151 @request.session[:user_id] = 2
166 @request.session[:user_id] = 2
152 get :edit, :project_id => 1, :id => 2
167 get :edit, :project_id => 1, :id => 2
153 assert_response :success
168 assert_response :success
154 assert_template 'edit'
169 assert_template 'edit'
155 end
170 end
156
171
157 def test_edit_with_parent
172 def test_edit_with_parent
158 board = Board.generate!(:project_id => 1, :parent_id => 2)
173 board = Board.generate!(:project_id => 1, :parent_id => 2)
159 @request.session[:user_id] = 2
174 @request.session[:user_id] = 2
160 get :edit, :project_id => 1, :id => board.id
175 get :edit, :project_id => 1, :id => board.id
161 assert_response :success
176 assert_response :success
162 assert_template 'edit'
177 assert_template 'edit'
163
178
164 assert_select 'select[name=?]', 'board[parent_id]' do
179 assert_select 'select[name=?]', 'board[parent_id]' do
165 assert_select 'option[value=2][selected=selected]'
180 assert_select 'option[value=2][selected=selected]'
166 end
181 end
167 end
182 end
168
183
169 def test_update
184 def test_update
170 @request.session[:user_id] = 2
185 @request.session[:user_id] = 2
171 assert_no_difference 'Board.count' do
186 assert_no_difference 'Board.count' do
172 put :update, :project_id => 1, :id => 2, :board => { :name => 'Testing', :description => 'Testing board update'}
187 put :update, :project_id => 1, :id => 2, :board => { :name => 'Testing', :description => 'Testing board update'}
173 end
188 end
174 assert_redirected_to '/projects/ecookbook/settings/boards'
189 assert_redirected_to '/projects/ecookbook/settings/boards'
175 assert_equal 'Testing', Board.find(2).name
190 assert_equal 'Testing', Board.find(2).name
176 end
191 end
177
192
178 def test_update_position
193 def test_update_position
179 @request.session[:user_id] = 2
194 @request.session[:user_id] = 2
180 put :update, :project_id => 1, :id => 2, :board => { :move_to => 'highest'}
195 put :update, :project_id => 1, :id => 2, :board => { :move_to => 'highest'}
181 assert_redirected_to '/projects/ecookbook/settings/boards'
196 assert_redirected_to '/projects/ecookbook/settings/boards'
182 board = Board.find(2)
197 board = Board.find(2)
183 assert_equal 1, board.position
198 assert_equal 1, board.position
184 end
199 end
185
200
186 def test_update_with_failure
201 def test_update_with_failure
187 @request.session[:user_id] = 2
202 @request.session[:user_id] = 2
188 put :update, :project_id => 1, :id => 2, :board => { :name => '', :description => 'Testing board update'}
203 put :update, :project_id => 1, :id => 2, :board => { :name => '', :description => 'Testing board update'}
189 assert_response :success
204 assert_response :success
190 assert_template 'edit'
205 assert_template 'edit'
191 end
206 end
192
207
193 def test_destroy
208 def test_destroy
194 @request.session[:user_id] = 2
209 @request.session[:user_id] = 2
195 assert_difference 'Board.count', -1 do
210 assert_difference 'Board.count', -1 do
196 delete :destroy, :project_id => 1, :id => 2
211 delete :destroy, :project_id => 1, :id => 2
197 end
212 end
198 assert_redirected_to '/projects/ecookbook/settings/boards'
213 assert_redirected_to '/projects/ecookbook/settings/boards'
199 assert_nil Board.find_by_id(2)
214 assert_nil Board.find_by_id(2)
200 end
215 end
201 end
216 end
General Comments 0
You need to be logged in to leave comments. Login now