##// END OF EJS Templates
Adds a few tests....
Jean-Philippe Lang -
r13313:5222650d9523
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,624 +1,632
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 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 ProjectsControllerTest < ActionController::TestCase
20 class ProjectsControllerTest < ActionController::TestCase
21 fixtures :projects, :versions, :users, :roles, :members,
21 fixtures :projects, :versions, :users, :roles, :members,
22 :member_roles, :issues, :journals, :journal_details,
22 :member_roles, :issues, :journals, :journal_details,
23 :trackers, :projects_trackers, :issue_statuses,
23 :trackers, :projects_trackers, :issue_statuses,
24 :enabled_modules, :enumerations, :boards, :messages,
24 :enabled_modules, :enumerations, :boards, :messages,
25 :attachments, :custom_fields, :custom_values, :time_entries,
25 :attachments, :custom_fields, :custom_values, :time_entries,
26 :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
26 :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
27
27
28 def setup
28 def setup
29 @request.session[:user_id] = nil
29 @request.session[:user_id] = nil
30 Setting.default_language = 'en'
30 Setting.default_language = 'en'
31 end
31 end
32
32
33 def test_index_by_anonymous_should_not_show_private_projects
33 def test_index_by_anonymous_should_not_show_private_projects
34 get :index
34 get :index
35 assert_response :success
35 assert_response :success
36 assert_template 'index'
36 assert_template 'index'
37 projects = assigns(:projects)
37 projects = assigns(:projects)
38 assert_not_nil projects
38 assert_not_nil projects
39 assert projects.all?(&:is_public?)
39 assert projects.all?(&:is_public?)
40
40
41 assert_select 'ul' do
41 assert_select 'ul' do
42 assert_select 'li' do
42 assert_select 'li' do
43 assert_select 'a', :text => 'eCookbook'
43 assert_select 'a', :text => 'eCookbook'
44 assert_select 'ul' do
44 assert_select 'ul' do
45 assert_select 'a', :text => 'Child of private child'
45 assert_select 'a', :text => 'Child of private child'
46 end
46 end
47 end
47 end
48 end
48 end
49 assert_select 'a', :text => /Private child of eCookbook/, :count => 0
49 assert_select 'a', :text => /Private child of eCookbook/, :count => 0
50 end
50 end
51
51
52 def test_index_atom
52 def test_index_atom
53 get :index, :format => 'atom'
53 get :index, :format => 'atom'
54 assert_response :success
54 assert_response :success
55 assert_template 'common/feed'
55 assert_template 'common/feed'
56 assert_select 'feed>title', :text => 'Redmine: Latest projects'
56 assert_select 'feed>title', :text => 'Redmine: Latest projects'
57 assert_select 'feed>entry', :count => Project.visible(User.current).count
57 assert_select 'feed>entry', :count => Project.visible(User.current).count
58 end
58 end
59
59
60 test "#index by non-admin user with view_time_entries permission should show overall spent time link" do
60 test "#index by non-admin user with view_time_entries permission should show overall spent time link" do
61 @request.session[:user_id] = 3
61 @request.session[:user_id] = 3
62 get :index
62 get :index
63 assert_template 'index'
63 assert_template 'index'
64 assert_select 'a[href=?]', '/time_entries'
64 assert_select 'a[href=?]', '/time_entries'
65 end
65 end
66
66
67 test "#index by non-admin user without view_time_entries permission should not show overall spent time link" do
67 test "#index by non-admin user without view_time_entries permission should not show overall spent time link" do
68 Role.find(2).remove_permission! :view_time_entries
68 Role.find(2).remove_permission! :view_time_entries
69 Role.non_member.remove_permission! :view_time_entries
69 Role.non_member.remove_permission! :view_time_entries
70 Role.anonymous.remove_permission! :view_time_entries
70 Role.anonymous.remove_permission! :view_time_entries
71 @request.session[:user_id] = 3
71 @request.session[:user_id] = 3
72
72
73 get :index
73 get :index
74 assert_template 'index'
74 assert_template 'index'
75 assert_select 'a[href=?]', '/time_entries', 0
75 assert_select 'a[href=?]', '/time_entries', 0
76 end
76 end
77
77
78 test "#index by non-admin user with permission should show add project link" do
79 Role.find(1).add_permission! :add_project
80 @request.session[:user_id] = 2
81 get :index
82 assert_template 'index'
83 assert_select 'a[href=?]', '/projects/new'
84 end
85
78 test "#new by admin user should accept get" do
86 test "#new by admin user should accept get" do
79 @request.session[:user_id] = 1
87 @request.session[:user_id] = 1
80
88
81 get :new
89 get :new
82 assert_response :success
90 assert_response :success
83 assert_template 'new'
91 assert_template 'new'
84 end
92 end
85
93
86 test "#new by non-admin user with add_project permission should accept get" do
94 test "#new by non-admin user with add_project permission should accept get" do
87 Role.non_member.add_permission! :add_project
95 Role.non_member.add_permission! :add_project
88 @request.session[:user_id] = 9
96 @request.session[:user_id] = 9
89
97
90 get :new
98 get :new
91 assert_response :success
99 assert_response :success
92 assert_template 'new'
100 assert_template 'new'
93 assert_select 'select[name=?]', 'project[parent_id]', 0
101 assert_select 'select[name=?]', 'project[parent_id]', 0
94 end
102 end
95
103
96 test "#new by non-admin user with add_subprojects permission should accept get" do
104 test "#new by non-admin user with add_subprojects permission should accept get" do
97 Role.find(1).remove_permission! :add_project
105 Role.find(1).remove_permission! :add_project
98 Role.find(1).add_permission! :add_subprojects
106 Role.find(1).add_permission! :add_subprojects
99 @request.session[:user_id] = 2
107 @request.session[:user_id] = 2
100
108
101 get :new, :parent_id => 'ecookbook'
109 get :new, :parent_id => 'ecookbook'
102 assert_response :success
110 assert_response :success
103 assert_template 'new'
111 assert_template 'new'
104
112
105 assert_select 'select[name=?]', 'project[parent_id]' do
113 assert_select 'select[name=?]', 'project[parent_id]' do
106 # parent project selected
114 # parent project selected
107 assert_select 'option[value="1"][selected=selected]'
115 assert_select 'option[value="1"][selected=selected]'
108 # no empty value
116 # no empty value
109 assert_select 'option[value=""]', 0
117 assert_select 'option[value=""]', 0
110 end
118 end
111 end
119 end
112
120
113 test "#create by admin user should create a new project" do
121 test "#create by admin user should create a new project" do
114 @request.session[:user_id] = 1
122 @request.session[:user_id] = 1
115
123
116 post :create,
124 post :create,
117 :project => {
125 :project => {
118 :name => "blog",
126 :name => "blog",
119 :description => "weblog",
127 :description => "weblog",
120 :homepage => 'http://weblog',
128 :homepage => 'http://weblog',
121 :identifier => "blog",
129 :identifier => "blog",
122 :is_public => 1,
130 :is_public => 1,
123 :custom_field_values => { '3' => 'Beta' },
131 :custom_field_values => { '3' => 'Beta' },
124 :tracker_ids => ['1', '3'],
132 :tracker_ids => ['1', '3'],
125 # an issue custom field that is not for all project
133 # an issue custom field that is not for all project
126 :issue_custom_field_ids => ['9'],
134 :issue_custom_field_ids => ['9'],
127 :enabled_module_names => ['issue_tracking', 'news', 'repository']
135 :enabled_module_names => ['issue_tracking', 'news', 'repository']
128 }
136 }
129 assert_redirected_to '/projects/blog/settings'
137 assert_redirected_to '/projects/blog/settings'
130
138
131 project = Project.find_by_name('blog')
139 project = Project.find_by_name('blog')
132 assert_kind_of Project, project
140 assert_kind_of Project, project
133 assert project.active?
141 assert project.active?
134 assert_equal 'weblog', project.description
142 assert_equal 'weblog', project.description
135 assert_equal 'http://weblog', project.homepage
143 assert_equal 'http://weblog', project.homepage
136 assert_equal true, project.is_public?
144 assert_equal true, project.is_public?
137 assert_nil project.parent
145 assert_nil project.parent
138 assert_equal 'Beta', project.custom_value_for(3).value
146 assert_equal 'Beta', project.custom_value_for(3).value
139 assert_equal [1, 3], project.trackers.map(&:id).sort
147 assert_equal [1, 3], project.trackers.map(&:id).sort
140 assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
148 assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
141 assert project.issue_custom_fields.include?(IssueCustomField.find(9))
149 assert project.issue_custom_fields.include?(IssueCustomField.find(9))
142 end
150 end
143
151
144 test "#create by admin user should create a new subproject" do
152 test "#create by admin user should create a new subproject" do
145 @request.session[:user_id] = 1
153 @request.session[:user_id] = 1
146
154
147 assert_difference 'Project.count' do
155 assert_difference 'Project.count' do
148 post :create, :project => { :name => "blog",
156 post :create, :project => { :name => "blog",
149 :description => "weblog",
157 :description => "weblog",
150 :identifier => "blog",
158 :identifier => "blog",
151 :is_public => 1,
159 :is_public => 1,
152 :custom_field_values => { '3' => 'Beta' },
160 :custom_field_values => { '3' => 'Beta' },
153 :parent_id => 1
161 :parent_id => 1
154 }
162 }
155 assert_redirected_to '/projects/blog/settings'
163 assert_redirected_to '/projects/blog/settings'
156 end
164 end
157
165
158 project = Project.find_by_name('blog')
166 project = Project.find_by_name('blog')
159 assert_kind_of Project, project
167 assert_kind_of Project, project
160 assert_equal Project.find(1), project.parent
168 assert_equal Project.find(1), project.parent
161 end
169 end
162
170
163 test "#create by admin user should continue" do
171 test "#create by admin user should continue" do
164 @request.session[:user_id] = 1
172 @request.session[:user_id] = 1
165
173
166 assert_difference 'Project.count' do
174 assert_difference 'Project.count' do
167 post :create, :project => {:name => "blog", :identifier => "blog"}, :continue => 'Create and continue'
175 post :create, :project => {:name => "blog", :identifier => "blog"}, :continue => 'Create and continue'
168 end
176 end
169 assert_redirected_to '/projects/new'
177 assert_redirected_to '/projects/new'
170 end
178 end
171
179
172 test "#create by non-admin user with add_project permission should create a new project" do
180 test "#create by non-admin user with add_project permission should create a new project" do
173 Role.non_member.add_permission! :add_project
181 Role.non_member.add_permission! :add_project
174 @request.session[:user_id] = 9
182 @request.session[:user_id] = 9
175
183
176 post :create, :project => { :name => "blog",
184 post :create, :project => { :name => "blog",
177 :description => "weblog",
185 :description => "weblog",
178 :identifier => "blog",
186 :identifier => "blog",
179 :is_public => 1,
187 :is_public => 1,
180 :custom_field_values => { '3' => 'Beta' },
188 :custom_field_values => { '3' => 'Beta' },
181 :tracker_ids => ['1', '3'],
189 :tracker_ids => ['1', '3'],
182 :enabled_module_names => ['issue_tracking', 'news', 'repository']
190 :enabled_module_names => ['issue_tracking', 'news', 'repository']
183 }
191 }
184
192
185 assert_redirected_to '/projects/blog/settings'
193 assert_redirected_to '/projects/blog/settings'
186
194
187 project = Project.find_by_name('blog')
195 project = Project.find_by_name('blog')
188 assert_kind_of Project, project
196 assert_kind_of Project, project
189 assert_equal 'weblog', project.description
197 assert_equal 'weblog', project.description
190 assert_equal true, project.is_public?
198 assert_equal true, project.is_public?
191 assert_equal [1, 3], project.trackers.map(&:id).sort
199 assert_equal [1, 3], project.trackers.map(&:id).sort
192 assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
200 assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
193
201
194 # User should be added as a project member
202 # User should be added as a project member
195 assert User.find(9).member_of?(project)
203 assert User.find(9).member_of?(project)
196 assert_equal 1, project.members.size
204 assert_equal 1, project.members.size
197 end
205 end
198
206
199 test "#create by non-admin user with add_project permission should fail with parent_id" do
207 test "#create by non-admin user with add_project permission should fail with parent_id" do
200 Role.non_member.add_permission! :add_project
208 Role.non_member.add_permission! :add_project
201 @request.session[:user_id] = 9
209 @request.session[:user_id] = 9
202
210
203 assert_no_difference 'Project.count' do
211 assert_no_difference 'Project.count' do
204 post :create, :project => { :name => "blog",
212 post :create, :project => { :name => "blog",
205 :description => "weblog",
213 :description => "weblog",
206 :identifier => "blog",
214 :identifier => "blog",
207 :is_public => 1,
215 :is_public => 1,
208 :custom_field_values => { '3' => 'Beta' },
216 :custom_field_values => { '3' => 'Beta' },
209 :parent_id => 1
217 :parent_id => 1
210 }
218 }
211 end
219 end
212 assert_response :success
220 assert_response :success
213 project = assigns(:project)
221 project = assigns(:project)
214 assert_kind_of Project, project
222 assert_kind_of Project, project
215 assert_not_equal [], project.errors[:parent_id]
223 assert_not_equal [], project.errors[:parent_id]
216 end
224 end
217
225
218 test "#create by non-admin user with add_subprojects permission should create a project with a parent_id" do
226 test "#create by non-admin user with add_subprojects permission should create a project with a parent_id" do
219 Role.find(1).remove_permission! :add_project
227 Role.find(1).remove_permission! :add_project
220 Role.find(1).add_permission! :add_subprojects
228 Role.find(1).add_permission! :add_subprojects
221 @request.session[:user_id] = 2
229 @request.session[:user_id] = 2
222
230
223 post :create, :project => { :name => "blog",
231 post :create, :project => { :name => "blog",
224 :description => "weblog",
232 :description => "weblog",
225 :identifier => "blog",
233 :identifier => "blog",
226 :is_public => 1,
234 :is_public => 1,
227 :custom_field_values => { '3' => 'Beta' },
235 :custom_field_values => { '3' => 'Beta' },
228 :parent_id => 1
236 :parent_id => 1
229 }
237 }
230 assert_redirected_to '/projects/blog/settings'
238 assert_redirected_to '/projects/blog/settings'
231 project = Project.find_by_name('blog')
239 project = Project.find_by_name('blog')
232 end
240 end
233
241
234 test "#create by non-admin user with add_subprojects permission should fail without parent_id" do
242 test "#create by non-admin user with add_subprojects permission should fail without parent_id" do
235 Role.find(1).remove_permission! :add_project
243 Role.find(1).remove_permission! :add_project
236 Role.find(1).add_permission! :add_subprojects
244 Role.find(1).add_permission! :add_subprojects
237 @request.session[:user_id] = 2
245 @request.session[:user_id] = 2
238
246
239 assert_no_difference 'Project.count' do
247 assert_no_difference 'Project.count' do
240 post :create, :project => { :name => "blog",
248 post :create, :project => { :name => "blog",
241 :description => "weblog",
249 :description => "weblog",
242 :identifier => "blog",
250 :identifier => "blog",
243 :is_public => 1,
251 :is_public => 1,
244 :custom_field_values => { '3' => 'Beta' }
252 :custom_field_values => { '3' => 'Beta' }
245 }
253 }
246 end
254 end
247 assert_response :success
255 assert_response :success
248 project = assigns(:project)
256 project = assigns(:project)
249 assert_kind_of Project, project
257 assert_kind_of Project, project
250 assert_not_equal [], project.errors[:parent_id]
258 assert_not_equal [], project.errors[:parent_id]
251 end
259 end
252
260
253 test "#create by non-admin user with add_subprojects permission should fail with unauthorized parent_id" do
261 test "#create by non-admin user with add_subprojects permission should fail with unauthorized parent_id" do
254 Role.find(1).remove_permission! :add_project
262 Role.find(1).remove_permission! :add_project
255 Role.find(1).add_permission! :add_subprojects
263 Role.find(1).add_permission! :add_subprojects
256 @request.session[:user_id] = 2
264 @request.session[:user_id] = 2
257
265
258 assert !User.find(2).member_of?(Project.find(6))
266 assert !User.find(2).member_of?(Project.find(6))
259 assert_no_difference 'Project.count' do
267 assert_no_difference 'Project.count' do
260 post :create, :project => { :name => "blog",
268 post :create, :project => { :name => "blog",
261 :description => "weblog",
269 :description => "weblog",
262 :identifier => "blog",
270 :identifier => "blog",
263 :is_public => 1,
271 :is_public => 1,
264 :custom_field_values => { '3' => 'Beta' },
272 :custom_field_values => { '3' => 'Beta' },
265 :parent_id => 6
273 :parent_id => 6
266 }
274 }
267 end
275 end
268 assert_response :success
276 assert_response :success
269 project = assigns(:project)
277 project = assigns(:project)
270 assert_kind_of Project, project
278 assert_kind_of Project, project
271 assert_not_equal [], project.errors[:parent_id]
279 assert_not_equal [], project.errors[:parent_id]
272 end
280 end
273
281
274 def test_create_subproject_with_inherit_members_should_inherit_members
282 def test_create_subproject_with_inherit_members_should_inherit_members
275 Role.find_by_name('Manager').add_permission! :add_subprojects
283 Role.find_by_name('Manager').add_permission! :add_subprojects
276 parent = Project.find(1)
284 parent = Project.find(1)
277 @request.session[:user_id] = 2
285 @request.session[:user_id] = 2
278
286
279 assert_difference 'Project.count' do
287 assert_difference 'Project.count' do
280 post :create, :project => {
288 post :create, :project => {
281 :name => 'inherited', :identifier => 'inherited', :parent_id => parent.id, :inherit_members => '1'
289 :name => 'inherited', :identifier => 'inherited', :parent_id => parent.id, :inherit_members => '1'
282 }
290 }
283 assert_response 302
291 assert_response 302
284 end
292 end
285
293
286 project = Project.order('id desc').first
294 project = Project.order('id desc').first
287 assert_equal 'inherited', project.name
295 assert_equal 'inherited', project.name
288 assert_equal parent, project.parent
296 assert_equal parent, project.parent
289 assert project.memberships.count > 0
297 assert project.memberships.count > 0
290 assert_equal parent.memberships.count, project.memberships.count
298 assert_equal parent.memberships.count, project.memberships.count
291 end
299 end
292
300
293 def test_create_should_preserve_modules_on_validation_failure
301 def test_create_should_preserve_modules_on_validation_failure
294 with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
302 with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
295 @request.session[:user_id] = 1
303 @request.session[:user_id] = 1
296 assert_no_difference 'Project.count' do
304 assert_no_difference 'Project.count' do
297 post :create, :project => {
305 post :create, :project => {
298 :name => "blog",
306 :name => "blog",
299 :identifier => "",
307 :identifier => "",
300 :enabled_module_names => %w(issue_tracking news)
308 :enabled_module_names => %w(issue_tracking news)
301 }
309 }
302 end
310 end
303 assert_response :success
311 assert_response :success
304 project = assigns(:project)
312 project = assigns(:project)
305 assert_equal %w(issue_tracking news), project.enabled_module_names.sort
313 assert_equal %w(issue_tracking news), project.enabled_module_names.sort
306 end
314 end
307 end
315 end
308
316
309 def test_show_by_id
317 def test_show_by_id
310 get :show, :id => 1
318 get :show, :id => 1
311 assert_response :success
319 assert_response :success
312 assert_template 'show'
320 assert_template 'show'
313 assert_not_nil assigns(:project)
321 assert_not_nil assigns(:project)
314 end
322 end
315
323
316 def test_show_by_identifier
324 def test_show_by_identifier
317 get :show, :id => 'ecookbook'
325 get :show, :id => 'ecookbook'
318 assert_response :success
326 assert_response :success
319 assert_template 'show'
327 assert_template 'show'
320 assert_not_nil assigns(:project)
328 assert_not_nil assigns(:project)
321 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
329 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
322
330
323 assert_select 'li', :text => /Development status/
331 assert_select 'li', :text => /Development status/
324 end
332 end
325
333
326 def test_show_should_not_display_empty_sidebar
334 def test_show_should_not_display_empty_sidebar
327 p = Project.find(1)
335 p = Project.find(1)
328 p.enabled_module_names = []
336 p.enabled_module_names = []
329 p.save!
337 p.save!
330
338
331 get :show, :id => 'ecookbook'
339 get :show, :id => 'ecookbook'
332 assert_response :success
340 assert_response :success
333 assert_select '#main.nosidebar'
341 assert_select '#main.nosidebar'
334 end
342 end
335
343
336 def test_show_should_not_display_hidden_custom_fields
344 def test_show_should_not_display_hidden_custom_fields
337 ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
345 ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
338 get :show, :id => 'ecookbook'
346 get :show, :id => 'ecookbook'
339 assert_response :success
347 assert_response :success
340 assert_template 'show'
348 assert_template 'show'
341 assert_not_nil assigns(:project)
349 assert_not_nil assigns(:project)
342
350
343 assert_select 'li', :text => /Development status/, :count => 0
351 assert_select 'li', :text => /Development status/, :count => 0
344 end
352 end
345
353
346 def test_show_should_not_fail_when_custom_values_are_nil
354 def test_show_should_not_fail_when_custom_values_are_nil
347 project = Project.find_by_identifier('ecookbook')
355 project = Project.find_by_identifier('ecookbook')
348 project.custom_values.first.update_attribute(:value, nil)
356 project.custom_values.first.update_attribute(:value, nil)
349 get :show, :id => 'ecookbook'
357 get :show, :id => 'ecookbook'
350 assert_response :success
358 assert_response :success
351 assert_template 'show'
359 assert_template 'show'
352 assert_not_nil assigns(:project)
360 assert_not_nil assigns(:project)
353 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
361 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
354 end
362 end
355
363
356 def show_archived_project_should_be_denied
364 def show_archived_project_should_be_denied
357 project = Project.find_by_identifier('ecookbook')
365 project = Project.find_by_identifier('ecookbook')
358 project.archive!
366 project.archive!
359
367
360 get :show, :id => 'ecookbook'
368 get :show, :id => 'ecookbook'
361 assert_response 403
369 assert_response 403
362 assert_nil assigns(:project)
370 assert_nil assigns(:project)
363 assert_select 'p', :text => /archived/
371 assert_select 'p', :text => /archived/
364 end
372 end
365
373
366 def test_show_should_not_show_private_subprojects_that_are_not_visible
374 def test_show_should_not_show_private_subprojects_that_are_not_visible
367 get :show, :id => 'ecookbook'
375 get :show, :id => 'ecookbook'
368 assert_response :success
376 assert_response :success
369 assert_template 'show'
377 assert_template 'show'
370 assert_select 'a', :text => /Private child/, :count => 0
378 assert_select 'a', :text => /Private child/, :count => 0
371 end
379 end
372
380
373 def test_show_should_show_private_subprojects_that_are_visible
381 def test_show_should_show_private_subprojects_that_are_visible
374 @request.session[:user_id] = 2 # manager who is a member of the private subproject
382 @request.session[:user_id] = 2 # manager who is a member of the private subproject
375 get :show, :id => 'ecookbook'
383 get :show, :id => 'ecookbook'
376 assert_response :success
384 assert_response :success
377 assert_template 'show'
385 assert_template 'show'
378 assert_select 'a', :text => /Private child/
386 assert_select 'a', :text => /Private child/
379 end
387 end
380
388
381 def test_settings
389 def test_settings
382 @request.session[:user_id] = 2 # manager
390 @request.session[:user_id] = 2 # manager
383 get :settings, :id => 1
391 get :settings, :id => 1
384 assert_response :success
392 assert_response :success
385 assert_template 'settings'
393 assert_template 'settings'
386 end
394 end
387
395
388 def test_settings_of_subproject
396 def test_settings_of_subproject
389 @request.session[:user_id] = 2
397 @request.session[:user_id] = 2
390 get :settings, :id => 'private-child'
398 get :settings, :id => 'private-child'
391 assert_response :success
399 assert_response :success
392 assert_template 'settings'
400 assert_template 'settings'
393
401
394 assert_select 'input[type=checkbox][name=?]', 'project[inherit_members]'
402 assert_select 'input[type=checkbox][name=?]', 'project[inherit_members]'
395 end
403 end
396
404
397 def test_settings_should_be_denied_for_member_on_closed_project
405 def test_settings_should_be_denied_for_member_on_closed_project
398 Project.find(1).close
406 Project.find(1).close
399 @request.session[:user_id] = 2 # manager
407 @request.session[:user_id] = 2 # manager
400
408
401 get :settings, :id => 1
409 get :settings, :id => 1
402 assert_response 403
410 assert_response 403
403 end
411 end
404
412
405 def test_settings_should_be_denied_for_anonymous_on_closed_project
413 def test_settings_should_be_denied_for_anonymous_on_closed_project
406 Project.find(1).close
414 Project.find(1).close
407
415
408 get :settings, :id => 1
416 get :settings, :id => 1
409 assert_response 302
417 assert_response 302
410 end
418 end
411
419
412 def test_setting_with_wiki_module_and_no_wiki
420 def test_setting_with_wiki_module_and_no_wiki
413 Project.find(1).wiki.destroy
421 Project.find(1).wiki.destroy
414 Role.find(1).add_permission! :manage_wiki
422 Role.find(1).add_permission! :manage_wiki
415 @request.session[:user_id] = 2
423 @request.session[:user_id] = 2
416
424
417 get :settings, :id => 1
425 get :settings, :id => 1
418 assert_response :success
426 assert_response :success
419 assert_template 'settings'
427 assert_template 'settings'
420
428
421 assert_select 'form[action=?]', '/projects/ecookbook/wiki' do
429 assert_select 'form[action=?]', '/projects/ecookbook/wiki' do
422 assert_select 'input[name=?]', 'wiki[start_page]'
430 assert_select 'input[name=?]', 'wiki[start_page]'
423 end
431 end
424 end
432 end
425
433
426 def test_update
434 def test_update
427 @request.session[:user_id] = 2 # manager
435 @request.session[:user_id] = 2 # manager
428 post :update, :id => 1, :project => {:name => 'Test changed name',
436 post :update, :id => 1, :project => {:name => 'Test changed name',
429 :issue_custom_field_ids => ['']}
437 :issue_custom_field_ids => ['']}
430 assert_redirected_to '/projects/ecookbook/settings'
438 assert_redirected_to '/projects/ecookbook/settings'
431 project = Project.find(1)
439 project = Project.find(1)
432 assert_equal 'Test changed name', project.name
440 assert_equal 'Test changed name', project.name
433 end
441 end
434
442
435 def test_update_with_failure
443 def test_update_with_failure
436 @request.session[:user_id] = 2 # manager
444 @request.session[:user_id] = 2 # manager
437 post :update, :id => 1, :project => {:name => ''}
445 post :update, :id => 1, :project => {:name => ''}
438 assert_response :success
446 assert_response :success
439 assert_template 'settings'
447 assert_template 'settings'
440 assert_select_error /name #{ESCAPED_CANT} be blank/i
448 assert_select_error /name #{ESCAPED_CANT} be blank/i
441 end
449 end
442
450
443 def test_update_should_be_denied_for_member_on_closed_project
451 def test_update_should_be_denied_for_member_on_closed_project
444 Project.find(1).close
452 Project.find(1).close
445 @request.session[:user_id] = 2 # manager
453 @request.session[:user_id] = 2 # manager
446
454
447 post :update, :id => 1, :project => {:name => 'Closed'}
455 post :update, :id => 1, :project => {:name => 'Closed'}
448 assert_response 403
456 assert_response 403
449 assert_equal 'eCookbook', Project.find(1).name
457 assert_equal 'eCookbook', Project.find(1).name
450 end
458 end
451
459
452 def test_update_should_be_denied_for_anonymous_on_closed_project
460 def test_update_should_be_denied_for_anonymous_on_closed_project
453 Project.find(1).close
461 Project.find(1).close
454
462
455 post :update, :id => 1, :project => {:name => 'Closed'}
463 post :update, :id => 1, :project => {:name => 'Closed'}
456 assert_response 302
464 assert_response 302
457 assert_equal 'eCookbook', Project.find(1).name
465 assert_equal 'eCookbook', Project.find(1).name
458 end
466 end
459
467
460 def test_modules
468 def test_modules
461 @request.session[:user_id] = 2
469 @request.session[:user_id] = 2
462 Project.find(1).enabled_module_names = ['issue_tracking', 'news']
470 Project.find(1).enabled_module_names = ['issue_tracking', 'news']
463
471
464 post :modules, :id => 1, :enabled_module_names => ['issue_tracking', 'repository', 'documents']
472 post :modules, :id => 1, :enabled_module_names => ['issue_tracking', 'repository', 'documents']
465 assert_redirected_to '/projects/ecookbook/settings/modules'
473 assert_redirected_to '/projects/ecookbook/settings/modules'
466 assert_equal ['documents', 'issue_tracking', 'repository'], Project.find(1).enabled_module_names.sort
474 assert_equal ['documents', 'issue_tracking', 'repository'], Project.find(1).enabled_module_names.sort
467 end
475 end
468
476
469 def test_destroy_leaf_project_without_confirmation_should_show_confirmation
477 def test_destroy_leaf_project_without_confirmation_should_show_confirmation
470 @request.session[:user_id] = 1 # admin
478 @request.session[:user_id] = 1 # admin
471
479
472 assert_no_difference 'Project.count' do
480 assert_no_difference 'Project.count' do
473 delete :destroy, :id => 2
481 delete :destroy, :id => 2
474 assert_response :success
482 assert_response :success
475 assert_template 'destroy'
483 assert_template 'destroy'
476 end
484 end
477 end
485 end
478
486
479 def test_destroy_without_confirmation_should_show_confirmation_with_subprojects
487 def test_destroy_without_confirmation_should_show_confirmation_with_subprojects
480 @request.session[:user_id] = 1 # admin
488 @request.session[:user_id] = 1 # admin
481
489
482 assert_no_difference 'Project.count' do
490 assert_no_difference 'Project.count' do
483 delete :destroy, :id => 1
491 delete :destroy, :id => 1
484 assert_response :success
492 assert_response :success
485 assert_template 'destroy'
493 assert_template 'destroy'
486 end
494 end
487 assert_select 'strong',
495 assert_select 'strong',
488 :text => ['Private child of eCookbook',
496 :text => ['Private child of eCookbook',
489 'Child of private child, eCookbook Subproject 1',
497 'Child of private child, eCookbook Subproject 1',
490 'eCookbook Subproject 2'].join(', ')
498 'eCookbook Subproject 2'].join(', ')
491 end
499 end
492
500
493 def test_destroy_with_confirmation_should_destroy_the_project_and_subprojects
501 def test_destroy_with_confirmation_should_destroy_the_project_and_subprojects
494 @request.session[:user_id] = 1 # admin
502 @request.session[:user_id] = 1 # admin
495
503
496 assert_difference 'Project.count', -5 do
504 assert_difference 'Project.count', -5 do
497 delete :destroy, :id => 1, :confirm => 1
505 delete :destroy, :id => 1, :confirm => 1
498 assert_redirected_to '/admin/projects'
506 assert_redirected_to '/admin/projects'
499 end
507 end
500 assert_nil Project.find_by_id(1)
508 assert_nil Project.find_by_id(1)
501 end
509 end
502
510
503 def test_archive
511 def test_archive
504 @request.session[:user_id] = 1 # admin
512 @request.session[:user_id] = 1 # admin
505 post :archive, :id => 1
513 post :archive, :id => 1
506 assert_redirected_to '/admin/projects'
514 assert_redirected_to '/admin/projects'
507 assert !Project.find(1).active?
515 assert !Project.find(1).active?
508 end
516 end
509
517
510 def test_archive_with_failure
518 def test_archive_with_failure
511 @request.session[:user_id] = 1
519 @request.session[:user_id] = 1
512 Project.any_instance.stubs(:archive).returns(false)
520 Project.any_instance.stubs(:archive).returns(false)
513 post :archive, :id => 1
521 post :archive, :id => 1
514 assert_redirected_to '/admin/projects'
522 assert_redirected_to '/admin/projects'
515 assert_match /project cannot be archived/i, flash[:error]
523 assert_match /project cannot be archived/i, flash[:error]
516 end
524 end
517
525
518 def test_unarchive
526 def test_unarchive
519 @request.session[:user_id] = 1 # admin
527 @request.session[:user_id] = 1 # admin
520 Project.find(1).archive
528 Project.find(1).archive
521 post :unarchive, :id => 1
529 post :unarchive, :id => 1
522 assert_redirected_to '/admin/projects'
530 assert_redirected_to '/admin/projects'
523 assert Project.find(1).active?
531 assert Project.find(1).active?
524 end
532 end
525
533
526 def test_close
534 def test_close
527 @request.session[:user_id] = 2
535 @request.session[:user_id] = 2
528 post :close, :id => 1
536 post :close, :id => 1
529 assert_redirected_to '/projects/ecookbook'
537 assert_redirected_to '/projects/ecookbook'
530 assert_equal Project::STATUS_CLOSED, Project.find(1).status
538 assert_equal Project::STATUS_CLOSED, Project.find(1).status
531 end
539 end
532
540
533 def test_reopen
541 def test_reopen
534 Project.find(1).close
542 Project.find(1).close
535 @request.session[:user_id] = 2
543 @request.session[:user_id] = 2
536 post :reopen, :id => 1
544 post :reopen, :id => 1
537 assert_redirected_to '/projects/ecookbook'
545 assert_redirected_to '/projects/ecookbook'
538 assert Project.find(1).active?
546 assert Project.find(1).active?
539 end
547 end
540
548
541 def test_project_breadcrumbs_should_be_limited_to_3_ancestors
549 def test_project_breadcrumbs_should_be_limited_to_3_ancestors
542 CustomField.delete_all
550 CustomField.delete_all
543 parent = nil
551 parent = nil
544 6.times do |i|
552 6.times do |i|
545 p = Project.generate_with_parent!(parent)
553 p = Project.generate_with_parent!(parent)
546 get :show, :id => p
554 get :show, :id => p
547 assert_select '#header h1' do
555 assert_select '#header h1' do
548 assert_select 'a', :count => [i, 3].min
556 assert_select 'a', :count => [i, 3].min
549 end
557 end
550
558
551 parent = p
559 parent = p
552 end
560 end
553 end
561 end
554
562
555 def test_get_copy
563 def test_get_copy
556 @request.session[:user_id] = 1 # admin
564 @request.session[:user_id] = 1 # admin
557 get :copy, :id => 1
565 get :copy, :id => 1
558 assert_response :success
566 assert_response :success
559 assert_template 'copy'
567 assert_template 'copy'
560 assert assigns(:project)
568 assert assigns(:project)
561 assert_equal Project.find(1).description, assigns(:project).description
569 assert_equal Project.find(1).description, assigns(:project).description
562 assert_nil assigns(:project).id
570 assert_nil assigns(:project).id
563
571
564 assert_select 'input[name=?][value=?]', 'project[enabled_module_names][]', 'issue_tracking', 1
572 assert_select 'input[name=?][value=?]', 'project[enabled_module_names][]', 'issue_tracking', 1
565 end
573 end
566
574
567 def test_get_copy_with_invalid_source_should_respond_with_404
575 def test_get_copy_with_invalid_source_should_respond_with_404
568 @request.session[:user_id] = 1
576 @request.session[:user_id] = 1
569 get :copy, :id => 99
577 get :copy, :id => 99
570 assert_response 404
578 assert_response 404
571 end
579 end
572
580
573 def test_post_copy_should_copy_requested_items
581 def test_post_copy_should_copy_requested_items
574 @request.session[:user_id] = 1 # admin
582 @request.session[:user_id] = 1 # admin
575 CustomField.delete_all
583 CustomField.delete_all
576
584
577 assert_difference 'Project.count' do
585 assert_difference 'Project.count' do
578 post :copy, :id => 1,
586 post :copy, :id => 1,
579 :project => {
587 :project => {
580 :name => 'Copy',
588 :name => 'Copy',
581 :identifier => 'unique-copy',
589 :identifier => 'unique-copy',
582 :tracker_ids => ['1', '2', '3', ''],
590 :tracker_ids => ['1', '2', '3', ''],
583 :enabled_module_names => %w(issue_tracking time_tracking)
591 :enabled_module_names => %w(issue_tracking time_tracking)
584 },
592 },
585 :only => %w(issues versions)
593 :only => %w(issues versions)
586 end
594 end
587 project = Project.find('unique-copy')
595 project = Project.find('unique-copy')
588 source = Project.find(1)
596 source = Project.find(1)
589 assert_equal %w(issue_tracking time_tracking), project.enabled_module_names.sort
597 assert_equal %w(issue_tracking time_tracking), project.enabled_module_names.sort
590
598
591 assert_equal source.versions.count, project.versions.count, "All versions were not copied"
599 assert_equal source.versions.count, project.versions.count, "All versions were not copied"
592 assert_equal source.issues.count, project.issues.count, "All issues were not copied"
600 assert_equal source.issues.count, project.issues.count, "All issues were not copied"
593 assert_equal 0, project.members.count
601 assert_equal 0, project.members.count
594 end
602 end
595
603
596 def test_post_copy_should_redirect_to_settings_when_successful
604 def test_post_copy_should_redirect_to_settings_when_successful
597 @request.session[:user_id] = 1 # admin
605 @request.session[:user_id] = 1 # admin
598 post :copy, :id => 1, :project => {:name => 'Copy', :identifier => 'unique-copy'}
606 post :copy, :id => 1, :project => {:name => 'Copy', :identifier => 'unique-copy'}
599 assert_response :redirect
607 assert_response :redirect
600 assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'unique-copy'
608 assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'unique-copy'
601 end
609 end
602
610
603 def test_jump_should_redirect_to_active_tab
611 def test_jump_should_redirect_to_active_tab
604 get :show, :id => 1, :jump => 'issues'
612 get :show, :id => 1, :jump => 'issues'
605 assert_redirected_to '/projects/ecookbook/issues'
613 assert_redirected_to '/projects/ecookbook/issues'
606 end
614 end
607
615
608 def test_jump_should_not_redirect_to_inactive_tab
616 def test_jump_should_not_redirect_to_inactive_tab
609 get :show, :id => 3, :jump => 'documents'
617 get :show, :id => 3, :jump => 'documents'
610 assert_response :success
618 assert_response :success
611 assert_template 'show'
619 assert_template 'show'
612 end
620 end
613
621
614 def test_jump_should_not_redirect_to_unknown_tab
622 def test_jump_should_not_redirect_to_unknown_tab
615 get :show, :id => 3, :jump => 'foobar'
623 get :show, :id => 3, :jump => 'foobar'
616 assert_response :success
624 assert_response :success
617 assert_template 'show'
625 assert_template 'show'
618 end
626 end
619
627
620 def test_body_should_have_project_css_class
628 def test_body_should_have_project_css_class
621 get :show, :id => 1
629 get :show, :id => 1
622 assert_select 'body.project-ecookbook'
630 assert_select 'body.project-ecookbook'
623 end
631 end
624 end
632 end
@@ -1,430 +1,441
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 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 UsersControllerTest < ActionController::TestCase
20 class UsersControllerTest < ActionController::TestCase
21 include Redmine::I18n
21 include Redmine::I18n
22
22
23 fixtures :users, :projects, :members, :member_roles, :roles,
23 fixtures :users, :projects, :members, :member_roles, :roles,
24 :custom_fields, :custom_values, :groups_users,
24 :custom_fields, :custom_values, :groups_users,
25 :auth_sources
25 :auth_sources
26
26
27 def setup
27 def setup
28 User.current = nil
28 User.current = nil
29 @request.session[:user_id] = 1 # admin
29 @request.session[:user_id] = 1 # admin
30 end
30 end
31
31
32 def test_index
32 def test_index
33 get :index
33 get :index
34 assert_response :success
34 assert_response :success
35 assert_template 'index'
35 assert_template 'index'
36 assert_not_nil assigns(:users)
36 assert_not_nil assigns(:users)
37 # active users only
37 # active users only
38 assert_nil assigns(:users).detect {|u| !u.active?}
38 assert_nil assigns(:users).detect {|u| !u.active?}
39 end
39 end
40
40
41 def test_index_with_status_filter
41 def test_index_with_status_filter
42 get :index, :status => 3
42 get :index, :status => 3
43 assert_response :success
43 assert_response :success
44 assert_template 'index'
44 assert_template 'index'
45 assert_not_nil assigns(:users)
45 assert_not_nil assigns(:users)
46 assert_equal [3], assigns(:users).map(&:status).uniq
46 assert_equal [3], assigns(:users).map(&:status).uniq
47 end
47 end
48
48
49 def test_index_with_name_filter
49 def test_index_with_name_filter
50 get :index, :name => 'john'
50 get :index, :name => 'john'
51 assert_response :success
51 assert_response :success
52 assert_template 'index'
52 assert_template 'index'
53 users = assigns(:users)
53 users = assigns(:users)
54 assert_not_nil users
54 assert_not_nil users
55 assert_equal 1, users.size
55 assert_equal 1, users.size
56 assert_equal 'John', users.first.firstname
56 assert_equal 'John', users.first.firstname
57 end
57 end
58
58
59 def test_index_with_group_filter
59 def test_index_with_group_filter
60 get :index, :group_id => '10'
60 get :index, :group_id => '10'
61 assert_response :success
61 assert_response :success
62 assert_template 'index'
62 assert_template 'index'
63 users = assigns(:users)
63 users = assigns(:users)
64 assert users.any?
64 assert users.any?
65 assert_equal([], (users - Group.find(10).users))
65 assert_equal([], (users - Group.find(10).users))
66 assert_select 'select[name=group_id]' do
66 assert_select 'select[name=group_id]' do
67 assert_select 'option[value="10"][selected=selected]'
67 assert_select 'option[value="10"][selected=selected]'
68 end
68 end
69 end
69 end
70
70
71 def test_show
71 def test_show
72 @request.session[:user_id] = nil
72 @request.session[:user_id] = nil
73 get :show, :id => 2
73 get :show, :id => 2
74 assert_response :success
74 assert_response :success
75 assert_template 'show'
75 assert_template 'show'
76 assert_not_nil assigns(:user)
76 assert_not_nil assigns(:user)
77
77
78 assert_select 'li', :text => /Phone number/
78 assert_select 'li', :text => /Phone number/
79 end
79 end
80
80
81 def test_show_should_not_display_hidden_custom_fields
81 def test_show_should_not_display_hidden_custom_fields
82 @request.session[:user_id] = nil
82 @request.session[:user_id] = nil
83 UserCustomField.find_by_name('Phone number').update_attribute :visible, false
83 UserCustomField.find_by_name('Phone number').update_attribute :visible, false
84 get :show, :id => 2
84 get :show, :id => 2
85 assert_response :success
85 assert_response :success
86 assert_template 'show'
86 assert_template 'show'
87 assert_not_nil assigns(:user)
87 assert_not_nil assigns(:user)
88
88
89 assert_select 'li', :text => /Phone number/, :count => 0
89 assert_select 'li', :text => /Phone number/, :count => 0
90 end
90 end
91
91
92 def test_show_should_not_fail_when_custom_values_are_nil
92 def test_show_should_not_fail_when_custom_values_are_nil
93 user = User.find(2)
93 user = User.find(2)
94
94
95 # Create a custom field to illustrate the issue
95 # Create a custom field to illustrate the issue
96 custom_field = CustomField.create!(:name => 'Testing', :field_format => 'text')
96 custom_field = CustomField.create!(:name => 'Testing', :field_format => 'text')
97 custom_value = user.custom_values.build(:custom_field => custom_field).save!
97 custom_value = user.custom_values.build(:custom_field => custom_field).save!
98
98
99 get :show, :id => 2
99 get :show, :id => 2
100 assert_response :success
100 assert_response :success
101 end
101 end
102
102
103 def test_show_inactive
103 def test_show_inactive
104 @request.session[:user_id] = nil
104 @request.session[:user_id] = nil
105 get :show, :id => 5
105 get :show, :id => 5
106 assert_response 404
106 assert_response 404
107 end
107 end
108
108
109 def test_show_inactive_by_admin
109 def test_show_inactive_by_admin
110 @request.session[:user_id] = 1
110 @request.session[:user_id] = 1
111 get :show, :id => 5
111 get :show, :id => 5
112 assert_response 200
112 assert_response 200
113 assert_not_nil assigns(:user)
113 assert_not_nil assigns(:user)
114 end
114 end
115
115
116 def test_show_user_who_is_not_visible_should_return_404
116 def test_show_user_who_is_not_visible_should_return_404
117 Role.anonymous.update! :users_visibility => 'members_of_visible_projects'
117 Role.anonymous.update! :users_visibility => 'members_of_visible_projects'
118 user = User.generate!
118 user = User.generate!
119
119
120 @request.session[:user_id] = nil
120 @request.session[:user_id] = nil
121 get :show, :id => user.id
121 get :show, :id => user.id
122 assert_response 404
122 assert_response 404
123 end
123 end
124
124
125 def test_show_displays_memberships_based_on_project_visibility
125 def test_show_displays_memberships_based_on_project_visibility
126 @request.session[:user_id] = 1
126 @request.session[:user_id] = 1
127 get :show, :id => 2
127 get :show, :id => 2
128 assert_response :success
128 assert_response :success
129 memberships = assigns(:memberships)
129 memberships = assigns(:memberships)
130 assert_not_nil memberships
130 assert_not_nil memberships
131 project_ids = memberships.map(&:project_id)
131 project_ids = memberships.map(&:project_id)
132 assert project_ids.include?(2) #private project admin can see
132 assert project_ids.include?(2) #private project admin can see
133 end
133 end
134
134
135 def test_show_current_should_require_authentication
135 def test_show_current_should_require_authentication
136 @request.session[:user_id] = nil
136 @request.session[:user_id] = nil
137 get :show, :id => 'current'
137 get :show, :id => 'current'
138 assert_response 302
138 assert_response 302
139 end
139 end
140
140
141 def test_show_current
141 def test_show_current
142 @request.session[:user_id] = 2
142 @request.session[:user_id] = 2
143 get :show, :id => 'current'
143 get :show, :id => 'current'
144 assert_response :success
144 assert_response :success
145 assert_template 'show'
145 assert_template 'show'
146 assert_equal User.find(2), assigns(:user)
146 assert_equal User.find(2), assigns(:user)
147 end
147 end
148
148
149 def test_new
149 def test_new
150 get :new
150 get :new
151 assert_response :success
151 assert_response :success
152 assert_template :new
152 assert_template :new
153 assert assigns(:user)
153 assert assigns(:user)
154 end
154 end
155
155
156 def test_create
156 def test_create
157 Setting.bcc_recipients = '1'
157 Setting.bcc_recipients = '1'
158
158
159 assert_difference 'User.count' do
159 assert_difference 'User.count' do
160 assert_difference 'ActionMailer::Base.deliveries.size' do
160 assert_difference 'ActionMailer::Base.deliveries.size' do
161 post :create,
161 post :create,
162 :user => {
162 :user => {
163 :firstname => 'John',
163 :firstname => 'John',
164 :lastname => 'Doe',
164 :lastname => 'Doe',
165 :login => 'jdoe',
165 :login => 'jdoe',
166 :password => 'secret123',
166 :password => 'secret123',
167 :password_confirmation => 'secret123',
167 :password_confirmation => 'secret123',
168 :mail => 'jdoe@gmail.com',
168 :mail => 'jdoe@gmail.com',
169 :mail_notification => 'none'
169 :mail_notification => 'none'
170 },
170 },
171 :send_information => '1'
171 :send_information => '1'
172 end
172 end
173 end
173 end
174
174
175 user = User.order('id DESC').first
175 user = User.order('id DESC').first
176 assert_redirected_to :controller => 'users', :action => 'edit', :id => user.id
176 assert_redirected_to :controller => 'users', :action => 'edit', :id => user.id
177
177
178 assert_equal 'John', user.firstname
178 assert_equal 'John', user.firstname
179 assert_equal 'Doe', user.lastname
179 assert_equal 'Doe', user.lastname
180 assert_equal 'jdoe', user.login
180 assert_equal 'jdoe', user.login
181 assert_equal 'jdoe@gmail.com', user.mail
181 assert_equal 'jdoe@gmail.com', user.mail
182 assert_equal 'none', user.mail_notification
182 assert_equal 'none', user.mail_notification
183 assert user.check_password?('secret123')
183 assert user.check_password?('secret123')
184
184
185 mail = ActionMailer::Base.deliveries.last
185 mail = ActionMailer::Base.deliveries.last
186 assert_not_nil mail
186 assert_not_nil mail
187 assert_equal [user.mail], mail.bcc
187 assert_equal [user.mail], mail.bcc
188 assert_mail_body_match 'secret', mail
188 assert_mail_body_match 'secret', mail
189 end
189 end
190
190
191 def test_create_with_preferences
191 def test_create_with_preferences
192 assert_difference 'User.count' do
192 assert_difference 'User.count' do
193 post :create,
193 post :create,
194 :user => {
194 :user => {
195 :firstname => 'John',
195 :firstname => 'John',
196 :lastname => 'Doe',
196 :lastname => 'Doe',
197 :login => 'jdoe',
197 :login => 'jdoe',
198 :password => 'secret123',
198 :password => 'secret123',
199 :password_confirmation => 'secret123',
199 :password_confirmation => 'secret123',
200 :mail => 'jdoe@gmail.com',
200 :mail => 'jdoe@gmail.com',
201 :mail_notification => 'none'
201 :mail_notification => 'none'
202 },
202 },
203 :pref => {
203 :pref => {
204 'hide_mail' => '1',
204 'hide_mail' => '1',
205 'time_zone' => 'Paris',
205 'time_zone' => 'Paris',
206 'comments_sorting' => 'desc',
206 'comments_sorting' => 'desc',
207 'warn_on_leaving_unsaved' => '0'
207 'warn_on_leaving_unsaved' => '0'
208 }
208 }
209 end
209 end
210 user = User.order('id DESC').first
210 user = User.order('id DESC').first
211 assert_equal 'jdoe', user.login
211 assert_equal 'jdoe', user.login
212 assert_equal true, user.pref.hide_mail
212 assert_equal true, user.pref.hide_mail
213 assert_equal 'Paris', user.pref.time_zone
213 assert_equal 'Paris', user.pref.time_zone
214 assert_equal 'desc', user.pref[:comments_sorting]
214 assert_equal 'desc', user.pref[:comments_sorting]
215 assert_equal '0', user.pref[:warn_on_leaving_unsaved]
215 assert_equal '0', user.pref[:warn_on_leaving_unsaved]
216 end
216 end
217
217
218 def test_create_with_generate_password_should_email_the_password
218 def test_create_with_generate_password_should_email_the_password
219 assert_difference 'User.count' do
219 assert_difference 'User.count' do
220 post :create, :user => {
220 post :create, :user => {
221 :login => 'randompass',
221 :login => 'randompass',
222 :firstname => 'Random',
222 :firstname => 'Random',
223 :lastname => 'Pass',
223 :lastname => 'Pass',
224 :mail => 'randompass@example.net',
224 :mail => 'randompass@example.net',
225 :language => 'en',
225 :language => 'en',
226 :generate_password => '1',
226 :generate_password => '1',
227 :password => '',
227 :password => '',
228 :password_confirmation => ''
228 :password_confirmation => ''
229 }, :send_information => 1
229 }, :send_information => 1
230 end
230 end
231 user = User.order('id DESC').first
231 user = User.order('id DESC').first
232 assert_equal 'randompass', user.login
232 assert_equal 'randompass', user.login
233
233
234 mail = ActionMailer::Base.deliveries.last
234 mail = ActionMailer::Base.deliveries.last
235 assert_not_nil mail
235 assert_not_nil mail
236 m = mail_body(mail).match(/Password: ([a-zA-Z0-9]+)/)
236 m = mail_body(mail).match(/Password: ([a-zA-Z0-9]+)/)
237 assert m
237 assert m
238 password = m[1]
238 password = m[1]
239 assert user.check_password?(password)
239 assert user.check_password?(password)
240 end
240 end
241
241
242 def test_create_and_continue
243 post :create, :user => {
244 :login => 'randompass',
245 :firstname => 'Random',
246 :lastname => 'Pass',
247 :mail => 'randompass@example.net',
248 :generate_password => '1'
249 }, :continue => '1'
250 assert_redirected_to '/users/new?user%5Bgenerate_password%5D=1'
251 end
252
242 def test_create_with_failure
253 def test_create_with_failure
243 assert_no_difference 'User.count' do
254 assert_no_difference 'User.count' do
244 post :create, :user => {}
255 post :create, :user => {}
245 end
256 end
246 assert_response :success
257 assert_response :success
247 assert_template 'new'
258 assert_template 'new'
248 end
259 end
249
260
250 def test_create_with_failure_sould_preserve_preference
261 def test_create_with_failure_sould_preserve_preference
251 assert_no_difference 'User.count' do
262 assert_no_difference 'User.count' do
252 post :create,
263 post :create,
253 :user => {},
264 :user => {},
254 :pref => {
265 :pref => {
255 'no_self_notified' => '1',
266 'no_self_notified' => '1',
256 'hide_mail' => '1',
267 'hide_mail' => '1',
257 'time_zone' => 'Paris',
268 'time_zone' => 'Paris',
258 'comments_sorting' => 'desc',
269 'comments_sorting' => 'desc',
259 'warn_on_leaving_unsaved' => '0'
270 'warn_on_leaving_unsaved' => '0'
260 }
271 }
261 end
272 end
262 assert_response :success
273 assert_response :success
263 assert_template 'new'
274 assert_template 'new'
264
275
265 assert_select 'select#pref_time_zone option[selected=selected]', :text => /Paris/
276 assert_select 'select#pref_time_zone option[selected=selected]', :text => /Paris/
266 assert_select 'input#pref_no_self_notified[value="1"][checked=checked]'
277 assert_select 'input#pref_no_self_notified[value="1"][checked=checked]'
267 end
278 end
268
279
269 def test_edit
280 def test_edit
270 get :edit, :id => 2
281 get :edit, :id => 2
271 assert_response :success
282 assert_response :success
272 assert_template 'edit'
283 assert_template 'edit'
273 assert_equal User.find(2), assigns(:user)
284 assert_equal User.find(2), assigns(:user)
274 end
285 end
275
286
276 def test_update
287 def test_update
277 ActionMailer::Base.deliveries.clear
288 ActionMailer::Base.deliveries.clear
278 put :update, :id => 2,
289 put :update, :id => 2,
279 :user => {:firstname => 'Changed', :mail_notification => 'only_assigned'},
290 :user => {:firstname => 'Changed', :mail_notification => 'only_assigned'},
280 :pref => {:hide_mail => '1', :comments_sorting => 'desc'}
291 :pref => {:hide_mail => '1', :comments_sorting => 'desc'}
281 user = User.find(2)
292 user = User.find(2)
282 assert_equal 'Changed', user.firstname
293 assert_equal 'Changed', user.firstname
283 assert_equal 'only_assigned', user.mail_notification
294 assert_equal 'only_assigned', user.mail_notification
284 assert_equal true, user.pref[:hide_mail]
295 assert_equal true, user.pref[:hide_mail]
285 assert_equal 'desc', user.pref[:comments_sorting]
296 assert_equal 'desc', user.pref[:comments_sorting]
286 assert ActionMailer::Base.deliveries.empty?
297 assert ActionMailer::Base.deliveries.empty?
287 end
298 end
288
299
289 def test_update_with_failure
300 def test_update_with_failure
290 assert_no_difference 'User.count' do
301 assert_no_difference 'User.count' do
291 put :update, :id => 2, :user => {:firstname => ''}
302 put :update, :id => 2, :user => {:firstname => ''}
292 end
303 end
293 assert_response :success
304 assert_response :success
294 assert_template 'edit'
305 assert_template 'edit'
295 end
306 end
296
307
297 def test_update_with_group_ids_should_assign_groups
308 def test_update_with_group_ids_should_assign_groups
298 put :update, :id => 2, :user => {:group_ids => ['10']}
309 put :update, :id => 2, :user => {:group_ids => ['10']}
299 user = User.find(2)
310 user = User.find(2)
300 assert_equal [10], user.group_ids
311 assert_equal [10], user.group_ids
301 end
312 end
302
313
303 def test_update_with_activation_should_send_a_notification
314 def test_update_with_activation_should_send_a_notification
304 u = User.new(:firstname => 'Foo', :lastname => 'Bar', :mail => 'foo.bar@somenet.foo', :language => 'fr')
315 u = User.new(:firstname => 'Foo', :lastname => 'Bar', :mail => 'foo.bar@somenet.foo', :language => 'fr')
305 u.login = 'foo'
316 u.login = 'foo'
306 u.status = User::STATUS_REGISTERED
317 u.status = User::STATUS_REGISTERED
307 u.save!
318 u.save!
308 ActionMailer::Base.deliveries.clear
319 ActionMailer::Base.deliveries.clear
309 Setting.bcc_recipients = '1'
320 Setting.bcc_recipients = '1'
310
321
311 put :update, :id => u.id, :user => {:status => User::STATUS_ACTIVE}
322 put :update, :id => u.id, :user => {:status => User::STATUS_ACTIVE}
312 assert u.reload.active?
323 assert u.reload.active?
313 mail = ActionMailer::Base.deliveries.last
324 mail = ActionMailer::Base.deliveries.last
314 assert_not_nil mail
325 assert_not_nil mail
315 assert_equal ['foo.bar@somenet.foo'], mail.bcc
326 assert_equal ['foo.bar@somenet.foo'], mail.bcc
316 assert_mail_body_match ll('fr', :notice_account_activated), mail
327 assert_mail_body_match ll('fr', :notice_account_activated), mail
317 end
328 end
318
329
319 def test_update_with_password_change_should_send_a_notification
330 def test_update_with_password_change_should_send_a_notification
320 ActionMailer::Base.deliveries.clear
331 ActionMailer::Base.deliveries.clear
321 Setting.bcc_recipients = '1'
332 Setting.bcc_recipients = '1'
322
333
323 put :update, :id => 2, :user => {:password => 'newpass123', :password_confirmation => 'newpass123'}, :send_information => '1'
334 put :update, :id => 2, :user => {:password => 'newpass123', :password_confirmation => 'newpass123'}, :send_information => '1'
324 u = User.find(2)
335 u = User.find(2)
325 assert u.check_password?('newpass123')
336 assert u.check_password?('newpass123')
326
337
327 mail = ActionMailer::Base.deliveries.last
338 mail = ActionMailer::Base.deliveries.last
328 assert_not_nil mail
339 assert_not_nil mail
329 assert_equal [u.mail], mail.bcc
340 assert_equal [u.mail], mail.bcc
330 assert_mail_body_match 'newpass123', mail
341 assert_mail_body_match 'newpass123', mail
331 end
342 end
332
343
333 def test_update_with_generate_password_should_email_the_password
344 def test_update_with_generate_password_should_email_the_password
334 ActionMailer::Base.deliveries.clear
345 ActionMailer::Base.deliveries.clear
335 Setting.bcc_recipients = '1'
346 Setting.bcc_recipients = '1'
336
347
337 put :update, :id => 2, :user => {
348 put :update, :id => 2, :user => {
338 :generate_password => '1',
349 :generate_password => '1',
339 :password => '',
350 :password => '',
340 :password_confirmation => ''
351 :password_confirmation => ''
341 }, :send_information => '1'
352 }, :send_information => '1'
342
353
343 mail = ActionMailer::Base.deliveries.last
354 mail = ActionMailer::Base.deliveries.last
344 assert_not_nil mail
355 assert_not_nil mail
345 m = mail_body(mail).match(/Password: ([a-zA-Z0-9]+)/)
356 m = mail_body(mail).match(/Password: ([a-zA-Z0-9]+)/)
346 assert m
357 assert m
347 password = m[1]
358 password = m[1]
348 assert User.find(2).check_password?(password)
359 assert User.find(2).check_password?(password)
349 end
360 end
350
361
351 def test_update_without_generate_password_should_not_change_password
362 def test_update_without_generate_password_should_not_change_password
352 put :update, :id => 2, :user => {
363 put :update, :id => 2, :user => {
353 :firstname => 'changed',
364 :firstname => 'changed',
354 :generate_password => '0',
365 :generate_password => '0',
355 :password => '',
366 :password => '',
356 :password_confirmation => ''
367 :password_confirmation => ''
357 }, :send_information => '1'
368 }, :send_information => '1'
358
369
359 user = User.find(2)
370 user = User.find(2)
360 assert_equal 'changed', user.firstname
371 assert_equal 'changed', user.firstname
361 assert user.check_password?('jsmith')
372 assert user.check_password?('jsmith')
362 end
373 end
363
374
364 def test_update_user_switchin_from_auth_source_to_password_authentication
375 def test_update_user_switchin_from_auth_source_to_password_authentication
365 # Configure as auth source
376 # Configure as auth source
366 u = User.find(2)
377 u = User.find(2)
367 u.auth_source = AuthSource.find(1)
378 u.auth_source = AuthSource.find(1)
368 u.save!
379 u.save!
369
380
370 put :update, :id => u.id, :user => {:auth_source_id => '', :password => 'newpass123', :password_confirmation => 'newpass123'}
381 put :update, :id => u.id, :user => {:auth_source_id => '', :password => 'newpass123', :password_confirmation => 'newpass123'}
371
382
372 assert_equal nil, u.reload.auth_source
383 assert_equal nil, u.reload.auth_source
373 assert u.check_password?('newpass123')
384 assert u.check_password?('newpass123')
374 end
385 end
375
386
376 def test_update_notified_project
387 def test_update_notified_project
377 get :edit, :id => 2
388 get :edit, :id => 2
378 assert_response :success
389 assert_response :success
379 assert_template 'edit'
390 assert_template 'edit'
380 u = User.find(2)
391 u = User.find(2)
381 assert_equal [1, 2, 5], u.projects.collect{|p| p.id}.sort
392 assert_equal [1, 2, 5], u.projects.collect{|p| p.id}.sort
382 assert_equal [1, 2, 5], u.notified_projects_ids.sort
393 assert_equal [1, 2, 5], u.notified_projects_ids.sort
383 assert_select 'input[name=?][value=?]', 'user[notified_project_ids][]', '1'
394 assert_select 'input[name=?][value=?]', 'user[notified_project_ids][]', '1'
384 assert_equal 'all', u.mail_notification
395 assert_equal 'all', u.mail_notification
385 put :update, :id => 2,
396 put :update, :id => 2,
386 :user => {
397 :user => {
387 :mail_notification => 'selected',
398 :mail_notification => 'selected',
388 :notified_project_ids => [1, 2]
399 :notified_project_ids => [1, 2]
389 }
400 }
390 u = User.find(2)
401 u = User.find(2)
391 assert_equal 'selected', u.mail_notification
402 assert_equal 'selected', u.mail_notification
392 assert_equal [1, 2], u.notified_projects_ids.sort
403 assert_equal [1, 2], u.notified_projects_ids.sort
393 end
404 end
394
405
395 def test_update_status_should_not_update_attributes
406 def test_update_status_should_not_update_attributes
396 user = User.find(2)
407 user = User.find(2)
397 user.pref[:no_self_notified] = '1'
408 user.pref[:no_self_notified] = '1'
398 user.pref.save
409 user.pref.save
399
410
400 put :update, :id => 2, :user => {:status => 3}
411 put :update, :id => 2, :user => {:status => 3}
401 assert_response 302
412 assert_response 302
402 user = User.find(2)
413 user = User.find(2)
403 assert_equal 3, user.status
414 assert_equal 3, user.status
404 assert_equal '1', user.pref[:no_self_notified]
415 assert_equal '1', user.pref[:no_self_notified]
405 end
416 end
406
417
407 def test_destroy
418 def test_destroy
408 assert_difference 'User.count', -1 do
419 assert_difference 'User.count', -1 do
409 delete :destroy, :id => 2
420 delete :destroy, :id => 2
410 end
421 end
411 assert_redirected_to '/users'
422 assert_redirected_to '/users'
412 assert_nil User.find_by_id(2)
423 assert_nil User.find_by_id(2)
413 end
424 end
414
425
415 def test_destroy_should_be_denied_for_non_admin_users
426 def test_destroy_should_be_denied_for_non_admin_users
416 @request.session[:user_id] = 3
427 @request.session[:user_id] = 3
417
428
418 assert_no_difference 'User.count' do
429 assert_no_difference 'User.count' do
419 get :destroy, :id => 2
430 get :destroy, :id => 2
420 end
431 end
421 assert_response 403
432 assert_response 403
422 end
433 end
423
434
424 def test_destroy_should_redirect_to_back_url_param
435 def test_destroy_should_redirect_to_back_url_param
425 assert_difference 'User.count', -1 do
436 assert_difference 'User.count', -1 do
426 delete :destroy, :id => 2, :back_url => '/users?name=foo'
437 delete :destroy, :id => 2, :back_url => '/users?name=foo'
427 end
438 end
428 assert_redirected_to '/users?name=foo'
439 assert_redirected_to '/users?name=foo'
429 end
440 end
430 end
441 end
@@ -1,959 +1,961
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 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 WikiControllerTest < ActionController::TestCase
20 class WikiControllerTest < ActionController::TestCase
21 fixtures :projects, :users, :roles, :members, :member_roles,
21 fixtures :projects, :users, :roles, :members, :member_roles,
22 :enabled_modules, :wikis, :wiki_pages, :wiki_contents,
22 :enabled_modules, :wikis, :wiki_pages, :wiki_contents,
23 :wiki_content_versions, :attachments,
23 :wiki_content_versions, :attachments,
24 :issues, :issue_statuses
24 :issues, :issue_statuses
25
25
26 def setup
26 def setup
27 User.current = nil
27 User.current = nil
28 end
28 end
29
29
30 def test_show_start_page
30 def test_show_start_page
31 get :show, :project_id => 'ecookbook'
31 get :show, :project_id => 'ecookbook'
32 assert_response :success
32 assert_response :success
33 assert_template 'show'
33 assert_template 'show'
34 assert_select 'h1', :text => /CookBook documentation/
34 assert_select 'h1', :text => /CookBook documentation/
35
35
36 # child_pages macro
36 # child_pages macro
37 assert_select 'ul.pages-hierarchy>li>a[href=?]', '/projects/ecookbook/wiki/Page_with_an_inline_image',
37 assert_select 'ul.pages-hierarchy>li>a[href=?]', '/projects/ecookbook/wiki/Page_with_an_inline_image',
38 :text => 'Page with an inline image'
38 :text => 'Page with an inline image'
39 end
39 end
40
40
41 def test_export_link
41 def test_export_link
42 Role.anonymous.add_permission! :export_wiki_pages
42 Role.anonymous.add_permission! :export_wiki_pages
43 get :show, :project_id => 'ecookbook'
43 get :show, :project_id => 'ecookbook'
44 assert_response :success
44 assert_response :success
45 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation.txt'
45 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation.txt'
46 end
46 end
47
47
48 def test_show_page_with_name
48 def test_show_page_with_name
49 get :show, :project_id => 1, :id => 'Another_page'
49 get :show, :project_id => 1, :id => 'Another_page'
50 assert_response :success
50 assert_response :success
51 assert_template 'show'
51 assert_template 'show'
52 assert_select 'h1', :text => /Another page/
52 assert_select 'h1', :text => /Another page/
53 # Included page with an inline image
53 # Included page with an inline image
54 assert_select 'p', :text => /This is an inline image/
54 assert_select 'p', :text => /This is an inline image/
55 assert_select 'img[src=?][alt=?]', '/attachments/download/3/logo.gif', 'This is a logo'
55 assert_select 'img[src=?][alt=?]', '/attachments/download/3/logo.gif', 'This is a logo'
56 end
56 end
57
57
58 def test_show_old_version
58 def test_show_old_version
59 with_settings :default_language => 'en' do
59 with_settings :default_language => 'en' do
60 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'
60 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'
61 end
61 end
62 assert_response :success
62 assert_response :success
63 assert_template 'show'
63 assert_template 'show'
64
64
65 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/1', :text => /Previous/
65 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/1', :text => /Previous/
66 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/diff', :text => /diff/
66 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/diff', :text => /diff/
67 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/3', :text => /Next/
67 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/3', :text => /Next/
68 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
68 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
69 end
69 end
70
70
71 def test_show_old_version_with_attachments
71 def test_show_old_version_with_attachments
72 page = WikiPage.find(4)
72 page = WikiPage.find(4)
73 assert page.attachments.any?
73 assert page.attachments.any?
74 content = page.content
74 content = page.content
75 content.text = "update"
75 content.text = "update"
76 content.save!
76 content.save!
77
77
78 get :show, :project_id => 'ecookbook', :id => page.title, :version => '1'
78 get :show, :project_id => 'ecookbook', :id => page.title, :version => '1'
79 assert_kind_of WikiContent::Version, assigns(:content)
79 assert_kind_of WikiContent::Version, assigns(:content)
80 assert_response :success
80 assert_response :success
81 assert_template 'show'
81 assert_template 'show'
82 end
82 end
83
83
84 def test_show_old_version_without_permission_should_be_denied
84 def test_show_old_version_without_permission_should_be_denied
85 Role.anonymous.remove_permission! :view_wiki_edits
85 Role.anonymous.remove_permission! :view_wiki_edits
86
86
87 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'
87 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'
88 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fprojects%2Fecookbook%2Fwiki%2FCookBook_documentation%2F2'
88 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fprojects%2Fecookbook%2Fwiki%2FCookBook_documentation%2F2'
89 end
89 end
90
90
91 def test_show_first_version
91 def test_show_first_version
92 with_settings :default_language => 'en' do
92 with_settings :default_language => 'en' do
93 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '1'
93 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '1'
94 end
94 end
95 assert_response :success
95 assert_response :success
96 assert_template 'show'
96 assert_template 'show'
97
97
98 assert_select 'a', :text => /Previous/, :count => 0
98 assert_select 'a', :text => /Previous/, :count => 0
99 assert_select 'a', :text => /diff/, :count => 0
99 assert_select 'a', :text => /diff/, :count => 0
100 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => /Next/
100 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => /Next/
101 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
101 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
102 end
102 end
103
103
104 def test_show_redirected_page
104 def test_show_redirected_page
105 WikiRedirect.create!(:wiki_id => 1, :title => 'Old_title', :redirects_to => 'Another_page')
105 WikiRedirect.create!(:wiki_id => 1, :title => 'Old_title', :redirects_to => 'Another_page')
106
106
107 get :show, :project_id => 'ecookbook', :id => 'Old_title'
107 get :show, :project_id => 'ecookbook', :id => 'Old_title'
108 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
108 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
109 end
109 end
110
110
111 def test_show_with_sidebar
111 def test_show_with_sidebar
112 page = Project.find(1).wiki.pages.new(:title => 'Sidebar')
112 page = Project.find(1).wiki.pages.new(:title => 'Sidebar')
113 page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
113 page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
114 page.save!
114 page.save!
115
115
116 get :show, :project_id => 1, :id => 'Another_page'
116 get :show, :project_id => 1, :id => 'Another_page'
117 assert_response :success
117 assert_response :success
118 assert_select 'div#sidebar', :text => /Side bar content for test_show_with_sidebar/
118 assert_select 'div#sidebar', :text => /Side bar content for test_show_with_sidebar/
119 end
119 end
120
120
121 def test_show_should_display_section_edit_links
121 def test_show_should_display_section_edit_links
122 @request.session[:user_id] = 2
122 @request.session[:user_id] = 2
123 get :show, :project_id => 1, :id => 'Page with sections'
123 get :show, :project_id => 1, :id => 'Page with sections'
124
124
125 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=1', 0
125 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=1', 0
126 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
126 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
127 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=3'
127 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=3'
128 end
128 end
129
129
130 def test_show_current_version_should_display_section_edit_links
130 def test_show_current_version_should_display_section_edit_links
131 @request.session[:user_id] = 2
131 @request.session[:user_id] = 2
132 get :show, :project_id => 1, :id => 'Page with sections', :version => 3
132 get :show, :project_id => 1, :id => 'Page with sections', :version => 3
133
133
134 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
134 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
135 end
135 end
136
136
137 def test_show_old_version_should_not_display_section_edit_links
137 def test_show_old_version_should_not_display_section_edit_links
138 @request.session[:user_id] = 2
138 @request.session[:user_id] = 2
139 get :show, :project_id => 1, :id => 'Page with sections', :version => 2
139 get :show, :project_id => 1, :id => 'Page with sections', :version => 2
140
140
141 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2', 0
141 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Page_with_sections/edit?section=2', 0
142 end
142 end
143
143
144 def test_show_unexistent_page_without_edit_right
144 def test_show_unexistent_page_without_edit_right
145 get :show, :project_id => 1, :id => 'Unexistent page'
145 get :show, :project_id => 1, :id => 'Unexistent page'
146 assert_response 404
146 assert_response 404
147 end
147 end
148
148
149 def test_show_unexistent_page_with_edit_right
149 def test_show_unexistent_page_with_edit_right
150 @request.session[:user_id] = 2
150 @request.session[:user_id] = 2
151 get :show, :project_id => 1, :id => 'Unexistent page'
151 get :show, :project_id => 1, :id => 'Unexistent page'
152 assert_response :success
152 assert_response :success
153 assert_template 'edit'
153 assert_template 'edit'
154 end
154 end
155
155
156 def test_show_specific_version_of_an_unexistent_page_without_edit_right
156 def test_show_specific_version_of_an_unexistent_page_without_edit_right
157 get :show, :project_id => 1, :id => 'Unexistent page', :version => 1
157 get :show, :project_id => 1, :id => 'Unexistent page', :version => 1
158 assert_response 404
158 assert_response 404
159 end
159 end
160
160
161 def test_show_unexistent_page_with_parent_should_preselect_parent
161 def test_show_unexistent_page_with_parent_should_preselect_parent
162 @request.session[:user_id] = 2
162 @request.session[:user_id] = 2
163 get :show, :project_id => 1, :id => 'Unexistent page', :parent => 'Another_page'
163 get :show, :project_id => 1, :id => 'Unexistent page', :parent => 'Another_page'
164 assert_response :success
164 assert_response :success
165 assert_template 'edit'
165 assert_template 'edit'
166 assert_select 'select[name=?] option[value="2"][selected=selected]', 'wiki_page[parent_id]'
166 assert_select 'select[name=?] option[value="2"][selected=selected]', 'wiki_page[parent_id]'
167 end
167 end
168
168
169 def test_show_should_not_show_history_without_permission
169 def test_show_should_not_show_history_without_permission
170 Role.anonymous.remove_permission! :view_wiki_edits
170 Role.anonymous.remove_permission! :view_wiki_edits
171 get :show, :project_id => 1, :id => 'Page with sections', :version => 2
171 get :show, :project_id => 1, :id => 'Page with sections', :version => 2
172
172
173 assert_response 302
173 assert_response 302
174 end
174 end
175
175
176 def test_show_page_without_content_should_display_the_edit_form
176 def test_show_page_without_content_should_display_the_edit_form
177 @request.session[:user_id] = 2
177 @request.session[:user_id] = 2
178 WikiPage.create!(:title => 'NoContent', :wiki => Project.find(1).wiki)
178 WikiPage.create!(:title => 'NoContent', :wiki => Project.find(1).wiki)
179
179
180 get :show, :project_id => 1, :id => 'NoContent'
180 get :show, :project_id => 1, :id => 'NoContent'
181 assert_response :success
181 assert_response :success
182 assert_template 'edit'
182 assert_template 'edit'
183 assert_select 'textarea[name=?]', 'content[text]'
183 assert_select 'textarea[name=?]', 'content[text]'
184 end
184 end
185
185
186 def test_create_page
186 def test_create_page
187 @request.session[:user_id] = 2
187 @request.session[:user_id] = 2
188 assert_difference 'WikiPage.count' do
188 assert_difference 'WikiPage.count' do
189 assert_difference 'WikiContent.count' do
189 assert_difference 'WikiContent.count' do
190 put :update, :project_id => 1,
190 put :update, :project_id => 1,
191 :id => 'New page',
191 :id => 'New page',
192 :content => {:comments => 'Created the page',
192 :content => {:comments => 'Created the page',
193 :text => "h1. New page\n\nThis is a new page",
193 :text => "h1. New page\n\nThis is a new page",
194 :version => 0}
194 :version => 0}
195 end
195 end
196 end
196 end
197 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'New_page'
197 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'New_page'
198 page = Project.find(1).wiki.find_page('New page')
198 page = Project.find(1).wiki.find_page('New page')
199 assert !page.new_record?
199 assert !page.new_record?
200 assert_not_nil page.content
200 assert_not_nil page.content
201 assert_nil page.parent
201 assert_nil page.parent
202 assert_equal 'Created the page', page.content.comments
202 assert_equal 'Created the page', page.content.comments
203 end
203 end
204
204
205 def test_create_page_with_attachments
205 def test_create_page_with_attachments
206 @request.session[:user_id] = 2
206 @request.session[:user_id] = 2
207 assert_difference 'WikiPage.count' do
207 assert_difference 'WikiPage.count' do
208 assert_difference 'Attachment.count' do
208 assert_difference 'Attachment.count' do
209 put :update, :project_id => 1,
209 put :update, :project_id => 1,
210 :id => 'New page',
210 :id => 'New page',
211 :content => {:comments => 'Created the page',
211 :content => {:comments => 'Created the page',
212 :text => "h1. New page\n\nThis is a new page",
212 :text => "h1. New page\n\nThis is a new page",
213 :version => 0},
213 :version => 0},
214 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
214 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
215 end
215 end
216 end
216 end
217 page = Project.find(1).wiki.find_page('New page')
217 page = Project.find(1).wiki.find_page('New page')
218 assert_equal 1, page.attachments.count
218 assert_equal 1, page.attachments.count
219 assert_equal 'testfile.txt', page.attachments.first.filename
219 assert_equal 'testfile.txt', page.attachments.first.filename
220 end
220 end
221
221
222 def test_create_page_with_parent
222 def test_create_page_with_parent
223 @request.session[:user_id] = 2
223 @request.session[:user_id] = 2
224 assert_difference 'WikiPage.count' do
224 assert_difference 'WikiPage.count' do
225 put :update, :project_id => 1, :id => 'New page',
225 put :update, :project_id => 1, :id => 'New page',
226 :content => {:text => "h1. New page\n\nThis is a new page", :version => 0},
226 :content => {:text => "h1. New page\n\nThis is a new page", :version => 0},
227 :wiki_page => {:parent_id => 2}
227 :wiki_page => {:parent_id => 2}
228 end
228 end
229 page = Project.find(1).wiki.find_page('New page')
229 page = Project.find(1).wiki.find_page('New page')
230 assert_equal WikiPage.find(2), page.parent
230 assert_equal WikiPage.find(2), page.parent
231 end
231 end
232
232
233 def test_edit_page
233 def test_edit_page
234 @request.session[:user_id] = 2
234 @request.session[:user_id] = 2
235 get :edit, :project_id => 'ecookbook', :id => 'Another_page'
235 get :edit, :project_id => 'ecookbook', :id => 'Another_page'
236
236
237 assert_response :success
237 assert_response :success
238 assert_template 'edit'
238 assert_template 'edit'
239
239
240 assert_select 'textarea[name=?]', 'content[text]',
240 assert_select 'textarea[name=?]', 'content[text]',
241 :text => WikiPage.find_by_title('Another_page').content.text
241 :text => WikiPage.find_by_title('Another_page').content.text
242 end
242 end
243
243
244 def test_edit_section
244 def test_edit_section
245 @request.session[:user_id] = 2
245 @request.session[:user_id] = 2
246 get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 2
246 get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 2
247
247
248 assert_response :success
248 assert_response :success
249 assert_template 'edit'
249 assert_template 'edit'
250
250
251 page = WikiPage.find_by_title('Page_with_sections')
251 page = WikiPage.find_by_title('Page_with_sections')
252 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
252 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
253
253
254 assert_select 'textarea[name=?]', 'content[text]', :text => section
254 assert_select 'textarea[name=?]', 'content[text]', :text => section
255 assert_select 'input[name=section][type=hidden][value="2"]'
255 assert_select 'input[name=section][type=hidden][value="2"]'
256 assert_select 'input[name=section_hash][type=hidden][value=?]', hash
256 assert_select 'input[name=section_hash][type=hidden][value=?]', hash
257 end
257 end
258
258
259 def test_edit_invalid_section_should_respond_with_404
259 def test_edit_invalid_section_should_respond_with_404
260 @request.session[:user_id] = 2
260 @request.session[:user_id] = 2
261 get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 10
261 get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 10
262
262
263 assert_response 404
263 assert_response 404
264 end
264 end
265
265
266 def test_update_page
266 def test_update_page
267 @request.session[:user_id] = 2
267 @request.session[:user_id] = 2
268 assert_no_difference 'WikiPage.count' do
268 assert_no_difference 'WikiPage.count' do
269 assert_no_difference 'WikiContent.count' do
269 assert_no_difference 'WikiContent.count' do
270 assert_difference 'WikiContent::Version.count' do
270 assert_difference 'WikiContent::Version.count' do
271 put :update, :project_id => 1,
271 put :update, :project_id => 1,
272 :id => 'Another_page',
272 :id => 'Another_page',
273 :content => {
273 :content => {
274 :comments => "my comments",
274 :comments => "my comments",
275 :text => "edited",
275 :text => "edited",
276 :version => 1
276 :version => 1
277 }
277 }
278 end
278 end
279 end
279 end
280 end
280 end
281 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
281 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
282
282
283 page = Wiki.find(1).pages.find_by_title('Another_page')
283 page = Wiki.find(1).pages.find_by_title('Another_page')
284 assert_equal "edited", page.content.text
284 assert_equal "edited", page.content.text
285 assert_equal 2, page.content.version
285 assert_equal 2, page.content.version
286 assert_equal "my comments", page.content.comments
286 assert_equal "my comments", page.content.comments
287 end
287 end
288
288
289 def test_update_page_with_parent
289 def test_update_page_with_parent
290 @request.session[:user_id] = 2
290 @request.session[:user_id] = 2
291 assert_no_difference 'WikiPage.count' do
291 assert_no_difference 'WikiPage.count' do
292 assert_no_difference 'WikiContent.count' do
292 assert_no_difference 'WikiContent.count' do
293 assert_difference 'WikiContent::Version.count' do
293 assert_difference 'WikiContent::Version.count' do
294 put :update, :project_id => 1,
294 put :update, :project_id => 1,
295 :id => 'Another_page',
295 :id => 'Another_page',
296 :content => {
296 :content => {
297 :comments => "my comments",
297 :comments => "my comments",
298 :text => "edited",
298 :text => "edited",
299 :version => 1
299 :version => 1
300 },
300 },
301 :wiki_page => {:parent_id => '1'}
301 :wiki_page => {:parent_id => '1'}
302 end
302 end
303 end
303 end
304 end
304 end
305 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
305 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
306
306
307 page = Wiki.find(1).pages.find_by_title('Another_page')
307 page = Wiki.find(1).pages.find_by_title('Another_page')
308 assert_equal "edited", page.content.text
308 assert_equal "edited", page.content.text
309 assert_equal 2, page.content.version
309 assert_equal 2, page.content.version
310 assert_equal "my comments", page.content.comments
310 assert_equal "my comments", page.content.comments
311 assert_equal WikiPage.find(1), page.parent
311 assert_equal WikiPage.find(1), page.parent
312 end
312 end
313
313
314 def test_update_page_with_failure
314 def test_update_page_with_failure
315 @request.session[:user_id] = 2
315 @request.session[:user_id] = 2
316 assert_no_difference 'WikiPage.count' do
316 assert_no_difference 'WikiPage.count' do
317 assert_no_difference 'WikiContent.count' do
317 assert_no_difference 'WikiContent.count' do
318 assert_no_difference 'WikiContent::Version.count' do
318 assert_no_difference 'WikiContent::Version.count' do
319 put :update, :project_id => 1,
319 put :update, :project_id => 1,
320 :id => 'Another_page',
320 :id => 'Another_page',
321 :content => {
321 :content => {
322 :comments => 'a' * 300, # failure here, comment is too long
322 :comments => 'a' * 300, # failure here, comment is too long
323 :text => 'edited',
323 :text => 'edited'
324 :version => 1
324 },
325 :wiki_page => {
326 :parent_id => ""
325 }
327 }
326 end
327 end
328 end
328 end
329 end
330 end
329 assert_response :success
331 assert_response :success
330 assert_template 'edit'
332 assert_template 'edit'
331
333
332 assert_select_error /Comment is too long/
334 assert_select_error /Comment is too long/
333 assert_select 'textarea#content_text', :text => "edited"
335 assert_select 'textarea#content_text', :text => "edited"
334 assert_select 'input#content_version[value="1"]'
336 assert_select 'input#content_version[value="1"]'
335 end
337 end
336
338
337 def test_update_page_with_parent_change_only_should_not_create_content_version
339 def test_update_page_with_parent_change_only_should_not_create_content_version
338 @request.session[:user_id] = 2
340 @request.session[:user_id] = 2
339 assert_no_difference 'WikiPage.count' do
341 assert_no_difference 'WikiPage.count' do
340 assert_no_difference 'WikiContent.count' do
342 assert_no_difference 'WikiContent.count' do
341 assert_no_difference 'WikiContent::Version.count' do
343 assert_no_difference 'WikiContent::Version.count' do
342 put :update, :project_id => 1,
344 put :update, :project_id => 1,
343 :id => 'Another_page',
345 :id => 'Another_page',
344 :content => {
346 :content => {
345 :comments => '',
347 :comments => '',
346 :text => Wiki.find(1).find_page('Another_page').content.text,
348 :text => Wiki.find(1).find_page('Another_page').content.text,
347 :version => 1
349 :version => 1
348 },
350 },
349 :wiki_page => {:parent_id => '1'}
351 :wiki_page => {:parent_id => '1'}
350 end
352 end
351 end
353 end
352 end
354 end
353 page = Wiki.find(1).pages.find_by_title('Another_page')
355 page = Wiki.find(1).pages.find_by_title('Another_page')
354 assert_equal 1, page.content.version
356 assert_equal 1, page.content.version
355 assert_equal WikiPage.find(1), page.parent
357 assert_equal WikiPage.find(1), page.parent
356 end
358 end
357
359
358 def test_update_page_with_attachments_only_should_not_create_content_version
360 def test_update_page_with_attachments_only_should_not_create_content_version
359 @request.session[:user_id] = 2
361 @request.session[:user_id] = 2
360 assert_no_difference 'WikiPage.count' do
362 assert_no_difference 'WikiPage.count' do
361 assert_no_difference 'WikiContent.count' do
363 assert_no_difference 'WikiContent.count' do
362 assert_no_difference 'WikiContent::Version.count' do
364 assert_no_difference 'WikiContent::Version.count' do
363 assert_difference 'Attachment.count' do
365 assert_difference 'Attachment.count' do
364 put :update, :project_id => 1,
366 put :update, :project_id => 1,
365 :id => 'Another_page',
367 :id => 'Another_page',
366 :content => {
368 :content => {
367 :comments => '',
369 :comments => '',
368 :text => Wiki.find(1).find_page('Another_page').content.text,
370 :text => Wiki.find(1).find_page('Another_page').content.text,
369 :version => 1
371 :version => 1
370 },
372 },
371 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
373 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
372 end
374 end
373 end
375 end
374 end
376 end
375 end
377 end
376 page = Wiki.find(1).pages.find_by_title('Another_page')
378 page = Wiki.find(1).pages.find_by_title('Another_page')
377 assert_equal 1, page.content.version
379 assert_equal 1, page.content.version
378 end
380 end
379
381
380 def test_update_stale_page_should_not_raise_an_error
382 def test_update_stale_page_should_not_raise_an_error
381 @request.session[:user_id] = 2
383 @request.session[:user_id] = 2
382 c = Wiki.find(1).find_page('Another_page').content
384 c = Wiki.find(1).find_page('Another_page').content
383 c.text = 'Previous text'
385 c.text = 'Previous text'
384 c.save!
386 c.save!
385 assert_equal 2, c.version
387 assert_equal 2, c.version
386
388
387 assert_no_difference 'WikiPage.count' do
389 assert_no_difference 'WikiPage.count' do
388 assert_no_difference 'WikiContent.count' do
390 assert_no_difference 'WikiContent.count' do
389 assert_no_difference 'WikiContent::Version.count' do
391 assert_no_difference 'WikiContent::Version.count' do
390 put :update, :project_id => 1,
392 put :update, :project_id => 1,
391 :id => 'Another_page',
393 :id => 'Another_page',
392 :content => {
394 :content => {
393 :comments => 'My comments',
395 :comments => 'My comments',
394 :text => 'Text should not be lost',
396 :text => 'Text should not be lost',
395 :version => 1
397 :version => 1
396 }
398 }
397 end
399 end
398 end
400 end
399 end
401 end
400 assert_response :success
402 assert_response :success
401 assert_template 'edit'
403 assert_template 'edit'
402 assert_select 'div.error', :text => /Data has been updated by another user/
404 assert_select 'div.error', :text => /Data has been updated by another user/
403 assert_select 'textarea[name=?]', 'content[text]', :text => /Text should not be lost/
405 assert_select 'textarea[name=?]', 'content[text]', :text => /Text should not be lost/
404 assert_select 'input[name=?][value=?]', 'content[comments]', 'My comments'
406 assert_select 'input[name=?][value=?]', 'content[comments]', 'My comments'
405
407
406 c.reload
408 c.reload
407 assert_equal 'Previous text', c.text
409 assert_equal 'Previous text', c.text
408 assert_equal 2, c.version
410 assert_equal 2, c.version
409 end
411 end
410
412
411 def test_update_page_without_content_should_create_content
413 def test_update_page_without_content_should_create_content
412 @request.session[:user_id] = 2
414 @request.session[:user_id] = 2
413 page = WikiPage.create!(:title => 'NoContent', :wiki => Project.find(1).wiki)
415 page = WikiPage.create!(:title => 'NoContent', :wiki => Project.find(1).wiki)
414
416
415 assert_no_difference 'WikiPage.count' do
417 assert_no_difference 'WikiPage.count' do
416 assert_difference 'WikiContent.count' do
418 assert_difference 'WikiContent.count' do
417 put :update, :project_id => 1, :id => 'NoContent', :content => {:text => 'Some content'}
419 put :update, :project_id => 1, :id => 'NoContent', :content => {:text => 'Some content'}
418 assert_response 302
420 assert_response 302
419 end
421 end
420 end
422 end
421 assert_equal 'Some content', page.reload.content.text
423 assert_equal 'Some content', page.reload.content.text
422 end
424 end
423
425
424 def test_update_section
426 def test_update_section
425 @request.session[:user_id] = 2
427 @request.session[:user_id] = 2
426 page = WikiPage.find_by_title('Page_with_sections')
428 page = WikiPage.find_by_title('Page_with_sections')
427 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
429 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
428 text = page.content.text
430 text = page.content.text
429
431
430 assert_no_difference 'WikiPage.count' do
432 assert_no_difference 'WikiPage.count' do
431 assert_no_difference 'WikiContent.count' do
433 assert_no_difference 'WikiContent.count' do
432 assert_difference 'WikiContent::Version.count' do
434 assert_difference 'WikiContent::Version.count' do
433 put :update, :project_id => 1, :id => 'Page_with_sections',
435 put :update, :project_id => 1, :id => 'Page_with_sections',
434 :content => {
436 :content => {
435 :text => "New section content",
437 :text => "New section content",
436 :version => 3
438 :version => 3
437 },
439 },
438 :section => 2,
440 :section => 2,
439 :section_hash => hash
441 :section_hash => hash
440 end
442 end
441 end
443 end
442 end
444 end
443 assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections#section-2'
445 assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections#section-2'
444 assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.reload.content.text
446 assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.reload.content.text
445 end
447 end
446
448
447 def test_update_section_should_allow_stale_page_update
449 def test_update_section_should_allow_stale_page_update
448 @request.session[:user_id] = 2
450 @request.session[:user_id] = 2
449 page = WikiPage.find_by_title('Page_with_sections')
451 page = WikiPage.find_by_title('Page_with_sections')
450 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
452 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
451 text = page.content.text
453 text = page.content.text
452
454
453 assert_no_difference 'WikiPage.count' do
455 assert_no_difference 'WikiPage.count' do
454 assert_no_difference 'WikiContent.count' do
456 assert_no_difference 'WikiContent.count' do
455 assert_difference 'WikiContent::Version.count' do
457 assert_difference 'WikiContent::Version.count' do
456 put :update, :project_id => 1, :id => 'Page_with_sections',
458 put :update, :project_id => 1, :id => 'Page_with_sections',
457 :content => {
459 :content => {
458 :text => "New section content",
460 :text => "New section content",
459 :version => 2 # Current version is 3
461 :version => 2 # Current version is 3
460 },
462 },
461 :section => 2,
463 :section => 2,
462 :section_hash => hash
464 :section_hash => hash
463 end
465 end
464 end
466 end
465 end
467 end
466 assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections#section-2'
468 assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections#section-2'
467 page.reload
469 page.reload
468 assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.content.text
470 assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.content.text
469 assert_equal 4, page.content.version
471 assert_equal 4, page.content.version
470 end
472 end
471
473
472 def test_update_section_should_not_allow_stale_section_update
474 def test_update_section_should_not_allow_stale_section_update
473 @request.session[:user_id] = 2
475 @request.session[:user_id] = 2
474
476
475 assert_no_difference 'WikiPage.count' do
477 assert_no_difference 'WikiPage.count' do
476 assert_no_difference 'WikiContent.count' do
478 assert_no_difference 'WikiContent.count' do
477 assert_no_difference 'WikiContent::Version.count' do
479 assert_no_difference 'WikiContent::Version.count' do
478 put :update, :project_id => 1, :id => 'Page_with_sections',
480 put :update, :project_id => 1, :id => 'Page_with_sections',
479 :content => {
481 :content => {
480 :comments => 'My comments',
482 :comments => 'My comments',
481 :text => "Text should not be lost",
483 :text => "Text should not be lost",
482 :version => 3
484 :version => 3
483 },
485 },
484 :section => 2,
486 :section => 2,
485 :section_hash => Digest::MD5.hexdigest("wrong hash")
487 :section_hash => Digest::MD5.hexdigest("wrong hash")
486 end
488 end
487 end
489 end
488 end
490 end
489 assert_response :success
491 assert_response :success
490 assert_template 'edit'
492 assert_template 'edit'
491 assert_select 'div.error', :text => /Data has been updated by another user/
493 assert_select 'div.error', :text => /Data has been updated by another user/
492 assert_select 'textarea[name=?]', 'content[text]', :text => /Text should not be lost/
494 assert_select 'textarea[name=?]', 'content[text]', :text => /Text should not be lost/
493 assert_select 'input[name=?][value=?]', 'content[comments]', 'My comments'
495 assert_select 'input[name=?][value=?]', 'content[comments]', 'My comments'
494 end
496 end
495
497
496 def test_preview
498 def test_preview
497 @request.session[:user_id] = 2
499 @request.session[:user_id] = 2
498 xhr :post, :preview, :project_id => 1, :id => 'CookBook_documentation',
500 xhr :post, :preview, :project_id => 1, :id => 'CookBook_documentation',
499 :content => { :comments => '',
501 :content => { :comments => '',
500 :text => 'this is a *previewed text*',
502 :text => 'this is a *previewed text*',
501 :version => 3 }
503 :version => 3 }
502 assert_response :success
504 assert_response :success
503 assert_template 'common/_preview'
505 assert_template 'common/_preview'
504 assert_select 'strong', :text => /previewed text/
506 assert_select 'strong', :text => /previewed text/
505 end
507 end
506
508
507 def test_preview_new_page
509 def test_preview_new_page
508 @request.session[:user_id] = 2
510 @request.session[:user_id] = 2
509 xhr :post, :preview, :project_id => 1, :id => 'New page',
511 xhr :post, :preview, :project_id => 1, :id => 'New page',
510 :content => { :text => 'h1. New page',
512 :content => { :text => 'h1. New page',
511 :comments => '',
513 :comments => '',
512 :version => 0 }
514 :version => 0 }
513 assert_response :success
515 assert_response :success
514 assert_template 'common/_preview'
516 assert_template 'common/_preview'
515 assert_select 'h1', :text => /New page/
517 assert_select 'h1', :text => /New page/
516 end
518 end
517
519
518 def test_history
520 def test_history
519 @request.session[:user_id] = 2
521 @request.session[:user_id] = 2
520 get :history, :project_id => 'ecookbook', :id => 'CookBook_documentation'
522 get :history, :project_id => 'ecookbook', :id => 'CookBook_documentation'
521 assert_response :success
523 assert_response :success
522 assert_template 'history'
524 assert_template 'history'
523 assert_not_nil assigns(:versions)
525 assert_not_nil assigns(:versions)
524 assert_equal 3, assigns(:versions).size
526 assert_equal 3, assigns(:versions).size
525
527
526 assert_select "input[type=submit][name=commit]"
528 assert_select "input[type=submit][name=commit]"
527 assert_select 'td' do
529 assert_select 'td' do
528 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => '2'
530 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => '2'
529 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/annotate', :text => 'Annotate'
531 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/annotate', :text => 'Annotate'
530 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => 'Delete'
532 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => 'Delete'
531 end
533 end
532 end
534 end
533
535
534 def test_history_with_one_version
536 def test_history_with_one_version
535 @request.session[:user_id] = 2
537 @request.session[:user_id] = 2
536 get :history, :project_id => 'ecookbook', :id => 'Another_page'
538 get :history, :project_id => 'ecookbook', :id => 'Another_page'
537 assert_response :success
539 assert_response :success
538 assert_template 'history'
540 assert_template 'history'
539 assert_not_nil assigns(:versions)
541 assert_not_nil assigns(:versions)
540 assert_equal 1, assigns(:versions).size
542 assert_equal 1, assigns(:versions).size
541 assert_select "input[type=submit][name=commit]", false
543 assert_select "input[type=submit][name=commit]", false
542 assert_select 'td' do
544 assert_select 'td' do
543 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => '1'
545 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => '1'
544 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1/annotate', :text => 'Annotate'
546 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1/annotate', :text => 'Annotate'
545 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => 'Delete', :count => 0
547 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => 'Delete', :count => 0
546 end
548 end
547 end
549 end
548
550
549 def test_diff
551 def test_diff
550 content = WikiPage.find(1).content
552 content = WikiPage.find(1).content
551 assert_difference 'WikiContent::Version.count', 2 do
553 assert_difference 'WikiContent::Version.count', 2 do
552 content.text = "Line removed\nThis is a sample text for testing diffs"
554 content.text = "Line removed\nThis is a sample text for testing diffs"
553 content.save!
555 content.save!
554 content.text = "This is a sample text for testing diffs\nLine added"
556 content.text = "This is a sample text for testing diffs\nLine added"
555 content.save!
557 content.save!
556 end
558 end
557
559
558 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => content.version, :version_from => (content.version - 1)
560 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => content.version, :version_from => (content.version - 1)
559 assert_response :success
561 assert_response :success
560 assert_template 'diff'
562 assert_template 'diff'
561 assert_select 'span.diff_out', :text => 'Line removed'
563 assert_select 'span.diff_out', :text => 'Line removed'
562 assert_select 'span.diff_in', :text => 'Line added'
564 assert_select 'span.diff_in', :text => 'Line added'
563 end
565 end
564
566
565 def test_diff_with_invalid_version_should_respond_with_404
567 def test_diff_with_invalid_version_should_respond_with_404
566 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => '99'
568 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => '99'
567 assert_response 404
569 assert_response 404
568 end
570 end
569
571
570 def test_diff_with_invalid_version_from_should_respond_with_404
572 def test_diff_with_invalid_version_from_should_respond_with_404
571 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => '99', :version_from => '98'
573 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => '99', :version_from => '98'
572 assert_response 404
574 assert_response 404
573 end
575 end
574
576
575 def test_annotate
577 def test_annotate
576 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => 2
578 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => 2
577 assert_response :success
579 assert_response :success
578 assert_template 'annotate'
580 assert_template 'annotate'
579
581
580 # Line 1
582 # Line 1
581 assert_select 'table.annotate tr:nth-child(1)' do
583 assert_select 'table.annotate tr:nth-child(1)' do
582 assert_select 'th.line-num', :text => '1'
584 assert_select 'th.line-num', :text => '1'
583 assert_select 'td.author', :text => /John Smith/
585 assert_select 'td.author', :text => /John Smith/
584 assert_select 'td', :text => /h1\. CookBook documentation/
586 assert_select 'td', :text => /h1\. CookBook documentation/
585 end
587 end
586
588
587 # Line 5
589 # Line 5
588 assert_select 'table.annotate tr:nth-child(5)' do
590 assert_select 'table.annotate tr:nth-child(5)' do
589 assert_select 'th.line-num', :text => '5'
591 assert_select 'th.line-num', :text => '5'
590 assert_select 'td.author', :text => /Redmine Admin/
592 assert_select 'td.author', :text => /Redmine Admin/
591 assert_select 'td', :text => /Some updated \[\[documentation\]\] here/
593 assert_select 'td', :text => /Some updated \[\[documentation\]\] here/
592 end
594 end
593 end
595 end
594
596
595 def test_annotate_with_invalid_version_should_respond_with_404
597 def test_annotate_with_invalid_version_should_respond_with_404
596 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => '99'
598 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => '99'
597 assert_response 404
599 assert_response 404
598 end
600 end
599
601
600 def test_get_rename
602 def test_get_rename
601 @request.session[:user_id] = 2
603 @request.session[:user_id] = 2
602 get :rename, :project_id => 1, :id => 'Another_page'
604 get :rename, :project_id => 1, :id => 'Another_page'
603 assert_response :success
605 assert_response :success
604 assert_template 'rename'
606 assert_template 'rename'
605
607
606 assert_select 'select[name=?]', 'wiki_page[parent_id]' do
608 assert_select 'select[name=?]', 'wiki_page[parent_id]' do
607 assert_select 'option[value=""]', :text => ''
609 assert_select 'option[value=""]', :text => ''
608 assert_select 'option[selected=selected]', 0
610 assert_select 'option[selected=selected]', 0
609 end
611 end
610 end
612 end
611
613
612 def test_get_rename_child_page
614 def test_get_rename_child_page
613 @request.session[:user_id] = 2
615 @request.session[:user_id] = 2
614 get :rename, :project_id => 1, :id => 'Child_1'
616 get :rename, :project_id => 1, :id => 'Child_1'
615 assert_response :success
617 assert_response :success
616 assert_template 'rename'
618 assert_template 'rename'
617
619
618 assert_select 'select[name=?]', 'wiki_page[parent_id]' do
620 assert_select 'select[name=?]', 'wiki_page[parent_id]' do
619 assert_select 'option[value=""]', :text => ''
621 assert_select 'option[value=""]', :text => ''
620 assert_select 'option[value="2"][selected=selected]', :text => /Another page/
622 assert_select 'option[value="2"][selected=selected]', :text => /Another page/
621 end
623 end
622 end
624 end
623
625
624 def test_rename_with_redirect
626 def test_rename_with_redirect
625 @request.session[:user_id] = 2
627 @request.session[:user_id] = 2
626 post :rename, :project_id => 1, :id => 'Another_page',
628 post :rename, :project_id => 1, :id => 'Another_page',
627 :wiki_page => { :title => 'Another renamed page',
629 :wiki_page => { :title => 'Another renamed page',
628 :redirect_existing_links => 1 }
630 :redirect_existing_links => 1 }
629 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
631 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
630 wiki = Project.find(1).wiki
632 wiki = Project.find(1).wiki
631 # Check redirects
633 # Check redirects
632 assert_not_nil wiki.find_page('Another page')
634 assert_not_nil wiki.find_page('Another page')
633 assert_nil wiki.find_page('Another page', :with_redirect => false)
635 assert_nil wiki.find_page('Another page', :with_redirect => false)
634 end
636 end
635
637
636 def test_rename_without_redirect
638 def test_rename_without_redirect
637 @request.session[:user_id] = 2
639 @request.session[:user_id] = 2
638 post :rename, :project_id => 1, :id => 'Another_page',
640 post :rename, :project_id => 1, :id => 'Another_page',
639 :wiki_page => { :title => 'Another renamed page',
641 :wiki_page => { :title => 'Another renamed page',
640 :redirect_existing_links => "0" }
642 :redirect_existing_links => "0" }
641 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
643 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
642 wiki = Project.find(1).wiki
644 wiki = Project.find(1).wiki
643 # Check that there's no redirects
645 # Check that there's no redirects
644 assert_nil wiki.find_page('Another page')
646 assert_nil wiki.find_page('Another page')
645 end
647 end
646
648
647 def test_rename_with_parent_assignment
649 def test_rename_with_parent_assignment
648 @request.session[:user_id] = 2
650 @request.session[:user_id] = 2
649 post :rename, :project_id => 1, :id => 'Another_page',
651 post :rename, :project_id => 1, :id => 'Another_page',
650 :wiki_page => { :title => 'Another page', :redirect_existing_links => "0", :parent_id => '4' }
652 :wiki_page => { :title => 'Another page', :redirect_existing_links => "0", :parent_id => '4' }
651 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
653 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
652 assert_equal WikiPage.find(4), WikiPage.find_by_title('Another_page').parent
654 assert_equal WikiPage.find(4), WikiPage.find_by_title('Another_page').parent
653 end
655 end
654
656
655 def test_rename_with_parent_unassignment
657 def test_rename_with_parent_unassignment
656 @request.session[:user_id] = 2
658 @request.session[:user_id] = 2
657 post :rename, :project_id => 1, :id => 'Child_1',
659 post :rename, :project_id => 1, :id => 'Child_1',
658 :wiki_page => { :title => 'Child 1', :redirect_existing_links => "0", :parent_id => '' }
660 :wiki_page => { :title => 'Child 1', :redirect_existing_links => "0", :parent_id => '' }
659 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Child_1'
661 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Child_1'
660 assert_nil WikiPage.find_by_title('Child_1').parent
662 assert_nil WikiPage.find_by_title('Child_1').parent
661 end
663 end
662
664
663 def test_get_rename_should_show_target_projects_list
665 def test_get_rename_should_show_target_projects_list
664 @request.session[:user_id] = 2
666 @request.session[:user_id] = 2
665 project = Project.find(5)
667 project = Project.find(5)
666 project.enable_module! :wiki
668 project.enable_module! :wiki
667
669
668 get :rename, :project_id => 1, :id => 'Another_page'
670 get :rename, :project_id => 1, :id => 'Another_page'
669 assert_response :success
671 assert_response :success
670 assert_template 'rename'
672 assert_template 'rename'
671
673
672 assert_select 'select[name=?]', 'wiki_page[wiki_id]' do
674 assert_select 'select[name=?]', 'wiki_page[wiki_id]' do
673 assert_select 'option', 2
675 assert_select 'option', 2
674 assert_select 'option[value=?][selected=selected]', '1', :text => /eCookbook/
676 assert_select 'option[value=?][selected=selected]', '1', :text => /eCookbook/
675 assert_select 'option[value=?]', project.wiki.id.to_s, :text => /#{project.name}/
677 assert_select 'option[value=?]', project.wiki.id.to_s, :text => /#{project.name}/
676 end
678 end
677 end
679 end
678
680
679 def test_rename_with_move
681 def test_rename_with_move
680 @request.session[:user_id] = 2
682 @request.session[:user_id] = 2
681 project = Project.find(5)
683 project = Project.find(5)
682 project.enable_module! :wiki
684 project.enable_module! :wiki
683
685
684 post :rename, :project_id => 1, :id => 'Another_page',
686 post :rename, :project_id => 1, :id => 'Another_page',
685 :wiki_page => {
687 :wiki_page => {
686 :wiki_id => project.wiki.id.to_s,
688 :wiki_id => project.wiki.id.to_s,
687 :title => 'Another renamed page',
689 :title => 'Another renamed page',
688 :redirect_existing_links => 1
690 :redirect_existing_links => 1
689 }
691 }
690 assert_redirected_to '/projects/private-child/wiki/Another_renamed_page'
692 assert_redirected_to '/projects/private-child/wiki/Another_renamed_page'
691
693
692 page = WikiPage.find(2)
694 page = WikiPage.find(2)
693 assert_equal project.wiki.id, page.wiki_id
695 assert_equal project.wiki.id, page.wiki_id
694 end
696 end
695
697
696 def test_destroy_a_page_without_children_should_not_ask_confirmation
698 def test_destroy_a_page_without_children_should_not_ask_confirmation
697 @request.session[:user_id] = 2
699 @request.session[:user_id] = 2
698 delete :destroy, :project_id => 1, :id => 'Child_2'
700 delete :destroy, :project_id => 1, :id => 'Child_2'
699 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
701 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
700 end
702 end
701
703
702 def test_destroy_parent_should_ask_confirmation
704 def test_destroy_parent_should_ask_confirmation
703 @request.session[:user_id] = 2
705 @request.session[:user_id] = 2
704 assert_no_difference('WikiPage.count') do
706 assert_no_difference('WikiPage.count') do
705 delete :destroy, :project_id => 1, :id => 'Another_page'
707 delete :destroy, :project_id => 1, :id => 'Another_page'
706 end
708 end
707 assert_response :success
709 assert_response :success
708 assert_template 'destroy'
710 assert_template 'destroy'
709 assert_select 'form' do
711 assert_select 'form' do
710 assert_select 'input[name=todo][value=nullify]'
712 assert_select 'input[name=todo][value=nullify]'
711 assert_select 'input[name=todo][value=destroy]'
713 assert_select 'input[name=todo][value=destroy]'
712 assert_select 'input[name=todo][value=reassign]'
714 assert_select 'input[name=todo][value=reassign]'
713 end
715 end
714 end
716 end
715
717
716 def test_destroy_parent_with_nullify_should_delete_parent_only
718 def test_destroy_parent_with_nullify_should_delete_parent_only
717 @request.session[:user_id] = 2
719 @request.session[:user_id] = 2
718 assert_difference('WikiPage.count', -1) do
720 assert_difference('WikiPage.count', -1) do
719 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'nullify'
721 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'nullify'
720 end
722 end
721 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
723 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
722 assert_nil WikiPage.find_by_id(2)
724 assert_nil WikiPage.find_by_id(2)
723 end
725 end
724
726
725 def test_destroy_parent_with_cascade_should_delete_descendants
727 def test_destroy_parent_with_cascade_should_delete_descendants
726 @request.session[:user_id] = 2
728 @request.session[:user_id] = 2
727 assert_difference('WikiPage.count', -4) do
729 assert_difference('WikiPage.count', -4) do
728 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'destroy'
730 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'destroy'
729 end
731 end
730 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
732 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
731 assert_nil WikiPage.find_by_id(2)
733 assert_nil WikiPage.find_by_id(2)
732 assert_nil WikiPage.find_by_id(5)
734 assert_nil WikiPage.find_by_id(5)
733 end
735 end
734
736
735 def test_destroy_parent_with_reassign
737 def test_destroy_parent_with_reassign
736 @request.session[:user_id] = 2
738 @request.session[:user_id] = 2
737 assert_difference('WikiPage.count', -1) do
739 assert_difference('WikiPage.count', -1) do
738 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'reassign', :reassign_to_id => 1
740 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'reassign', :reassign_to_id => 1
739 end
741 end
740 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
742 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
741 assert_nil WikiPage.find_by_id(2)
743 assert_nil WikiPage.find_by_id(2)
742 assert_equal WikiPage.find(1), WikiPage.find_by_id(5).parent
744 assert_equal WikiPage.find(1), WikiPage.find_by_id(5).parent
743 end
745 end
744
746
745 def test_destroy_version
747 def test_destroy_version
746 @request.session[:user_id] = 2
748 @request.session[:user_id] = 2
747 assert_difference 'WikiContent::Version.count', -1 do
749 assert_difference 'WikiContent::Version.count', -1 do
748 assert_no_difference 'WikiContent.count' do
750 assert_no_difference 'WikiContent.count' do
749 assert_no_difference 'WikiPage.count' do
751 assert_no_difference 'WikiPage.count' do
750 delete :destroy_version, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => 2
752 delete :destroy_version, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => 2
751 assert_redirected_to '/projects/ecookbook/wiki/CookBook_documentation/history'
753 assert_redirected_to '/projects/ecookbook/wiki/CookBook_documentation/history'
752 end
754 end
753 end
755 end
754 end
756 end
755 end
757 end
756
758
757 def test_index
759 def test_index
758 get :index, :project_id => 'ecookbook'
760 get :index, :project_id => 'ecookbook'
759 assert_response :success
761 assert_response :success
760 assert_template 'index'
762 assert_template 'index'
761 pages = assigns(:pages)
763 pages = assigns(:pages)
762 assert_not_nil pages
764 assert_not_nil pages
763 assert_equal Project.find(1).wiki.pages.size, pages.size
765 assert_equal Project.find(1).wiki.pages.size, pages.size
764 assert_equal pages.first.content.updated_on, pages.first.updated_on
766 assert_equal pages.first.content.updated_on, pages.first.updated_on
765
767
766 assert_select 'ul.pages-hierarchy' do
768 assert_select 'ul.pages-hierarchy' do
767 assert_select 'li' do
769 assert_select 'li' do
768 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => 'CookBook documentation'
770 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => 'CookBook documentation'
769 assert_select 'ul li a[href=?]', '/projects/ecookbook/wiki/Page_with_an_inline_image', :text => 'Page with an inline image'
771 assert_select 'ul li a[href=?]', '/projects/ecookbook/wiki/Page_with_an_inline_image', :text => 'Page with an inline image'
770 end
772 end
771 assert_select 'li a[href=?]', '/projects/ecookbook/wiki/Another_page', :text => 'Another page'
773 assert_select 'li a[href=?]', '/projects/ecookbook/wiki/Another_page', :text => 'Another page'
772 end
774 end
773 end
775 end
774
776
775 def test_index_should_include_atom_link
777 def test_index_should_include_atom_link
776 get :index, :project_id => 'ecookbook'
778 get :index, :project_id => 'ecookbook'
777 assert_select 'a[href=?]', '/projects/ecookbook/activity.atom?show_wiki_edits=1'
779 assert_select 'a[href=?]', '/projects/ecookbook/activity.atom?show_wiki_edits=1'
778 end
780 end
779
781
780 def test_export_to_html
782 def test_export_to_html
781 @request.session[:user_id] = 2
783 @request.session[:user_id] = 2
782 get :export, :project_id => 'ecookbook'
784 get :export, :project_id => 'ecookbook'
783
785
784 assert_response :success
786 assert_response :success
785 assert_not_nil assigns(:pages)
787 assert_not_nil assigns(:pages)
786 assert assigns(:pages).any?
788 assert assigns(:pages).any?
787 assert_equal "text/html", @response.content_type
789 assert_equal "text/html", @response.content_type
788
790
789 assert_select "a[name=?]", "CookBook_documentation"
791 assert_select "a[name=?]", "CookBook_documentation"
790 assert_select "a[name=?]", "Another_page"
792 assert_select "a[name=?]", "Another_page"
791 assert_select "a[name=?]", "Page_with_an_inline_image"
793 assert_select "a[name=?]", "Page_with_an_inline_image"
792 end
794 end
793
795
794 def test_export_to_pdf
796 def test_export_to_pdf
795 @request.session[:user_id] = 2
797 @request.session[:user_id] = 2
796 get :export, :project_id => 'ecookbook', :format => 'pdf'
798 get :export, :project_id => 'ecookbook', :format => 'pdf'
797
799
798 assert_response :success
800 assert_response :success
799 assert_not_nil assigns(:pages)
801 assert_not_nil assigns(:pages)
800 assert assigns(:pages).any?
802 assert assigns(:pages).any?
801 assert_equal 'application/pdf', @response.content_type
803 assert_equal 'application/pdf', @response.content_type
802 assert_equal 'attachment; filename="ecookbook.pdf"', @response.headers['Content-Disposition']
804 assert_equal 'attachment; filename="ecookbook.pdf"', @response.headers['Content-Disposition']
803 assert @response.body.starts_with?('%PDF')
805 assert @response.body.starts_with?('%PDF')
804 end
806 end
805
807
806 def test_export_without_permission_should_be_denied
808 def test_export_without_permission_should_be_denied
807 @request.session[:user_id] = 2
809 @request.session[:user_id] = 2
808 Role.find_by_name('Manager').remove_permission! :export_wiki_pages
810 Role.find_by_name('Manager').remove_permission! :export_wiki_pages
809 get :export, :project_id => 'ecookbook'
811 get :export, :project_id => 'ecookbook'
810
812
811 assert_response 403
813 assert_response 403
812 end
814 end
813
815
814 def test_date_index
816 def test_date_index
815 get :date_index, :project_id => 'ecookbook'
817 get :date_index, :project_id => 'ecookbook'
816
818
817 assert_response :success
819 assert_response :success
818 assert_template 'date_index'
820 assert_template 'date_index'
819 assert_not_nil assigns(:pages)
821 assert_not_nil assigns(:pages)
820 assert_not_nil assigns(:pages_by_date)
822 assert_not_nil assigns(:pages_by_date)
821
823
822 assert_select 'a[href=?]', '/projects/ecookbook/activity.atom?show_wiki_edits=1'
824 assert_select 'a[href=?]', '/projects/ecookbook/activity.atom?show_wiki_edits=1'
823 end
825 end
824
826
825 def test_not_found
827 def test_not_found
826 get :show, :project_id => 999
828 get :show, :project_id => 999
827 assert_response 404
829 assert_response 404
828 end
830 end
829
831
830 def test_protect_page
832 def test_protect_page
831 page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
833 page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
832 assert !page.protected?
834 assert !page.protected?
833 @request.session[:user_id] = 2
835 @request.session[:user_id] = 2
834 post :protect, :project_id => 1, :id => page.title, :protected => '1'
836 post :protect, :project_id => 1, :id => page.title, :protected => '1'
835 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
837 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
836 assert page.reload.protected?
838 assert page.reload.protected?
837 end
839 end
838
840
839 def test_unprotect_page
841 def test_unprotect_page
840 page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
842 page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
841 assert page.protected?
843 assert page.protected?
842 @request.session[:user_id] = 2
844 @request.session[:user_id] = 2
843 post :protect, :project_id => 1, :id => page.title, :protected => '0'
845 post :protect, :project_id => 1, :id => page.title, :protected => '0'
844 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'CookBook_documentation'
846 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'CookBook_documentation'
845 assert !page.reload.protected?
847 assert !page.reload.protected?
846 end
848 end
847
849
848 def test_show_page_with_edit_link
850 def test_show_page_with_edit_link
849 @request.session[:user_id] = 2
851 @request.session[:user_id] = 2
850 get :show, :project_id => 1
852 get :show, :project_id => 1
851 assert_response :success
853 assert_response :success
852 assert_template 'show'
854 assert_template 'show'
853 assert_select 'a[href=?]', '/projects/1/wiki/CookBook_documentation/edit'
855 assert_select 'a[href=?]', '/projects/1/wiki/CookBook_documentation/edit'
854 end
856 end
855
857
856 def test_show_page_without_edit_link
858 def test_show_page_without_edit_link
857 @request.session[:user_id] = 4
859 @request.session[:user_id] = 4
858 get :show, :project_id => 1
860 get :show, :project_id => 1
859 assert_response :success
861 assert_response :success
860 assert_template 'show'
862 assert_template 'show'
861 assert_select 'a[href=?]', '/projects/1/wiki/CookBook_documentation/edit', 0
863 assert_select 'a[href=?]', '/projects/1/wiki/CookBook_documentation/edit', 0
862 end
864 end
863
865
864 def test_show_pdf
866 def test_show_pdf
865 @request.session[:user_id] = 2
867 @request.session[:user_id] = 2
866 get :show, :project_id => 1, :format => 'pdf'
868 get :show, :project_id => 1, :format => 'pdf'
867 assert_response :success
869 assert_response :success
868 assert_not_nil assigns(:page)
870 assert_not_nil assigns(:page)
869 assert_equal 'application/pdf', @response.content_type
871 assert_equal 'application/pdf', @response.content_type
870 assert_equal 'attachment; filename="CookBook_documentation.pdf"',
872 assert_equal 'attachment; filename="CookBook_documentation.pdf"',
871 @response.headers['Content-Disposition']
873 @response.headers['Content-Disposition']
872 end
874 end
873
875
874 def test_show_html
876 def test_show_html
875 @request.session[:user_id] = 2
877 @request.session[:user_id] = 2
876 get :show, :project_id => 1, :format => 'html'
878 get :show, :project_id => 1, :format => 'html'
877 assert_response :success
879 assert_response :success
878 assert_not_nil assigns(:page)
880 assert_not_nil assigns(:page)
879 assert_equal 'text/html', @response.content_type
881 assert_equal 'text/html', @response.content_type
880 assert_equal 'attachment; filename="CookBook_documentation.html"',
882 assert_equal 'attachment; filename="CookBook_documentation.html"',
881 @response.headers['Content-Disposition']
883 @response.headers['Content-Disposition']
882 assert_select 'h1', :text => /CookBook documentation/
884 assert_select 'h1', :text => /CookBook documentation/
883 end
885 end
884
886
885 def test_show_versioned_html
887 def test_show_versioned_html
886 @request.session[:user_id] = 2
888 @request.session[:user_id] = 2
887 get :show, :project_id => 1, :format => 'html', :version => 2
889 get :show, :project_id => 1, :format => 'html', :version => 2
888 assert_response :success
890 assert_response :success
889 assert_not_nil assigns(:content)
891 assert_not_nil assigns(:content)
890 assert_equal 2, assigns(:content).version
892 assert_equal 2, assigns(:content).version
891 assert_equal 'text/html', @response.content_type
893 assert_equal 'text/html', @response.content_type
892 assert_equal 'attachment; filename="CookBook_documentation.html"',
894 assert_equal 'attachment; filename="CookBook_documentation.html"',
893 @response.headers['Content-Disposition']
895 @response.headers['Content-Disposition']
894 assert_select 'h1', :text => /CookBook documentation/
896 assert_select 'h1', :text => /CookBook documentation/
895 end
897 end
896
898
897 def test_show_txt
899 def test_show_txt
898 @request.session[:user_id] = 2
900 @request.session[:user_id] = 2
899 get :show, :project_id => 1, :format => 'txt'
901 get :show, :project_id => 1, :format => 'txt'
900 assert_response :success
902 assert_response :success
901 assert_not_nil assigns(:page)
903 assert_not_nil assigns(:page)
902 assert_equal 'text/plain', @response.content_type
904 assert_equal 'text/plain', @response.content_type
903 assert_equal 'attachment; filename="CookBook_documentation.txt"',
905 assert_equal 'attachment; filename="CookBook_documentation.txt"',
904 @response.headers['Content-Disposition']
906 @response.headers['Content-Disposition']
905 assert_include 'h1. CookBook documentation', @response.body
907 assert_include 'h1. CookBook documentation', @response.body
906 end
908 end
907
909
908 def test_show_versioned_txt
910 def test_show_versioned_txt
909 @request.session[:user_id] = 2
911 @request.session[:user_id] = 2
910 get :show, :project_id => 1, :format => 'txt', :version => 2
912 get :show, :project_id => 1, :format => 'txt', :version => 2
911 assert_response :success
913 assert_response :success
912 assert_not_nil assigns(:content)
914 assert_not_nil assigns(:content)
913 assert_equal 2, assigns(:content).version
915 assert_equal 2, assigns(:content).version
914 assert_equal 'text/plain', @response.content_type
916 assert_equal 'text/plain', @response.content_type
915 assert_equal 'attachment; filename="CookBook_documentation.txt"',
917 assert_equal 'attachment; filename="CookBook_documentation.txt"',
916 @response.headers['Content-Disposition']
918 @response.headers['Content-Disposition']
917 assert_include 'h1. CookBook documentation', @response.body
919 assert_include 'h1. CookBook documentation', @response.body
918 end
920 end
919
921
920 def test_edit_unprotected_page
922 def test_edit_unprotected_page
921 # Non members can edit unprotected wiki pages
923 # Non members can edit unprotected wiki pages
922 @request.session[:user_id] = 4
924 @request.session[:user_id] = 4
923 get :edit, :project_id => 1, :id => 'Another_page'
925 get :edit, :project_id => 1, :id => 'Another_page'
924 assert_response :success
926 assert_response :success
925 assert_template 'edit'
927 assert_template 'edit'
926 end
928 end
927
929
928 def test_edit_protected_page_by_nonmember
930 def test_edit_protected_page_by_nonmember
929 # Non members can't edit protected wiki pages
931 # Non members can't edit protected wiki pages
930 @request.session[:user_id] = 4
932 @request.session[:user_id] = 4
931 get :edit, :project_id => 1, :id => 'CookBook_documentation'
933 get :edit, :project_id => 1, :id => 'CookBook_documentation'
932 assert_response 403
934 assert_response 403
933 end
935 end
934
936
935 def test_edit_protected_page_by_member
937 def test_edit_protected_page_by_member
936 @request.session[:user_id] = 2
938 @request.session[:user_id] = 2
937 get :edit, :project_id => 1, :id => 'CookBook_documentation'
939 get :edit, :project_id => 1, :id => 'CookBook_documentation'
938 assert_response :success
940 assert_response :success
939 assert_template 'edit'
941 assert_template 'edit'
940 end
942 end
941
943
942 def test_history_of_non_existing_page_should_return_404
944 def test_history_of_non_existing_page_should_return_404
943 get :history, :project_id => 1, :id => 'Unknown_page'
945 get :history, :project_id => 1, :id => 'Unknown_page'
944 assert_response 404
946 assert_response 404
945 end
947 end
946
948
947 def test_add_attachment
949 def test_add_attachment
948 @request.session[:user_id] = 2
950 @request.session[:user_id] = 2
949 assert_difference 'Attachment.count' do
951 assert_difference 'Attachment.count' do
950 post :add_attachment, :project_id => 1, :id => 'CookBook_documentation',
952 post :add_attachment, :project_id => 1, :id => 'CookBook_documentation',
951 :attachments => {
953 :attachments => {
952 '1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'),
954 '1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'),
953 'description' => 'test file'}
955 'description' => 'test file'}
954 }
956 }
955 end
957 end
956 attachment = Attachment.order('id DESC').first
958 attachment = Attachment.order('id DESC').first
957 assert_equal Wiki.find(1).find_page('CookBook_documentation'), attachment.container
959 assert_equal Wiki.find(1).find_page('CookBook_documentation'), attachment.container
958 end
960 end
959 end
961 end
@@ -1,353 +1,360
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 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 WorkflowsControllerTest < ActionController::TestCase
20 class WorkflowsControllerTest < ActionController::TestCase
21 fixtures :roles, :trackers, :workflows, :users, :issue_statuses
21 fixtures :roles, :trackers, :workflows, :users, :issue_statuses
22
22
23 def setup
23 def setup
24 User.current = nil
24 User.current = nil
25 @request.session[:user_id] = 1 # admin
25 @request.session[:user_id] = 1 # admin
26 end
26 end
27
27
28 def test_index
28 def test_index
29 get :index
29 get :index
30 assert_response :success
30 assert_response :success
31 assert_template 'index'
31 assert_template 'index'
32
32
33 count = WorkflowTransition.where(:role_id => 1, :tracker_id => 2).count
33 count = WorkflowTransition.where(:role_id => 1, :tracker_id => 2).count
34 assert_select 'a[href=?]', '/workflows/edit?role_id=1&amp;tracker_id=2', :content => count.to_s
34 assert_select 'a[href=?]', '/workflows/edit?role_id=1&amp;tracker_id=2', :content => count.to_s
35 end
35 end
36
36
37 def test_get_edit
37 def test_get_edit
38 get :edit
38 get :edit
39 assert_response :success
39 assert_response :success
40 assert_template 'edit'
40 assert_template 'edit'
41 end
41 end
42
42
43 def test_get_edit_with_role_and_tracker
43 def test_get_edit_with_role_and_tracker
44 WorkflowTransition.delete_all
44 WorkflowTransition.delete_all
45 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
45 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
46 WorkflowTransition.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
46 WorkflowTransition.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
47
47
48 get :edit, :role_id => 2, :tracker_id => 1
48 get :edit, :role_id => 2, :tracker_id => 1
49 assert_response :success
49 assert_response :success
50 assert_template 'edit'
50 assert_template 'edit'
51
51
52 # used status only
52 # used status only
53 assert_not_nil assigns(:statuses)
53 assert_not_nil assigns(:statuses)
54 assert_equal [2, 3, 5], assigns(:statuses).collect(&:id)
54 assert_equal [2, 3, 5], assigns(:statuses).collect(&:id)
55
55
56 # allowed transitions
56 # allowed transitions
57 assert_select 'input[type=checkbox][name=?][value="1"][checked=checked]', 'transitions[3][5][always]'
57 assert_select 'input[type=checkbox][name=?][value="1"][checked=checked]', 'transitions[3][5][always]'
58 # not allowed
58 # not allowed
59 assert_select 'input[type=checkbox][name=?][value="1"]:not([checked=checked])', 'transitions[3][2][always]'
59 assert_select 'input[type=checkbox][name=?][value="1"]:not([checked=checked])', 'transitions[3][2][always]'
60 # unused
60 # unused
61 assert_select 'input[type=checkbox][name=?]', 'transitions[1][1][always]', 0
61 assert_select 'input[type=checkbox][name=?]', 'transitions[1][1][always]', 0
62 end
62 end
63
63
64 def test_get_edit_with_all_roles_and_all_trackers
65 get :edit, :role_id => 'all', :tracker_id => 'all'
66 assert_response :success
67 assert_equal Role.sorted.to_a, assigns(:roles)
68 assert_equal Tracker.sorted.to_a, assigns(:trackers)
69 end
70
64 def test_get_edit_with_role_and_tracker_and_all_statuses
71 def test_get_edit_with_role_and_tracker_and_all_statuses
65 WorkflowTransition.delete_all
72 WorkflowTransition.delete_all
66
73
67 get :edit, :role_id => 2, :tracker_id => 1, :used_statuses_only => '0'
74 get :edit, :role_id => 2, :tracker_id => 1, :used_statuses_only => '0'
68 assert_response :success
75 assert_response :success
69 assert_template 'edit'
76 assert_template 'edit'
70
77
71 assert_not_nil assigns(:statuses)
78 assert_not_nil assigns(:statuses)
72 assert_equal IssueStatus.count, assigns(:statuses).size
79 assert_equal IssueStatus.count, assigns(:statuses).size
73
80
74 assert_select 'input[type=checkbox][name=?]', 'transitions[1][1][always]'
81 assert_select 'input[type=checkbox][name=?]', 'transitions[1][1][always]'
75 end
82 end
76
83
77 def test_post_edit
84 def test_post_edit
78 WorkflowTransition.delete_all
85 WorkflowTransition.delete_all
79
86
80 post :edit, :role_id => 2, :tracker_id => 1,
87 post :edit, :role_id => 2, :tracker_id => 1,
81 :transitions => {
88 :transitions => {
82 '4' => {'5' => {'always' => '1'}},
89 '4' => {'5' => {'always' => '1'}},
83 '3' => {'1' => {'always' => '1'}, '2' => {'always' => '1'}}
90 '3' => {'1' => {'always' => '1'}, '2' => {'always' => '1'}}
84 }
91 }
85 assert_response 302
92 assert_response 302
86
93
87 assert_equal 3, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
94 assert_equal 3, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
88 assert_not_nil WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
95 assert_not_nil WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
89 assert_nil WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4).first
96 assert_nil WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4).first
90 end
97 end
91
98
92 def test_post_edit_with_additional_transitions
99 def test_post_edit_with_additional_transitions
93 WorkflowTransition.delete_all
100 WorkflowTransition.delete_all
94
101
95 post :edit, :role_id => 2, :tracker_id => 1,
102 post :edit, :role_id => 2, :tracker_id => 1,
96 :transitions => {
103 :transitions => {
97 '4' => {'5' => {'always' => '1', 'author' => '0', 'assignee' => '0'}},
104 '4' => {'5' => {'always' => '1', 'author' => '0', 'assignee' => '0'}},
98 '3' => {'1' => {'always' => '0', 'author' => '1', 'assignee' => '0'},
105 '3' => {'1' => {'always' => '0', 'author' => '1', 'assignee' => '0'},
99 '2' => {'always' => '0', 'author' => '0', 'assignee' => '1'},
106 '2' => {'always' => '0', 'author' => '0', 'assignee' => '1'},
100 '4' => {'always' => '0', 'author' => '1', 'assignee' => '1'}}
107 '4' => {'always' => '0', 'author' => '1', 'assignee' => '1'}}
101 }
108 }
102 assert_response 302
109 assert_response 302
103
110
104 assert_equal 4, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
111 assert_equal 4, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
105
112
106 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5).first
113 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5).first
107 assert ! w.author
114 assert ! w.author
108 assert ! w.assignee
115 assert ! w.assignee
109 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1).first
116 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1).first
110 assert w.author
117 assert w.author
111 assert ! w.assignee
118 assert ! w.assignee
112 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
119 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
113 assert ! w.author
120 assert ! w.author
114 assert w.assignee
121 assert w.assignee
115 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4).first
122 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4).first
116 assert w.author
123 assert w.author
117 assert w.assignee
124 assert w.assignee
118 end
125 end
119
126
120 def test_get_permissions
127 def test_get_permissions
121 get :permissions
128 get :permissions
122
129
123 assert_response :success
130 assert_response :success
124 assert_template 'permissions'
131 assert_template 'permissions'
125 end
132 end
126
133
127 def test_get_permissions_with_role_and_tracker
134 def test_get_permissions_with_role_and_tracker
128 WorkflowPermission.delete_all
135 WorkflowPermission.delete_all
129 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'assigned_to_id', :rule => 'required')
136 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'assigned_to_id', :rule => 'required')
130 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
137 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
131 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 3, :field_name => 'fixed_version_id', :rule => 'readonly')
138 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 3, :field_name => 'fixed_version_id', :rule => 'readonly')
132
139
133 get :permissions, :role_id => 1, :tracker_id => 2
140 get :permissions, :role_id => 1, :tracker_id => 2
134 assert_response :success
141 assert_response :success
135 assert_template 'permissions'
142 assert_template 'permissions'
136
143
137 assert_select 'input[name=?][value="1"]', 'role_id[]'
144 assert_select 'input[name=?][value="1"]', 'role_id[]'
138 assert_select 'input[name=?][value="2"]', 'tracker_id[]'
145 assert_select 'input[name=?][value="2"]', 'tracker_id[]'
139
146
140 # Required field
147 # Required field
141 assert_select 'select[name=?]', 'permissions[2][assigned_to_id]' do
148 assert_select 'select[name=?]', 'permissions[2][assigned_to_id]' do
142 assert_select 'option[value=""]'
149 assert_select 'option[value=""]'
143 assert_select 'option[value=""][selected=selected]', 0
150 assert_select 'option[value=""][selected=selected]', 0
144 assert_select 'option[value=readonly]', :text => 'Read-only'
151 assert_select 'option[value=readonly]', :text => 'Read-only'
145 assert_select 'option[value=readonly][selected=selected]', 0
152 assert_select 'option[value=readonly][selected=selected]', 0
146 assert_select 'option[value=required]', :text => 'Required'
153 assert_select 'option[value=required]', :text => 'Required'
147 assert_select 'option[value=required][selected=selected]'
154 assert_select 'option[value=required][selected=selected]'
148 end
155 end
149
156
150 # Read-only field
157 # Read-only field
151 assert_select 'select[name=?]', 'permissions[3][fixed_version_id]' do
158 assert_select 'select[name=?]', 'permissions[3][fixed_version_id]' do
152 assert_select 'option[value=""]'
159 assert_select 'option[value=""]'
153 assert_select 'option[value=""][selected=selected]', 0
160 assert_select 'option[value=""][selected=selected]', 0
154 assert_select 'option[value=readonly]', :text => 'Read-only'
161 assert_select 'option[value=readonly]', :text => 'Read-only'
155 assert_select 'option[value=readonly][selected=selected]'
162 assert_select 'option[value=readonly][selected=selected]'
156 assert_select 'option[value=required]', :text => 'Required'
163 assert_select 'option[value=required]', :text => 'Required'
157 assert_select 'option[value=required][selected=selected]', 0
164 assert_select 'option[value=required][selected=selected]', 0
158 end
165 end
159
166
160 # Other field
167 # Other field
161 assert_select 'select[name=?]', 'permissions[3][due_date]' do
168 assert_select 'select[name=?]', 'permissions[3][due_date]' do
162 assert_select 'option[value=""]'
169 assert_select 'option[value=""]'
163 assert_select 'option[value=""][selected=selected]', 0
170 assert_select 'option[value=""][selected=selected]', 0
164 assert_select 'option[value=readonly]', :text => 'Read-only'
171 assert_select 'option[value=readonly]', :text => 'Read-only'
165 assert_select 'option[value=readonly][selected=selected]', 0
172 assert_select 'option[value=readonly][selected=selected]', 0
166 assert_select 'option[value=required]', :text => 'Required'
173 assert_select 'option[value=required]', :text => 'Required'
167 assert_select 'option[value=required][selected=selected]', 0
174 assert_select 'option[value=required][selected=selected]', 0
168 end
175 end
169 end
176 end
170
177
171 def test_get_permissions_with_required_custom_field_should_not_show_required_option
178 def test_get_permissions_with_required_custom_field_should_not_show_required_option
172 cf = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :tracker_ids => [1], :is_required => true)
179 cf = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :tracker_ids => [1], :is_required => true)
173
180
174 get :permissions, :role_id => 1, :tracker_id => 1
181 get :permissions, :role_id => 1, :tracker_id => 1
175 assert_response :success
182 assert_response :success
176 assert_template 'permissions'
183 assert_template 'permissions'
177
184
178 # Custom field that is always required
185 # Custom field that is always required
179 # The default option is "(Required)"
186 # The default option is "(Required)"
180 assert_select 'select[name=?]', "permissions[3][#{cf.id}]" do
187 assert_select 'select[name=?]', "permissions[3][#{cf.id}]" do
181 assert_select 'option[value=""]'
188 assert_select 'option[value=""]'
182 assert_select 'option[value=readonly]', :text => 'Read-only'
189 assert_select 'option[value=readonly]', :text => 'Read-only'
183 assert_select 'option[value=required]', 0
190 assert_select 'option[value=required]', 0
184 end
191 end
185 end
192 end
186
193
187 def test_get_permissions_should_disable_hidden_custom_fields
194 def test_get_permissions_should_disable_hidden_custom_fields
188 cf1 = IssueCustomField.generate!(:tracker_ids => [1], :visible => true)
195 cf1 = IssueCustomField.generate!(:tracker_ids => [1], :visible => true)
189 cf2 = IssueCustomField.generate!(:tracker_ids => [1], :visible => false, :role_ids => [1])
196 cf2 = IssueCustomField.generate!(:tracker_ids => [1], :visible => false, :role_ids => [1])
190 cf3 = IssueCustomField.generate!(:tracker_ids => [1], :visible => false, :role_ids => [1, 2])
197 cf3 = IssueCustomField.generate!(:tracker_ids => [1], :visible => false, :role_ids => [1, 2])
191
198
192 get :permissions, :role_id => 2, :tracker_id => 1
199 get :permissions, :role_id => 2, :tracker_id => 1
193 assert_response :success
200 assert_response :success
194 assert_template 'permissions'
201 assert_template 'permissions'
195
202
196 assert_select 'select[name=?]:not(.disabled)', "permissions[1][#{cf1.id}]"
203 assert_select 'select[name=?]:not(.disabled)', "permissions[1][#{cf1.id}]"
197 assert_select 'select[name=?]:not(.disabled)', "permissions[1][#{cf3.id}]"
204 assert_select 'select[name=?]:not(.disabled)', "permissions[1][#{cf3.id}]"
198
205
199 assert_select 'select[name=?][disabled=disabled]', "permissions[1][#{cf2.id}]" do
206 assert_select 'select[name=?][disabled=disabled]', "permissions[1][#{cf2.id}]" do
200 assert_select 'option[value=""][selected=selected]', :text => 'Hidden'
207 assert_select 'option[value=""][selected=selected]', :text => 'Hidden'
201 end
208 end
202 end
209 end
203
210
204 def test_get_permissions_with_missing_permissions_for_roles_should_default_to_no_change
211 def test_get_permissions_with_missing_permissions_for_roles_should_default_to_no_change
205 WorkflowPermission.delete_all
212 WorkflowPermission.delete_all
206 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
213 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
207
214
208 get :permissions, :role_id => [1, 2], :tracker_id => 2
215 get :permissions, :role_id => [1, 2], :tracker_id => 2
209 assert_response :success
216 assert_response :success
210
217
211 assert_select 'select[name=?]', 'permissions[1][assigned_to_id]' do
218 assert_select 'select[name=?]', 'permissions[1][assigned_to_id]' do
212 assert_select 'option[selected]', 1
219 assert_select 'option[selected]', 1
213 assert_select 'option[selected][value=no_change]'
220 assert_select 'option[selected][value=no_change]'
214 end
221 end
215 end
222 end
216
223
217 def test_get_permissions_with_different_permissions_for_roles_should_default_to_no_change
224 def test_get_permissions_with_different_permissions_for_roles_should_default_to_no_change
218 WorkflowPermission.delete_all
225 WorkflowPermission.delete_all
219 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
226 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
220 WorkflowPermission.create!(:role_id => 2, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'readonly')
227 WorkflowPermission.create!(:role_id => 2, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'readonly')
221
228
222 get :permissions, :role_id => [1, 2], :tracker_id => 2
229 get :permissions, :role_id => [1, 2], :tracker_id => 2
223 assert_response :success
230 assert_response :success
224
231
225 assert_select 'select[name=?]', 'permissions[1][assigned_to_id]' do
232 assert_select 'select[name=?]', 'permissions[1][assigned_to_id]' do
226 assert_select 'option[selected]', 1
233 assert_select 'option[selected]', 1
227 assert_select 'option[selected][value=no_change]'
234 assert_select 'option[selected][value=no_change]'
228 end
235 end
229 end
236 end
230
237
231 def test_get_permissions_with_same_permissions_for_roles_should_default_to_permission
238 def test_get_permissions_with_same_permissions_for_roles_should_default_to_permission
232 WorkflowPermission.delete_all
239 WorkflowPermission.delete_all
233 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
240 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
234 WorkflowPermission.create!(:role_id => 2, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
241 WorkflowPermission.create!(:role_id => 2, :tracker_id => 2, :old_status_id => 1, :field_name => 'assigned_to_id', :rule => 'required')
235
242
236 get :permissions, :role_id => [1, 2], :tracker_id => 2
243 get :permissions, :role_id => [1, 2], :tracker_id => 2
237 assert_response :success
244 assert_response :success
238
245
239 assert_select 'select[name=?]', 'permissions[1][assigned_to_id]' do
246 assert_select 'select[name=?]', 'permissions[1][assigned_to_id]' do
240 assert_select 'option[selected]', 1
247 assert_select 'option[selected]', 1
241 assert_select 'option[selected][value=required]'
248 assert_select 'option[selected][value=required]'
242 end
249 end
243 end
250 end
244
251
245 def test_get_permissions_with_role_and_tracker_and_all_statuses_should_show_all_statuses
252 def test_get_permissions_with_role_and_tracker_and_all_statuses_should_show_all_statuses
246 WorkflowTransition.delete_all
253 WorkflowTransition.delete_all
247
254
248 get :permissions, :role_id => 1, :tracker_id => 2, :used_statuses_only => '0'
255 get :permissions, :role_id => 1, :tracker_id => 2, :used_statuses_only => '0'
249 assert_response :success
256 assert_response :success
250 assert_equal IssueStatus.sorted.to_a, assigns(:statuses)
257 assert_equal IssueStatus.sorted.to_a, assigns(:statuses)
251 end
258 end
252
259
253 def test_post_permissions
260 def test_post_permissions
254 WorkflowPermission.delete_all
261 WorkflowPermission.delete_all
255
262
256 post :permissions, :role_id => 1, :tracker_id => 2, :permissions => {
263 post :permissions, :role_id => 1, :tracker_id => 2, :permissions => {
257 '1' => {'assigned_to_id' => '', 'fixed_version_id' => 'required', 'due_date' => ''},
264 '1' => {'assigned_to_id' => '', 'fixed_version_id' => 'required', 'due_date' => ''},
258 '2' => {'assigned_to_id' => 'readonly', 'fixed_version_id' => 'readonly', 'due_date' => ''},
265 '2' => {'assigned_to_id' => 'readonly', 'fixed_version_id' => 'readonly', 'due_date' => ''},
259 '3' => {'assigned_to_id' => '', 'fixed_version_id' => '', 'due_date' => ''}
266 '3' => {'assigned_to_id' => '', 'fixed_version_id' => '', 'due_date' => ''}
260 }
267 }
261 assert_response 302
268 assert_response 302
262
269
263 workflows = WorkflowPermission.all
270 workflows = WorkflowPermission.all
264 assert_equal 3, workflows.size
271 assert_equal 3, workflows.size
265 workflows.each do |workflow|
272 workflows.each do |workflow|
266 assert_equal 1, workflow.role_id
273 assert_equal 1, workflow.role_id
267 assert_equal 2, workflow.tracker_id
274 assert_equal 2, workflow.tracker_id
268 end
275 end
269 assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'assigned_to_id' && wf.rule == 'readonly'}
276 assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'assigned_to_id' && wf.rule == 'readonly'}
270 assert workflows.detect {|wf| wf.old_status_id == 1 && wf.field_name == 'fixed_version_id' && wf.rule == 'required'}
277 assert workflows.detect {|wf| wf.old_status_id == 1 && wf.field_name == 'fixed_version_id' && wf.rule == 'required'}
271 assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'fixed_version_id' && wf.rule == 'readonly'}
278 assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'fixed_version_id' && wf.rule == 'readonly'}
272 end
279 end
273
280
274 def test_get_copy
281 def test_get_copy
275 get :copy
282 get :copy
276 assert_response :success
283 assert_response :success
277 assert_template 'copy'
284 assert_template 'copy'
278 assert_select 'select[name=source_tracker_id]' do
285 assert_select 'select[name=source_tracker_id]' do
279 assert_select 'option[value="1"]', :text => 'Bug'
286 assert_select 'option[value="1"]', :text => 'Bug'
280 end
287 end
281 assert_select 'select[name=source_role_id]' do
288 assert_select 'select[name=source_role_id]' do
282 assert_select 'option[value="2"]', :text => 'Developer'
289 assert_select 'option[value="2"]', :text => 'Developer'
283 end
290 end
284 assert_select 'select[name=?]', 'target_tracker_ids[]' do
291 assert_select 'select[name=?]', 'target_tracker_ids[]' do
285 assert_select 'option[value="3"]', :text => 'Support request'
292 assert_select 'option[value="3"]', :text => 'Support request'
286 end
293 end
287 assert_select 'select[name=?]', 'target_role_ids[]' do
294 assert_select 'select[name=?]', 'target_role_ids[]' do
288 assert_select 'option[value="1"]', :text => 'Manager'
295 assert_select 'option[value="1"]', :text => 'Manager'
289 end
296 end
290 end
297 end
291
298
292 def test_post_copy_one_to_one
299 def test_post_copy_one_to_one
293 source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
300 source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
294
301
295 post :copy, :source_tracker_id => '1', :source_role_id => '2',
302 post :copy, :source_tracker_id => '1', :source_role_id => '2',
296 :target_tracker_ids => ['3'], :target_role_ids => ['1']
303 :target_tracker_ids => ['3'], :target_role_ids => ['1']
297 assert_response 302
304 assert_response 302
298 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
305 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
299 end
306 end
300
307
301 def test_post_copy_one_to_many
308 def test_post_copy_one_to_many
302 source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
309 source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
303
310
304 post :copy, :source_tracker_id => '1', :source_role_id => '2',
311 post :copy, :source_tracker_id => '1', :source_role_id => '2',
305 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
312 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
306 assert_response 302
313 assert_response 302
307 assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 1)
314 assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 1)
308 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
315 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
309 assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 3)
316 assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 3)
310 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 3)
317 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 3)
311 end
318 end
312
319
313 def test_post_copy_many_to_many
320 def test_post_copy_many_to_many
314 source_t2 = status_transitions(:tracker_id => 2, :role_id => 2)
321 source_t2 = status_transitions(:tracker_id => 2, :role_id => 2)
315 source_t3 = status_transitions(:tracker_id => 3, :role_id => 2)
322 source_t3 = status_transitions(:tracker_id => 3, :role_id => 2)
316
323
317 post :copy, :source_tracker_id => 'any', :source_role_id => '2',
324 post :copy, :source_tracker_id => 'any', :source_role_id => '2',
318 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
325 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
319 assert_response 302
326 assert_response 302
320 assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 1)
327 assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 1)
321 assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 1)
328 assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 1)
322 assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 3)
329 assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 3)
323 assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 3)
330 assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 3)
324 end
331 end
325
332
326 def test_post_copy_with_incomplete_source_specification_should_fail
333 def test_post_copy_with_incomplete_source_specification_should_fail
327 assert_no_difference 'WorkflowRule.count' do
334 assert_no_difference 'WorkflowRule.count' do
328 post :copy,
335 post :copy,
329 :source_tracker_id => '', :source_role_id => '2',
336 :source_tracker_id => '', :source_role_id => '2',
330 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
337 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
331 assert_response 200
338 assert_response 200
332 assert_select 'div.flash.error', :text => 'Please select a source tracker or role'
339 assert_select 'div.flash.error', :text => 'Please select a source tracker or role'
333 end
340 end
334 end
341 end
335
342
336 def test_post_copy_with_incomplete_target_specification_should_fail
343 def test_post_copy_with_incomplete_target_specification_should_fail
337 assert_no_difference 'WorkflowRule.count' do
344 assert_no_difference 'WorkflowRule.count' do
338 post :copy,
345 post :copy,
339 :source_tracker_id => '1', :source_role_id => '2',
346 :source_tracker_id => '1', :source_role_id => '2',
340 :target_tracker_ids => ['2', '3']
347 :target_tracker_ids => ['2', '3']
341 assert_response 200
348 assert_response 200
342 assert_select 'div.flash.error', :text => 'Please select target tracker(s) and role(s)'
349 assert_select 'div.flash.error', :text => 'Please select target tracker(s) and role(s)'
343 end
350 end
344 end
351 end
345
352
346 # Returns an array of status transitions that can be compared
353 # Returns an array of status transitions that can be compared
347 def status_transitions(conditions)
354 def status_transitions(conditions)
348 WorkflowTransition.
355 WorkflowTransition.
349 where(conditions).
356 where(conditions).
350 order('tracker_id, role_id, old_status_id, new_status_id').
357 order('tracker_id, role_id, old_status_id, new_status_id').
351 collect {|w| [w.old_status, w.new_status_id]}
358 collect {|w| [w.old_status, w.new_status_id]}
352 end
359 end
353 end
360 end
@@ -1,274 +1,294
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 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 Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base
20 class Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base
21 fixtures :users, :members, :member_roles, :roles, :projects
21 fixtures :users, :members, :member_roles, :roles, :projects
22
22
23 test "GET /users.xml should return users" do
24 get '/users.xml', {}, credentials('admin')
25
26 assert_response :success
27 assert_equal 'application/xml', response.content_type
28 assert_select 'users' do
29 assert_select 'user', assigns(:users).size
30 end
31 end
32
33 test "GET /users.json should return users" do
34 get '/users.json', {}, credentials('admin')
35
36 assert_response :success
37 assert_equal 'application/json', response.content_type
38 json = ActiveSupport::JSON.decode(response.body)
39 assert json.key?('users')
40 assert_equal assigns(:users).size, json['users'].size
41 end
42
23 test "GET /users/:id.xml should return the user" do
43 test "GET /users/:id.xml should return the user" do
24 get '/users/2.xml'
44 get '/users/2.xml'
25
45
26 assert_response :success
46 assert_response :success
27 assert_select 'user id', :text => '2'
47 assert_select 'user id', :text => '2'
28 end
48 end
29
49
30 test "GET /users/:id.json should return the user" do
50 test "GET /users/:id.json should return the user" do
31 get '/users/2.json'
51 get '/users/2.json'
32
52
33 assert_response :success
53 assert_response :success
34 json = ActiveSupport::JSON.decode(response.body)
54 json = ActiveSupport::JSON.decode(response.body)
35 assert_kind_of Hash, json
55 assert_kind_of Hash, json
36 assert_kind_of Hash, json['user']
56 assert_kind_of Hash, json['user']
37 assert_equal 2, json['user']['id']
57 assert_equal 2, json['user']['id']
38 end
58 end
39
59
40 test "GET /users/:id.xml with include=memberships should include memberships" do
60 test "GET /users/:id.xml with include=memberships should include memberships" do
41 get '/users/2.xml?include=memberships'
61 get '/users/2.xml?include=memberships'
42
62
43 assert_response :success
63 assert_response :success
44 assert_select 'user memberships', 1
64 assert_select 'user memberships', 1
45 end
65 end
46
66
47 test "GET /users/:id.json with include=memberships should include memberships" do
67 test "GET /users/:id.json with include=memberships should include memberships" do
48 get '/users/2.json?include=memberships'
68 get '/users/2.json?include=memberships'
49
69
50 assert_response :success
70 assert_response :success
51 json = ActiveSupport::JSON.decode(response.body)
71 json = ActiveSupport::JSON.decode(response.body)
52 assert_kind_of Array, json['user']['memberships']
72 assert_kind_of Array, json['user']['memberships']
53 assert_equal [{
73 assert_equal [{
54 "id"=>1,
74 "id"=>1,
55 "project"=>{"name"=>"eCookbook", "id"=>1},
75 "project"=>{"name"=>"eCookbook", "id"=>1},
56 "roles"=>[{"name"=>"Manager", "id"=>1}]
76 "roles"=>[{"name"=>"Manager", "id"=>1}]
57 }], json['user']['memberships']
77 }], json['user']['memberships']
58 end
78 end
59
79
60 test "GET /users/current.xml should require authentication" do
80 test "GET /users/current.xml should require authentication" do
61 get '/users/current.xml'
81 get '/users/current.xml'
62
82
63 assert_response 401
83 assert_response 401
64 end
84 end
65
85
66 test "GET /users/current.xml should return current user" do
86 test "GET /users/current.xml should return current user" do
67 get '/users/current.xml', {}, credentials('jsmith')
87 get '/users/current.xml', {}, credentials('jsmith')
68
88
69 assert_select 'user id', :text => '2'
89 assert_select 'user id', :text => '2'
70 end
90 end
71
91
72 test "GET /users/:id should not return login for other user" do
92 test "GET /users/:id should not return login for other user" do
73 get '/users/3.xml', {}, credentials('jsmith')
93 get '/users/3.xml', {}, credentials('jsmith')
74 assert_response :success
94 assert_response :success
75 assert_select 'user login', 0
95 assert_select 'user login', 0
76 end
96 end
77
97
78 test "GET /users/:id should return login for current user" do
98 test "GET /users/:id should return login for current user" do
79 get '/users/2.xml', {}, credentials('jsmith')
99 get '/users/2.xml', {}, credentials('jsmith')
80 assert_response :success
100 assert_response :success
81 assert_select 'user login', :text => 'jsmith'
101 assert_select 'user login', :text => 'jsmith'
82 end
102 end
83
103
84 test "GET /users/:id should not return api_key for other user" do
104 test "GET /users/:id should not return api_key for other user" do
85 get '/users/3.xml', {}, credentials('jsmith')
105 get '/users/3.xml', {}, credentials('jsmith')
86 assert_response :success
106 assert_response :success
87 assert_select 'user api_key', 0
107 assert_select 'user api_key', 0
88 end
108 end
89
109
90 test "GET /users/:id should return api_key for current user" do
110 test "GET /users/:id should return api_key for current user" do
91 get '/users/2.xml', {}, credentials('jsmith')
111 get '/users/2.xml', {}, credentials('jsmith')
92 assert_response :success
112 assert_response :success
93 assert_select 'user api_key', :text => User.find(2).api_key
113 assert_select 'user api_key', :text => User.find(2).api_key
94 end
114 end
95
115
96 test "GET /users/:id should not return status for standard user" do
116 test "GET /users/:id should not return status for standard user" do
97 get '/users/3.xml', {}, credentials('jsmith')
117 get '/users/3.xml', {}, credentials('jsmith')
98 assert_response :success
118 assert_response :success
99 assert_select 'user status', 0
119 assert_select 'user status', 0
100 end
120 end
101
121
102 test "GET /users/:id should return status for administrators" do
122 test "GET /users/:id should return status for administrators" do
103 get '/users/2.xml', {}, credentials('admin')
123 get '/users/2.xml', {}, credentials('admin')
104 assert_response :success
124 assert_response :success
105 assert_select 'user status', :text => User.find(1).status.to_s
125 assert_select 'user status', :text => User.find(1).status.to_s
106 end
126 end
107
127
108 test "POST /users.xml with valid parameters should create the user" do
128 test "POST /users.xml with valid parameters should create the user" do
109 assert_difference('User.count') do
129 assert_difference('User.count') do
110 post '/users.xml', {
130 post '/users.xml', {
111 :user => {
131 :user => {
112 :login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
132 :login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
113 :mail => 'foo@example.net', :password => 'secret123',
133 :mail => 'foo@example.net', :password => 'secret123',
114 :mail_notification => 'only_assigned'}
134 :mail_notification => 'only_assigned'}
115 },
135 },
116 credentials('admin')
136 credentials('admin')
117 end
137 end
118
138
119 user = User.order('id DESC').first
139 user = User.order('id DESC').first
120 assert_equal 'foo', user.login
140 assert_equal 'foo', user.login
121 assert_equal 'Firstname', user.firstname
141 assert_equal 'Firstname', user.firstname
122 assert_equal 'Lastname', user.lastname
142 assert_equal 'Lastname', user.lastname
123 assert_equal 'foo@example.net', user.mail
143 assert_equal 'foo@example.net', user.mail
124 assert_equal 'only_assigned', user.mail_notification
144 assert_equal 'only_assigned', user.mail_notification
125 assert !user.admin?
145 assert !user.admin?
126 assert user.check_password?('secret123')
146 assert user.check_password?('secret123')
127
147
128 assert_response :created
148 assert_response :created
129 assert_equal 'application/xml', @response.content_type
149 assert_equal 'application/xml', @response.content_type
130 assert_select 'user id', :text => user.id.to_s
150 assert_select 'user id', :text => user.id.to_s
131 end
151 end
132
152
133 test "POST /users.json with valid parameters should create the user" do
153 test "POST /users.json with valid parameters should create the user" do
134 assert_difference('User.count') do
154 assert_difference('User.count') do
135 post '/users.json', {
155 post '/users.json', {
136 :user => {
156 :user => {
137 :login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
157 :login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
138 :mail => 'foo@example.net', :password => 'secret123',
158 :mail => 'foo@example.net', :password => 'secret123',
139 :mail_notification => 'only_assigned'}
159 :mail_notification => 'only_assigned'}
140 },
160 },
141 credentials('admin')
161 credentials('admin')
142 end
162 end
143
163
144 user = User.order('id DESC').first
164 user = User.order('id DESC').first
145 assert_equal 'foo', user.login
165 assert_equal 'foo', user.login
146 assert_equal 'Firstname', user.firstname
166 assert_equal 'Firstname', user.firstname
147 assert_equal 'Lastname', user.lastname
167 assert_equal 'Lastname', user.lastname
148 assert_equal 'foo@example.net', user.mail
168 assert_equal 'foo@example.net', user.mail
149 assert !user.admin?
169 assert !user.admin?
150
170
151 assert_response :created
171 assert_response :created
152 assert_equal 'application/json', @response.content_type
172 assert_equal 'application/json', @response.content_type
153 json = ActiveSupport::JSON.decode(response.body)
173 json = ActiveSupport::JSON.decode(response.body)
154 assert_kind_of Hash, json
174 assert_kind_of Hash, json
155 assert_kind_of Hash, json['user']
175 assert_kind_of Hash, json['user']
156 assert_equal user.id, json['user']['id']
176 assert_equal user.id, json['user']['id']
157 end
177 end
158
178
159 test "POST /users.xml with with invalid parameters should return errors" do
179 test "POST /users.xml with with invalid parameters should return errors" do
160 assert_no_difference('User.count') do
180 assert_no_difference('User.count') do
161 post '/users.xml', {:user => {:login => 'foo', :lastname => 'Lastname', :mail => 'foo'}}, credentials('admin')
181 post '/users.xml', {:user => {:login => 'foo', :lastname => 'Lastname', :mail => 'foo'}}, credentials('admin')
162 end
182 end
163
183
164 assert_response :unprocessable_entity
184 assert_response :unprocessable_entity
165 assert_equal 'application/xml', @response.content_type
185 assert_equal 'application/xml', @response.content_type
166 assert_select 'errors error', :text => "First name can't be blank"
186 assert_select 'errors error', :text => "First name can't be blank"
167 end
187 end
168
188
169 test "POST /users.json with with invalid parameters should return errors" do
189 test "POST /users.json with with invalid parameters should return errors" do
170 assert_no_difference('User.count') do
190 assert_no_difference('User.count') do
171 post '/users.json', {:user => {:login => 'foo', :lastname => 'Lastname', :mail => 'foo'}}, credentials('admin')
191 post '/users.json', {:user => {:login => 'foo', :lastname => 'Lastname', :mail => 'foo'}}, credentials('admin')
172 end
192 end
173
193
174 assert_response :unprocessable_entity
194 assert_response :unprocessable_entity
175 assert_equal 'application/json', @response.content_type
195 assert_equal 'application/json', @response.content_type
176 json = ActiveSupport::JSON.decode(response.body)
196 json = ActiveSupport::JSON.decode(response.body)
177 assert_kind_of Hash, json
197 assert_kind_of Hash, json
178 assert json.has_key?('errors')
198 assert json.has_key?('errors')
179 assert_kind_of Array, json['errors']
199 assert_kind_of Array, json['errors']
180 end
200 end
181
201
182 test "PUT /users/:id.xml with valid parameters should update the user" do
202 test "PUT /users/:id.xml with valid parameters should update the user" do
183 assert_no_difference('User.count') do
203 assert_no_difference('User.count') do
184 put '/users/2.xml', {
204 put '/users/2.xml', {
185 :user => {
205 :user => {
186 :login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
206 :login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
187 :mail => 'jsmith@somenet.foo'}
207 :mail => 'jsmith@somenet.foo'}
188 },
208 },
189 credentials('admin')
209 credentials('admin')
190 end
210 end
191
211
192 user = User.find(2)
212 user = User.find(2)
193 assert_equal 'jsmith', user.login
213 assert_equal 'jsmith', user.login
194 assert_equal 'John', user.firstname
214 assert_equal 'John', user.firstname
195 assert_equal 'Renamed', user.lastname
215 assert_equal 'Renamed', user.lastname
196 assert_equal 'jsmith@somenet.foo', user.mail
216 assert_equal 'jsmith@somenet.foo', user.mail
197 assert !user.admin?
217 assert !user.admin?
198
218
199 assert_response :ok
219 assert_response :ok
200 assert_equal '', @response.body
220 assert_equal '', @response.body
201 end
221 end
202
222
203 test "PUT /users/:id.json with valid parameters should update the user" do
223 test "PUT /users/:id.json with valid parameters should update the user" do
204 assert_no_difference('User.count') do
224 assert_no_difference('User.count') do
205 put '/users/2.json', {
225 put '/users/2.json', {
206 :user => {
226 :user => {
207 :login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
227 :login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
208 :mail => 'jsmith@somenet.foo'}
228 :mail => 'jsmith@somenet.foo'}
209 },
229 },
210 credentials('admin')
230 credentials('admin')
211 end
231 end
212
232
213 user = User.find(2)
233 user = User.find(2)
214 assert_equal 'jsmith', user.login
234 assert_equal 'jsmith', user.login
215 assert_equal 'John', user.firstname
235 assert_equal 'John', user.firstname
216 assert_equal 'Renamed', user.lastname
236 assert_equal 'Renamed', user.lastname
217 assert_equal 'jsmith@somenet.foo', user.mail
237 assert_equal 'jsmith@somenet.foo', user.mail
218 assert !user.admin?
238 assert !user.admin?
219
239
220 assert_response :ok
240 assert_response :ok
221 assert_equal '', @response.body
241 assert_equal '', @response.body
222 end
242 end
223
243
224 test "PUT /users/:id.xml with invalid parameters" do
244 test "PUT /users/:id.xml with invalid parameters" do
225 assert_no_difference('User.count') do
245 assert_no_difference('User.count') do
226 put '/users/2.xml', {
246 put '/users/2.xml', {
227 :user => {
247 :user => {
228 :login => 'jsmith', :firstname => '', :lastname => 'Lastname',
248 :login => 'jsmith', :firstname => '', :lastname => 'Lastname',
229 :mail => 'foo'}
249 :mail => 'foo'}
230 },
250 },
231 credentials('admin')
251 credentials('admin')
232 end
252 end
233
253
234 assert_response :unprocessable_entity
254 assert_response :unprocessable_entity
235 assert_equal 'application/xml', @response.content_type
255 assert_equal 'application/xml', @response.content_type
236 assert_select 'errors error', :text => "First name can't be blank"
256 assert_select 'errors error', :text => "First name can't be blank"
237 end
257 end
238
258
239 test "PUT /users/:id.json with invalid parameters" do
259 test "PUT /users/:id.json with invalid parameters" do
240 assert_no_difference('User.count') do
260 assert_no_difference('User.count') do
241 put '/users/2.json', {
261 put '/users/2.json', {
242 :user => {
262 :user => {
243 :login => 'jsmith', :firstname => '', :lastname => 'Lastname',
263 :login => 'jsmith', :firstname => '', :lastname => 'Lastname',
244 :mail => 'foo'}
264 :mail => 'foo'}
245 },
265 },
246 credentials('admin')
266 credentials('admin')
247 end
267 end
248
268
249 assert_response :unprocessable_entity
269 assert_response :unprocessable_entity
250 assert_equal 'application/json', @response.content_type
270 assert_equal 'application/json', @response.content_type
251 json = ActiveSupport::JSON.decode(response.body)
271 json = ActiveSupport::JSON.decode(response.body)
252 assert_kind_of Hash, json
272 assert_kind_of Hash, json
253 assert json.has_key?('errors')
273 assert json.has_key?('errors')
254 assert_kind_of Array, json['errors']
274 assert_kind_of Array, json['errors']
255 end
275 end
256
276
257 test "DELETE /users/:id.xml should delete the user" do
277 test "DELETE /users/:id.xml should delete the user" do
258 assert_difference('User.count', -1) do
278 assert_difference('User.count', -1) do
259 delete '/users/2.xml', {}, credentials('admin')
279 delete '/users/2.xml', {}, credentials('admin')
260 end
280 end
261
281
262 assert_response :ok
282 assert_response :ok
263 assert_equal '', @response.body
283 assert_equal '', @response.body
264 end
284 end
265
285
266 test "DELETE /users/:id.json should delete the user" do
286 test "DELETE /users/:id.json should delete the user" do
267 assert_difference('User.count', -1) do
287 assert_difference('User.count', -1) do
268 delete '/users/2.json', {}, credentials('admin')
288 delete '/users/2.json', {}, credentials('admin')
269 end
289 end
270
290
271 assert_response :ok
291 assert_response :ok
272 assert_equal '', @response.body
292 assert_equal '', @response.body
273 end
293 end
274 end
294 end
@@ -1,135 +1,161
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 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 GroupTest < ActiveSupport::TestCase
20 class GroupTest < ActiveSupport::TestCase
21 fixtures :projects, :trackers, :issue_statuses, :issues,
21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 :enumerations, :users,
22 :enumerations, :users,
23 :projects_trackers,
23 :projects_trackers,
24 :roles,
24 :roles,
25 :member_roles,
25 :member_roles,
26 :members,
26 :members,
27 :groups_users
27 :groups_users
28
28
29 include Redmine::I18n
29 include Redmine::I18n
30
30
31 def test_create
31 def test_create
32 g = Group.new(:name => 'New group')
32 g = Group.new(:name => 'New group')
33 assert g.save
33 assert g.save
34 g.reload
34 g.reload
35 assert_equal 'New group', g.name
35 assert_equal 'New group', g.name
36 end
36 end
37
37
38 def test_name_should_accept_255_characters
38 def test_name_should_accept_255_characters
39 name = 'a' * 255
39 name = 'a' * 255
40 g = Group.new(:name => name)
40 g = Group.new(:name => name)
41 assert g.save
41 assert g.save
42 g.reload
42 g.reload
43 assert_equal name, g.name
43 assert_equal name, g.name
44 end
44 end
45
45
46 def test_blank_name_error_message
46 def test_blank_name_error_message
47 set_language_if_valid 'en'
47 set_language_if_valid 'en'
48 g = Group.new
48 g = Group.new
49 assert !g.save
49 assert !g.save
50 assert_include "Name can't be blank", g.errors.full_messages
50 assert_include "Name can't be blank", g.errors.full_messages
51 end
51 end
52
52
53 def test_blank_name_error_message_fr
53 def test_blank_name_error_message_fr
54 set_language_if_valid 'fr'
54 set_language_if_valid 'fr'
55 str = "Nom doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8')
55 str = "Nom doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8')
56 g = Group.new
56 g = Group.new
57 assert !g.save
57 assert !g.save
58 assert_include str, g.errors.full_messages
58 assert_include str, g.errors.full_messages
59 end
59 end
60
60
61 def test_group_roles_should_be_given_to_added_user
61 def test_group_roles_should_be_given_to_added_user
62 group = Group.find(11)
62 group = Group.find(11)
63 user = User.find(9)
63 user = User.find(9)
64 project = Project.first
64 project = Project.first
65
65
66 Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
66 Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
67 group.users << user
67 group.users << user
68 assert user.member_of?(project)
68 assert user.member_of?(project)
69 end
69 end
70
70
71 def test_new_roles_should_be_given_to_existing_user
71 def test_new_roles_should_be_given_to_existing_user
72 group = Group.find(11)
72 group = Group.find(11)
73 user = User.find(9)
73 user = User.find(9)
74 project = Project.first
74 project = Project.first
75
75
76 group.users << user
76 group.users << user
77 m = Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
77 m = Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
78 assert user.member_of?(project)
78 assert user.member_of?(project)
79 end
79 end
80
80
81 def test_user_roles_should_updated_when_updating_user_ids
81 def test_user_roles_should_updated_when_updating_user_ids
82 group = Group.find(11)
82 group = Group.find(11)
83 user = User.find(9)
83 user = User.find(9)
84 project = Project.first
84 project = Project.first
85
85
86 Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
86 Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
87 group.user_ids = [user.id]
87 group.user_ids = [user.id]
88 group.save!
88 group.save!
89 assert User.find(9).member_of?(project)
89 assert User.find(9).member_of?(project)
90
90
91 group.user_ids = [1]
91 group.user_ids = [1]
92 group.save!
92 group.save!
93 assert !User.find(9).member_of?(project)
93 assert !User.find(9).member_of?(project)
94 end
94 end
95
95
96 def test_user_roles_should_updated_when_updating_group_roles
96 def test_user_roles_should_updated_when_updating_group_roles
97 group = Group.find(11)
97 group = Group.find(11)
98 user = User.find(9)
98 user = User.find(9)
99 project = Project.first
99 project = Project.first
100 group.users << user
100 group.users << user
101 m = Member.create!(:principal => group, :project => project, :role_ids => [1])
101 m = Member.create!(:principal => group, :project => project, :role_ids => [1])
102 assert_equal [1], user.reload.roles_for_project(project).collect(&:id).sort
102 assert_equal [1], user.reload.roles_for_project(project).collect(&:id).sort
103
103
104 m.role_ids = [1, 2]
104 m.role_ids = [1, 2]
105 assert_equal [1, 2], user.reload.roles_for_project(project).collect(&:id).sort
105 assert_equal [1, 2], user.reload.roles_for_project(project).collect(&:id).sort
106
106
107 m.role_ids = [2]
107 m.role_ids = [2]
108 assert_equal [2], user.reload.roles_for_project(project).collect(&:id).sort
108 assert_equal [2], user.reload.roles_for_project(project).collect(&:id).sort
109
109
110 m.role_ids = [1]
110 m.role_ids = [1]
111 assert_equal [1], user.reload.roles_for_project(project).collect(&:id).sort
111 assert_equal [1], user.reload.roles_for_project(project).collect(&:id).sort
112 end
112 end
113
113
114 def test_user_memberships_should_be_removed_when_removing_group_membership
114 def test_user_memberships_should_be_removed_when_removing_group_membership
115 assert User.find(8).member_of?(Project.find(5))
115 assert User.find(8).member_of?(Project.find(5))
116 Member.find_by_project_id_and_user_id(5, 10).destroy
116 Member.find_by_project_id_and_user_id(5, 10).destroy
117 assert !User.find(8).member_of?(Project.find(5))
117 assert !User.find(8).member_of?(Project.find(5))
118 end
118 end
119
119
120 def test_user_roles_should_be_removed_when_removing_user_from_group
120 def test_user_roles_should_be_removed_when_removing_user_from_group
121 assert User.find(8).member_of?(Project.find(5))
121 assert User.find(8).member_of?(Project.find(5))
122 User.find(8).groups = []
122 User.find(8).groups = []
123 assert !User.find(8).member_of?(Project.find(5))
123 assert !User.find(8).member_of?(Project.find(5))
124 end
124 end
125
125
126 def test_destroy_should_unassign_issues
126 def test_destroy_should_unassign_issues
127 group = Group.find(10)
127 group = Group.find(10)
128 Issue.where(:id => 1).update_all(["assigned_to_id = ?", group.id])
128 Issue.where(:id => 1).update_all(["assigned_to_id = ?", group.id])
129
129
130 assert group.destroy
130 assert group.destroy
131 assert group.destroyed?
131 assert group.destroyed?
132
132
133 assert_equal nil, Issue.find(1).assigned_to_id
133 assert_equal nil, Issue.find(1).assigned_to_id
134 end
134 end
135
136 def test_builtin_groups_should_be_created_if_missing
137 Group.delete_all
138
139 assert_difference 'Group.count', 2 do
140 group = Group.anonymous
141 assert_equal GroupAnonymous, group.class
142
143 group = Group.non_member
144 assert_equal GroupNonMember, group.class
145 end
146 end
147
148 def test_builtin_in_group_should_be_uniq
149 group = GroupAnonymous.new
150 group.name = 'Foo'
151 assert !group.save
152 end
153
154 def test_builtin_in_group_should_not_accept_users
155 group = Group.anonymous
156 assert_raise RuntimeError do
157 group.users << User.find(1)
158 end
159 assert_equal 0, group.reload.users.count
160 end
135 end
161 end
@@ -1,950 +1,975
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 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 ProjectTest < ActiveSupport::TestCase
20 class ProjectTest < ActiveSupport::TestCase
21 fixtures :projects, :trackers, :issue_statuses, :issues,
21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 :journals, :journal_details,
22 :journals, :journal_details,
23 :enumerations, :users, :issue_categories,
23 :enumerations, :users, :issue_categories,
24 :projects_trackers,
24 :projects_trackers,
25 :custom_fields,
25 :custom_fields,
26 :custom_fields_projects,
26 :custom_fields_projects,
27 :custom_fields_trackers,
27 :custom_fields_trackers,
28 :custom_values,
28 :custom_values,
29 :roles,
29 :roles,
30 :member_roles,
30 :member_roles,
31 :members,
31 :members,
32 :enabled_modules,
32 :enabled_modules,
33 :versions,
33 :versions,
34 :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
34 :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
35 :groups_users,
35 :groups_users,
36 :boards, :messages,
36 :boards, :messages,
37 :repositories,
37 :repositories,
38 :news, :comments,
38 :news, :comments,
39 :documents,
39 :documents,
40 :workflows
40 :workflows
41
41
42 def setup
42 def setup
43 @ecookbook = Project.find(1)
43 @ecookbook = Project.find(1)
44 @ecookbook_sub1 = Project.find(3)
44 @ecookbook_sub1 = Project.find(3)
45 set_tmp_attachments_directory
45 set_tmp_attachments_directory
46 User.current = nil
46 User.current = nil
47 end
47 end
48
48
49 def test_truth
49 def test_truth
50 assert_kind_of Project, @ecookbook
50 assert_kind_of Project, @ecookbook
51 assert_equal "eCookbook", @ecookbook.name
51 assert_equal "eCookbook", @ecookbook.name
52 end
52 end
53
53
54 def test_default_attributes
54 def test_default_attributes
55 with_settings :default_projects_public => '1' do
55 with_settings :default_projects_public => '1' do
56 assert_equal true, Project.new.is_public
56 assert_equal true, Project.new.is_public
57 assert_equal false, Project.new(:is_public => false).is_public
57 assert_equal false, Project.new(:is_public => false).is_public
58 end
58 end
59
59
60 with_settings :default_projects_public => '0' do
60 with_settings :default_projects_public => '0' do
61 assert_equal false, Project.new.is_public
61 assert_equal false, Project.new.is_public
62 assert_equal true, Project.new(:is_public => true).is_public
62 assert_equal true, Project.new(:is_public => true).is_public
63 end
63 end
64
64
65 with_settings :sequential_project_identifiers => '1' do
65 with_settings :sequential_project_identifiers => '1' do
66 assert !Project.new.identifier.blank?
66 assert !Project.new.identifier.blank?
67 assert Project.new(:identifier => '').identifier.blank?
67 assert Project.new(:identifier => '').identifier.blank?
68 end
68 end
69
69
70 with_settings :sequential_project_identifiers => '0' do
70 with_settings :sequential_project_identifiers => '0' do
71 assert Project.new.identifier.blank?
71 assert Project.new.identifier.blank?
72 assert !Project.new(:identifier => 'test').blank?
72 assert !Project.new(:identifier => 'test').blank?
73 end
73 end
74
74
75 with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
75 with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
76 assert_equal ['issue_tracking', 'repository'], Project.new.enabled_module_names
76 assert_equal ['issue_tracking', 'repository'], Project.new.enabled_module_names
77 end
77 end
78 end
78 end
79
79
80 def test_default_trackers_should_match_default_tracker_ids_setting
80 def test_default_trackers_should_match_default_tracker_ids_setting
81 with_settings :default_projects_tracker_ids => ['1', '3'] do
81 with_settings :default_projects_tracker_ids => ['1', '3'] do
82 assert_equal Tracker.find(1, 3).sort, Project.new.trackers.sort
82 assert_equal Tracker.find(1, 3).sort, Project.new.trackers.sort
83 end
83 end
84 end
84 end
85
85
86 def test_default_trackers_should_be_all_trackers_with_blank_setting
86 def test_default_trackers_should_be_all_trackers_with_blank_setting
87 with_settings :default_projects_tracker_ids => nil do
87 with_settings :default_projects_tracker_ids => nil do
88 assert_equal Tracker.all.sort, Project.new.trackers.sort
88 assert_equal Tracker.all.sort, Project.new.trackers.sort
89 end
89 end
90 end
90 end
91
91
92 def test_default_trackers_should_be_empty_with_empty_setting
92 def test_default_trackers_should_be_empty_with_empty_setting
93 with_settings :default_projects_tracker_ids => [] do
93 with_settings :default_projects_tracker_ids => [] do
94 assert_equal [], Project.new.trackers
94 assert_equal [], Project.new.trackers
95 end
95 end
96 end
96 end
97
97
98 def test_default_trackers_should_not_replace_initialized_trackers
98 def test_default_trackers_should_not_replace_initialized_trackers
99 with_settings :default_projects_tracker_ids => ['1', '3'] do
99 with_settings :default_projects_tracker_ids => ['1', '3'] do
100 assert_equal Tracker.find(1, 2).sort, Project.new(:tracker_ids => [1, 2]).trackers.sort
100 assert_equal Tracker.find(1, 2).sort, Project.new(:tracker_ids => [1, 2]).trackers.sort
101 end
101 end
102 end
102 end
103
103
104 def test_update
104 def test_update
105 assert_equal "eCookbook", @ecookbook.name
105 assert_equal "eCookbook", @ecookbook.name
106 @ecookbook.name = "eCook"
106 @ecookbook.name = "eCook"
107 assert @ecookbook.save, @ecookbook.errors.full_messages.join("; ")
107 assert @ecookbook.save, @ecookbook.errors.full_messages.join("; ")
108 @ecookbook.reload
108 @ecookbook.reload
109 assert_equal "eCook", @ecookbook.name
109 assert_equal "eCook", @ecookbook.name
110 end
110 end
111
111
112 def test_validate_identifier
112 def test_validate_identifier
113 to_test = {"abc" => true,
113 to_test = {"abc" => true,
114 "ab12" => true,
114 "ab12" => true,
115 "ab-12" => true,
115 "ab-12" => true,
116 "ab_12" => true,
116 "ab_12" => true,
117 "12" => false,
117 "12" => false,
118 "new" => false}
118 "new" => false}
119
119
120 to_test.each do |identifier, valid|
120 to_test.each do |identifier, valid|
121 p = Project.new
121 p = Project.new
122 p.identifier = identifier
122 p.identifier = identifier
123 p.valid?
123 p.valid?
124 if valid
124 if valid
125 assert p.errors['identifier'].blank?, "identifier #{identifier} was not valid"
125 assert p.errors['identifier'].blank?, "identifier #{identifier} was not valid"
126 else
126 else
127 assert p.errors['identifier'].present?, "identifier #{identifier} was valid"
127 assert p.errors['identifier'].present?, "identifier #{identifier} was valid"
128 end
128 end
129 end
129 end
130 end
130 end
131
131
132 def test_identifier_should_not_be_frozen_for_a_new_project
132 def test_identifier_should_not_be_frozen_for_a_new_project
133 assert_equal false, Project.new.identifier_frozen?
133 assert_equal false, Project.new.identifier_frozen?
134 end
134 end
135
135
136 def test_identifier_should_not_be_frozen_for_a_saved_project_with_blank_identifier
136 def test_identifier_should_not_be_frozen_for_a_saved_project_with_blank_identifier
137 Project.where(:id => 1).update_all(["identifier = ''"])
137 Project.where(:id => 1).update_all(["identifier = ''"])
138 assert_equal false, Project.find(1).identifier_frozen?
138 assert_equal false, Project.find(1).identifier_frozen?
139 end
139 end
140
140
141 def test_identifier_should_be_frozen_for_a_saved_project_with_valid_identifier
141 def test_identifier_should_be_frozen_for_a_saved_project_with_valid_identifier
142 assert_equal true, Project.find(1).identifier_frozen?
142 assert_equal true, Project.find(1).identifier_frozen?
143 end
143 end
144
144
145 def test_members_should_be_active_users
145 def test_members_should_be_active_users
146 Project.all.each do |project|
146 Project.all.each do |project|
147 assert_nil project.members.detect {|m| !(m.user.is_a?(User) && m.user.active?) }
147 assert_nil project.members.detect {|m| !(m.user.is_a?(User) && m.user.active?) }
148 end
148 end
149 end
149 end
150
150
151 def test_users_should_be_active_users
151 def test_users_should_be_active_users
152 Project.all.each do |project|
152 Project.all.each do |project|
153 assert_nil project.users.detect {|u| !(u.is_a?(User) && u.active?) }
153 assert_nil project.users.detect {|u| !(u.is_a?(User) && u.active?) }
154 end
154 end
155 end
155 end
156
156
157 def test_open_scope_on_issues_association
157 def test_open_scope_on_issues_association
158 assert_kind_of Issue, Project.find(1).issues.open.first
158 assert_kind_of Issue, Project.find(1).issues.open.first
159 end
159 end
160
160
161 def test_archive
161 def test_archive
162 user = @ecookbook.members.first.user
162 user = @ecookbook.members.first.user
163 @ecookbook.archive
163 @ecookbook.archive
164 @ecookbook.reload
164 @ecookbook.reload
165
165
166 assert !@ecookbook.active?
166 assert !@ecookbook.active?
167 assert @ecookbook.archived?
167 assert @ecookbook.archived?
168 assert !user.projects.include?(@ecookbook)
168 assert !user.projects.include?(@ecookbook)
169 # Subproject are also archived
169 # Subproject are also archived
170 assert !@ecookbook.children.empty?
170 assert !@ecookbook.children.empty?
171 assert @ecookbook.descendants.active.empty?
171 assert @ecookbook.descendants.active.empty?
172 end
172 end
173
173
174 def test_archive_should_fail_if_versions_are_used_by_non_descendant_projects
174 def test_archive_should_fail_if_versions_are_used_by_non_descendant_projects
175 # Assign an issue of a project to a version of a child project
175 # Assign an issue of a project to a version of a child project
176 Issue.find(4).update_attribute :fixed_version_id, 4
176 Issue.find(4).update_attribute :fixed_version_id, 4
177
177
178 assert_no_difference "Project.where(:status => Project::STATUS_ARCHIVED).count" do
178 assert_no_difference "Project.where(:status => Project::STATUS_ARCHIVED).count" do
179 assert_equal false, @ecookbook.archive
179 assert_equal false, @ecookbook.archive
180 end
180 end
181 @ecookbook.reload
181 @ecookbook.reload
182 assert @ecookbook.active?
182 assert @ecookbook.active?
183 end
183 end
184
184
185 def test_unarchive
185 def test_unarchive
186 user = @ecookbook.members.first.user
186 user = @ecookbook.members.first.user
187 @ecookbook.archive
187 @ecookbook.archive
188 # A subproject of an archived project can not be unarchived
188 # A subproject of an archived project can not be unarchived
189 assert !@ecookbook_sub1.unarchive
189 assert !@ecookbook_sub1.unarchive
190
190
191 # Unarchive project
191 # Unarchive project
192 assert @ecookbook.unarchive
192 assert @ecookbook.unarchive
193 @ecookbook.reload
193 @ecookbook.reload
194 assert @ecookbook.active?
194 assert @ecookbook.active?
195 assert !@ecookbook.archived?
195 assert !@ecookbook.archived?
196 assert user.projects.include?(@ecookbook)
196 assert user.projects.include?(@ecookbook)
197 # Subproject can now be unarchived
197 # Subproject can now be unarchived
198 @ecookbook_sub1.reload
198 @ecookbook_sub1.reload
199 assert @ecookbook_sub1.unarchive
199 assert @ecookbook_sub1.unarchive
200 end
200 end
201
201
202 def test_destroy
202 def test_destroy
203 # 2 active members
203 # 2 active members
204 assert_equal 2, @ecookbook.members.size
204 assert_equal 2, @ecookbook.members.size
205 # and 1 is locked
205 # and 1 is locked
206 assert_equal 3, Member.where(:project_id => @ecookbook.id).count
206 assert_equal 3, Member.where(:project_id => @ecookbook.id).count
207 # some boards
207 # some boards
208 assert @ecookbook.boards.any?
208 assert @ecookbook.boards.any?
209
209
210 @ecookbook.destroy
210 @ecookbook.destroy
211 # make sure that the project non longer exists
211 # make sure that the project non longer exists
212 assert_raise(ActiveRecord::RecordNotFound) { Project.find(@ecookbook.id) }
212 assert_raise(ActiveRecord::RecordNotFound) { Project.find(@ecookbook.id) }
213 # make sure related data was removed
213 # make sure related data was removed
214 assert_nil Member.where(:project_id => @ecookbook.id).first
214 assert_nil Member.where(:project_id => @ecookbook.id).first
215 assert_nil Board.where(:project_id => @ecookbook.id).first
215 assert_nil Board.where(:project_id => @ecookbook.id).first
216 assert_nil Issue.where(:project_id => @ecookbook.id).first
216 assert_nil Issue.where(:project_id => @ecookbook.id).first
217 end
217 end
218
218
219 def test_destroy_should_destroy_subtasks
219 def test_destroy_should_destroy_subtasks
220 issues = (0..2).to_a.map {Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'test')}
220 issues = (0..2).to_a.map {Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'test')}
221 issues[0].update_attribute :parent_issue_id, issues[1].id
221 issues[0].update_attribute :parent_issue_id, issues[1].id
222 issues[2].update_attribute :parent_issue_id, issues[1].id
222 issues[2].update_attribute :parent_issue_id, issues[1].id
223 assert_equal 2, issues[1].children.count
223 assert_equal 2, issues[1].children.count
224
224
225 assert_nothing_raised do
225 assert_nothing_raised do
226 Project.find(1).destroy
226 Project.find(1).destroy
227 end
227 end
228 assert_equal 0, Issue.where(:id => issues.map(&:id)).count
228 assert_equal 0, Issue.where(:id => issues.map(&:id)).count
229 end
229 end
230
230
231 def test_destroying_root_projects_should_clear_data
231 def test_destroying_root_projects_should_clear_data
232 Project.roots.each do |root|
232 Project.roots.each do |root|
233 root.destroy
233 root.destroy
234 end
234 end
235
235
236 assert_equal 0, Project.count, "Projects were not deleted: #{Project.all.inspect}"
236 assert_equal 0, Project.count, "Projects were not deleted: #{Project.all.inspect}"
237 assert_equal 0, Member.count, "Members were not deleted: #{Member.all.inspect}"
237 assert_equal 0, Member.count, "Members were not deleted: #{Member.all.inspect}"
238 assert_equal 0, MemberRole.count
238 assert_equal 0, MemberRole.count
239 assert_equal 0, Issue.count
239 assert_equal 0, Issue.count
240 assert_equal 0, Journal.count
240 assert_equal 0, Journal.count
241 assert_equal 0, JournalDetail.count
241 assert_equal 0, JournalDetail.count
242 assert_equal 0, Attachment.count, "Attachments were not deleted: #{Attachment.all.inspect}"
242 assert_equal 0, Attachment.count, "Attachments were not deleted: #{Attachment.all.inspect}"
243 assert_equal 0, EnabledModule.count
243 assert_equal 0, EnabledModule.count
244 assert_equal 0, IssueCategory.count
244 assert_equal 0, IssueCategory.count
245 assert_equal 0, IssueRelation.count
245 assert_equal 0, IssueRelation.count
246 assert_equal 0, Board.count
246 assert_equal 0, Board.count
247 assert_equal 0, Message.count
247 assert_equal 0, Message.count
248 assert_equal 0, News.count
248 assert_equal 0, News.count
249 assert_equal 0, Query.where("project_id IS NOT NULL").count
249 assert_equal 0, Query.where("project_id IS NOT NULL").count
250 assert_equal 0, Repository.count
250 assert_equal 0, Repository.count
251 assert_equal 0, Changeset.count
251 assert_equal 0, Changeset.count
252 assert_equal 0, Change.count
252 assert_equal 0, Change.count
253 assert_equal 0, Comment.count
253 assert_equal 0, Comment.count
254 assert_equal 0, TimeEntry.count
254 assert_equal 0, TimeEntry.count
255 assert_equal 0, Version.count
255 assert_equal 0, Version.count
256 assert_equal 0, Watcher.count
256 assert_equal 0, Watcher.count
257 assert_equal 0, Wiki.count
257 assert_equal 0, Wiki.count
258 assert_equal 0, WikiPage.count
258 assert_equal 0, WikiPage.count
259 assert_equal 0, WikiContent.count
259 assert_equal 0, WikiContent.count
260 assert_equal 0, WikiContent::Version.count
260 assert_equal 0, WikiContent::Version.count
261 assert_equal 0, Project.connection.select_all("SELECT * FROM projects_trackers").count
261 assert_equal 0, Project.connection.select_all("SELECT * FROM projects_trackers").count
262 assert_equal 0, Project.connection.select_all("SELECT * FROM custom_fields_projects").count
262 assert_equal 0, Project.connection.select_all("SELECT * FROM custom_fields_projects").count
263 assert_equal 0, CustomValue.where(:customized_type => ['Project', 'Issue', 'TimeEntry', 'Version']).count
263 assert_equal 0, CustomValue.where(:customized_type => ['Project', 'Issue', 'TimeEntry', 'Version']).count
264 end
264 end
265
265
266 def test_destroy_should_delete_time_entries_custom_values
266 def test_destroy_should_delete_time_entries_custom_values
267 project = Project.generate!
267 project = Project.generate!
268 time_entry = TimeEntry.generate!(:project => project, :custom_field_values => {10 => '1'})
268 time_entry = TimeEntry.generate!(:project => project, :custom_field_values => {10 => '1'})
269
269
270 assert_difference 'CustomValue.where(:customized_type => "TimeEntry").count', -1 do
270 assert_difference 'CustomValue.where(:customized_type => "TimeEntry").count', -1 do
271 assert project.destroy
271 assert project.destroy
272 end
272 end
273 end
273 end
274
274
275 def test_move_an_orphan_project_to_a_root_project
275 def test_move_an_orphan_project_to_a_root_project
276 sub = Project.find(2)
276 sub = Project.find(2)
277 sub.set_parent! @ecookbook
277 sub.set_parent! @ecookbook
278 assert_equal @ecookbook.id, sub.parent.id
278 assert_equal @ecookbook.id, sub.parent.id
279 @ecookbook.reload
279 @ecookbook.reload
280 assert_equal 4, @ecookbook.children.size
280 assert_equal 4, @ecookbook.children.size
281 end
281 end
282
282
283 def test_move_an_orphan_project_to_a_subproject
283 def test_move_an_orphan_project_to_a_subproject
284 sub = Project.find(2)
284 sub = Project.find(2)
285 assert sub.set_parent!(@ecookbook_sub1)
285 assert sub.set_parent!(@ecookbook_sub1)
286 end
286 end
287
287
288 def test_move_a_root_project_to_a_project
288 def test_move_a_root_project_to_a_project
289 sub = @ecookbook
289 sub = @ecookbook
290 assert sub.set_parent!(Project.find(2))
290 assert sub.set_parent!(Project.find(2))
291 end
291 end
292
292
293 def test_should_not_move_a_project_to_its_children
293 def test_should_not_move_a_project_to_its_children
294 sub = @ecookbook
294 sub = @ecookbook
295 assert !(sub.set_parent!(Project.find(3)))
295 assert !(sub.set_parent!(Project.find(3)))
296 end
296 end
297
297
298 def test_set_parent_should_add_roots_in_alphabetical_order
298 def test_set_parent_should_add_roots_in_alphabetical_order
299 ProjectCustomField.delete_all
299 ProjectCustomField.delete_all
300 Project.delete_all
300 Project.delete_all
301 Project.create!(:name => 'Project C', :identifier => 'project-c').set_parent!(nil)
301 Project.create!(:name => 'Project C', :identifier => 'project-c').set_parent!(nil)
302 Project.create!(:name => 'Project B', :identifier => 'project-b').set_parent!(nil)
302 Project.create!(:name => 'Project B', :identifier => 'project-b').set_parent!(nil)
303 Project.create!(:name => 'Project D', :identifier => 'project-d').set_parent!(nil)
303 Project.create!(:name => 'Project D', :identifier => 'project-d').set_parent!(nil)
304 Project.create!(:name => 'Project A', :identifier => 'project-a').set_parent!(nil)
304 Project.create!(:name => 'Project A', :identifier => 'project-a').set_parent!(nil)
305
305
306 assert_equal 4, Project.count
306 assert_equal 4, Project.count
307 assert_equal Project.all.sort_by(&:name), Project.all.sort_by(&:lft)
307 assert_equal Project.all.sort_by(&:name), Project.all.sort_by(&:lft)
308 end
308 end
309
309
310 def test_set_parent_should_add_children_in_alphabetical_order
310 def test_set_parent_should_add_children_in_alphabetical_order
311 ProjectCustomField.delete_all
311 ProjectCustomField.delete_all
312 parent = Project.create!(:name => 'Parent', :identifier => 'parent')
312 parent = Project.create!(:name => 'Parent', :identifier => 'parent')
313 Project.create!(:name => 'Project C', :identifier => 'project-c').set_parent!(parent)
313 Project.create!(:name => 'Project C', :identifier => 'project-c').set_parent!(parent)
314 Project.create!(:name => 'Project B', :identifier => 'project-b').set_parent!(parent)
314 Project.create!(:name => 'Project B', :identifier => 'project-b').set_parent!(parent)
315 Project.create!(:name => 'Project D', :identifier => 'project-d').set_parent!(parent)
315 Project.create!(:name => 'Project D', :identifier => 'project-d').set_parent!(parent)
316 Project.create!(:name => 'Project A', :identifier => 'project-a').set_parent!(parent)
316 Project.create!(:name => 'Project A', :identifier => 'project-a').set_parent!(parent)
317
317
318 parent.reload
318 parent.reload
319 assert_equal 4, parent.children.size
319 assert_equal 4, parent.children.size
320 assert_equal parent.children.sort_by(&:name), parent.children.to_a
320 assert_equal parent.children.sort_by(&:name), parent.children.to_a
321 end
321 end
322
322
323 def test_set_parent_should_update_issue_fixed_version_associations_when_a_fixed_version_is_moved_out_of_the_hierarchy
323 def test_set_parent_should_update_issue_fixed_version_associations_when_a_fixed_version_is_moved_out_of_the_hierarchy
324 # Parent issue with a hierarchy project's fixed version
324 # Parent issue with a hierarchy project's fixed version
325 parent_issue = Issue.find(1)
325 parent_issue = Issue.find(1)
326 parent_issue.update_attribute(:fixed_version_id, 4)
326 parent_issue.update_attribute(:fixed_version_id, 4)
327 parent_issue.reload
327 parent_issue.reload
328 assert_equal 4, parent_issue.fixed_version_id
328 assert_equal 4, parent_issue.fixed_version_id
329
329
330 # Should keep fixed versions for the issues
330 # Should keep fixed versions for the issues
331 issue_with_local_fixed_version = Issue.find(5)
331 issue_with_local_fixed_version = Issue.find(5)
332 issue_with_local_fixed_version.update_attribute(:fixed_version_id, 4)
332 issue_with_local_fixed_version.update_attribute(:fixed_version_id, 4)
333 issue_with_local_fixed_version.reload
333 issue_with_local_fixed_version.reload
334 assert_equal 4, issue_with_local_fixed_version.fixed_version_id
334 assert_equal 4, issue_with_local_fixed_version.fixed_version_id
335
335
336 # Local issue with hierarchy fixed_version
336 # Local issue with hierarchy fixed_version
337 issue_with_hierarchy_fixed_version = Issue.find(13)
337 issue_with_hierarchy_fixed_version = Issue.find(13)
338 issue_with_hierarchy_fixed_version.update_attribute(:fixed_version_id, 6)
338 issue_with_hierarchy_fixed_version.update_attribute(:fixed_version_id, 6)
339 issue_with_hierarchy_fixed_version.reload
339 issue_with_hierarchy_fixed_version.reload
340 assert_equal 6, issue_with_hierarchy_fixed_version.fixed_version_id
340 assert_equal 6, issue_with_hierarchy_fixed_version.fixed_version_id
341
341
342 # Move project out of the issue's hierarchy
342 # Move project out of the issue's hierarchy
343 moved_project = Project.find(3)
343 moved_project = Project.find(3)
344 moved_project.set_parent!(Project.find(2))
344 moved_project.set_parent!(Project.find(2))
345 parent_issue.reload
345 parent_issue.reload
346 issue_with_local_fixed_version.reload
346 issue_with_local_fixed_version.reload
347 issue_with_hierarchy_fixed_version.reload
347 issue_with_hierarchy_fixed_version.reload
348
348
349 assert_equal 4, issue_with_local_fixed_version.fixed_version_id, "Fixed version was not keep on an issue local to the moved project"
349 assert_equal 4, issue_with_local_fixed_version.fixed_version_id, "Fixed version was not keep on an issue local to the moved project"
350 assert_equal nil, issue_with_hierarchy_fixed_version.fixed_version_id, "Fixed version is still set after moving the Project out of the hierarchy where the version is defined in"
350 assert_equal nil, issue_with_hierarchy_fixed_version.fixed_version_id, "Fixed version is still set after moving the Project out of the hierarchy where the version is defined in"
351 assert_equal nil, parent_issue.fixed_version_id, "Fixed version is still set after moving the Version out of the hierarchy for the issue."
351 assert_equal nil, parent_issue.fixed_version_id, "Fixed version is still set after moving the Version out of the hierarchy for the issue."
352 end
352 end
353
353
354 def test_parent
354 def test_parent
355 p = Project.find(6).parent
355 p = Project.find(6).parent
356 assert p.is_a?(Project)
356 assert p.is_a?(Project)
357 assert_equal 5, p.id
357 assert_equal 5, p.id
358 end
358 end
359
359
360 def test_ancestors
360 def test_ancestors
361 a = Project.find(6).ancestors
361 a = Project.find(6).ancestors
362 assert a.first.is_a?(Project)
362 assert a.first.is_a?(Project)
363 assert_equal [1, 5], a.collect(&:id)
363 assert_equal [1, 5], a.collect(&:id)
364 end
364 end
365
365
366 def test_root
366 def test_root
367 r = Project.find(6).root
367 r = Project.find(6).root
368 assert r.is_a?(Project)
368 assert r.is_a?(Project)
369 assert_equal 1, r.id
369 assert_equal 1, r.id
370 end
370 end
371
371
372 def test_children
372 def test_children
373 c = Project.find(1).children
373 c = Project.find(1).children
374 assert c.first.is_a?(Project)
374 assert c.first.is_a?(Project)
375 assert_equal [5, 3, 4], c.collect(&:id)
375 assert_equal [5, 3, 4], c.collect(&:id)
376 end
376 end
377
377
378 def test_descendants
378 def test_descendants
379 d = Project.find(1).descendants
379 d = Project.find(1).descendants
380 assert d.first.is_a?(Project)
380 assert d.first.is_a?(Project)
381 assert_equal [5, 6, 3, 4], d.collect(&:id)
381 assert_equal [5, 6, 3, 4], d.collect(&:id)
382 end
382 end
383
383
384 def test_allowed_parents_should_be_empty_for_non_member_user
384 def test_allowed_parents_should_be_empty_for_non_member_user
385 Role.non_member.add_permission!(:add_project)
385 Role.non_member.add_permission!(:add_project)
386 user = User.find(9)
386 user = User.find(9)
387 assert user.memberships.empty?
387 assert user.memberships.empty?
388 User.current = user
388 User.current = user
389 assert Project.new.allowed_parents.compact.empty?
389 assert Project.new.allowed_parents.compact.empty?
390 end
390 end
391
391
392 def test_allowed_parents_with_add_subprojects_permission
392 def test_allowed_parents_with_add_subprojects_permission
393 Role.find(1).remove_permission!(:add_project)
393 Role.find(1).remove_permission!(:add_project)
394 Role.find(1).add_permission!(:add_subprojects)
394 Role.find(1).add_permission!(:add_subprojects)
395 User.current = User.find(2)
395 User.current = User.find(2)
396 # new project
396 # new project
397 assert !Project.new.allowed_parents.include?(nil)
397 assert !Project.new.allowed_parents.include?(nil)
398 assert Project.new.allowed_parents.include?(Project.find(1))
398 assert Project.new.allowed_parents.include?(Project.find(1))
399 # existing root project
399 # existing root project
400 assert Project.find(1).allowed_parents.include?(nil)
400 assert Project.find(1).allowed_parents.include?(nil)
401 # existing child
401 # existing child
402 assert Project.find(3).allowed_parents.include?(Project.find(1))
402 assert Project.find(3).allowed_parents.include?(Project.find(1))
403 assert !Project.find(3).allowed_parents.include?(nil)
403 assert !Project.find(3).allowed_parents.include?(nil)
404 end
404 end
405
405
406 def test_allowed_parents_with_add_project_permission
406 def test_allowed_parents_with_add_project_permission
407 Role.find(1).add_permission!(:add_project)
407 Role.find(1).add_permission!(:add_project)
408 Role.find(1).remove_permission!(:add_subprojects)
408 Role.find(1).remove_permission!(:add_subprojects)
409 User.current = User.find(2)
409 User.current = User.find(2)
410 # new project
410 # new project
411 assert Project.new.allowed_parents.include?(nil)
411 assert Project.new.allowed_parents.include?(nil)
412 assert !Project.new.allowed_parents.include?(Project.find(1))
412 assert !Project.new.allowed_parents.include?(Project.find(1))
413 # existing root project
413 # existing root project
414 assert Project.find(1).allowed_parents.include?(nil)
414 assert Project.find(1).allowed_parents.include?(nil)
415 # existing child
415 # existing child
416 assert Project.find(3).allowed_parents.include?(Project.find(1))
416 assert Project.find(3).allowed_parents.include?(Project.find(1))
417 assert Project.find(3).allowed_parents.include?(nil)
417 assert Project.find(3).allowed_parents.include?(nil)
418 end
418 end
419
419
420 def test_allowed_parents_with_add_project_and_subprojects_permission
420 def test_allowed_parents_with_add_project_and_subprojects_permission
421 Role.find(1).add_permission!(:add_project)
421 Role.find(1).add_permission!(:add_project)
422 Role.find(1).add_permission!(:add_subprojects)
422 Role.find(1).add_permission!(:add_subprojects)
423 User.current = User.find(2)
423 User.current = User.find(2)
424 # new project
424 # new project
425 assert Project.new.allowed_parents.include?(nil)
425 assert Project.new.allowed_parents.include?(nil)
426 assert Project.new.allowed_parents.include?(Project.find(1))
426 assert Project.new.allowed_parents.include?(Project.find(1))
427 # existing root project
427 # existing root project
428 assert Project.find(1).allowed_parents.include?(nil)
428 assert Project.find(1).allowed_parents.include?(nil)
429 # existing child
429 # existing child
430 assert Project.find(3).allowed_parents.include?(Project.find(1))
430 assert Project.find(3).allowed_parents.include?(Project.find(1))
431 assert Project.find(3).allowed_parents.include?(nil)
431 assert Project.find(3).allowed_parents.include?(nil)
432 end
432 end
433
433
434 def test_users_by_role
434 def test_users_by_role
435 users_by_role = Project.find(1).users_by_role
435 users_by_role = Project.find(1).users_by_role
436 assert_kind_of Hash, users_by_role
436 assert_kind_of Hash, users_by_role
437 role = Role.find(1)
437 role = Role.find(1)
438 assert_kind_of Array, users_by_role[role]
438 assert_kind_of Array, users_by_role[role]
439 assert users_by_role[role].include?(User.find(2))
439 assert users_by_role[role].include?(User.find(2))
440 end
440 end
441
441
442 def test_rolled_up_trackers
442 def test_rolled_up_trackers
443 parent = Project.find(1)
443 parent = Project.find(1)
444 parent.trackers = Tracker.find([1,2])
444 parent.trackers = Tracker.find([1,2])
445 child = parent.children.find(3)
445 child = parent.children.find(3)
446
446
447 assert_equal [1, 2], parent.tracker_ids
447 assert_equal [1, 2], parent.tracker_ids
448 assert_equal [2, 3], child.trackers.collect(&:id)
448 assert_equal [2, 3], child.trackers.collect(&:id)
449
449
450 assert_kind_of Tracker, parent.rolled_up_trackers.first
450 assert_kind_of Tracker, parent.rolled_up_trackers.first
451 assert_equal Tracker.find(1), parent.rolled_up_trackers.first
451 assert_equal Tracker.find(1), parent.rolled_up_trackers.first
452
452
453 assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id)
453 assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id)
454 assert_equal [2, 3], child.rolled_up_trackers.collect(&:id)
454 assert_equal [2, 3], child.rolled_up_trackers.collect(&:id)
455 end
455 end
456
456
457 def test_rolled_up_trackers_should_ignore_archived_subprojects
457 def test_rolled_up_trackers_should_ignore_archived_subprojects
458 parent = Project.find(1)
458 parent = Project.find(1)
459 parent.trackers = Tracker.find([1,2])
459 parent.trackers = Tracker.find([1,2])
460 child = parent.children.find(3)
460 child = parent.children.find(3)
461 child.trackers = Tracker.find([1,3])
461 child.trackers = Tracker.find([1,3])
462 parent.children.each(&:archive)
462 parent.children.each(&:archive)
463
463
464 assert_equal [1,2], parent.rolled_up_trackers.collect(&:id)
464 assert_equal [1,2], parent.rolled_up_trackers.collect(&:id)
465 end
465 end
466
466
467 test "#rolled_up_trackers should ignore projects with issue_tracking module disabled" do
467 test "#rolled_up_trackers should ignore projects with issue_tracking module disabled" do
468 parent = Project.generate!
468 parent = Project.generate!
469 parent.trackers = Tracker.find([1, 2])
469 parent.trackers = Tracker.find([1, 2])
470 child = Project.generate_with_parent!(parent)
470 child = Project.generate_with_parent!(parent)
471 child.trackers = Tracker.find([2, 3])
471 child.trackers = Tracker.find([2, 3])
472
472
473 assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id).sort
473 assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id).sort
474
474
475 assert child.disable_module!(:issue_tracking)
475 assert child.disable_module!(:issue_tracking)
476 parent.reload
476 parent.reload
477 assert_equal [1, 2], parent.rolled_up_trackers.collect(&:id).sort
477 assert_equal [1, 2], parent.rolled_up_trackers.collect(&:id).sort
478 end
478 end
479
479
480 test "#rolled_up_versions should include the versions for the current project" do
480 test "#rolled_up_versions should include the versions for the current project" do
481 project = Project.generate!
481 project = Project.generate!
482 parent_version_1 = Version.generate!(:project => project)
482 parent_version_1 = Version.generate!(:project => project)
483 parent_version_2 = Version.generate!(:project => project)
483 parent_version_2 = Version.generate!(:project => project)
484 assert_equal [parent_version_1, parent_version_2].sort,
484 assert_equal [parent_version_1, parent_version_2].sort,
485 project.rolled_up_versions.sort
485 project.rolled_up_versions.sort
486 end
486 end
487
487
488 test "#rolled_up_versions should include versions for a subproject" do
488 test "#rolled_up_versions should include versions for a subproject" do
489 project = Project.generate!
489 project = Project.generate!
490 parent_version_1 = Version.generate!(:project => project)
490 parent_version_1 = Version.generate!(:project => project)
491 parent_version_2 = Version.generate!(:project => project)
491 parent_version_2 = Version.generate!(:project => project)
492 subproject = Project.generate_with_parent!(project)
492 subproject = Project.generate_with_parent!(project)
493 subproject_version = Version.generate!(:project => subproject)
493 subproject_version = Version.generate!(:project => subproject)
494
494
495 assert_equal [parent_version_1, parent_version_2, subproject_version].sort,
495 assert_equal [parent_version_1, parent_version_2, subproject_version].sort,
496 project.rolled_up_versions.sort
496 project.rolled_up_versions.sort
497 end
497 end
498
498
499 test "#rolled_up_versions should include versions for a sub-subproject" do
499 test "#rolled_up_versions should include versions for a sub-subproject" do
500 project = Project.generate!
500 project = Project.generate!
501 parent_version_1 = Version.generate!(:project => project)
501 parent_version_1 = Version.generate!(:project => project)
502 parent_version_2 = Version.generate!(:project => project)
502 parent_version_2 = Version.generate!(:project => project)
503 subproject = Project.generate_with_parent!(project)
503 subproject = Project.generate_with_parent!(project)
504 sub_subproject = Project.generate_with_parent!(subproject)
504 sub_subproject = Project.generate_with_parent!(subproject)
505 sub_subproject_version = Version.generate!(:project => sub_subproject)
505 sub_subproject_version = Version.generate!(:project => sub_subproject)
506 project.reload
506 project.reload
507
507
508 assert_equal [parent_version_1, parent_version_2, sub_subproject_version].sort,
508 assert_equal [parent_version_1, parent_version_2, sub_subproject_version].sort,
509 project.rolled_up_versions.sort
509 project.rolled_up_versions.sort
510 end
510 end
511
511
512 test "#rolled_up_versions should only check active projects" do
512 test "#rolled_up_versions should only check active projects" do
513 project = Project.generate!
513 project = Project.generate!
514 parent_version_1 = Version.generate!(:project => project)
514 parent_version_1 = Version.generate!(:project => project)
515 parent_version_2 = Version.generate!(:project => project)
515 parent_version_2 = Version.generate!(:project => project)
516 subproject = Project.generate_with_parent!(project)
516 subproject = Project.generate_with_parent!(project)
517 subproject_version = Version.generate!(:project => subproject)
517 subproject_version = Version.generate!(:project => subproject)
518 assert subproject.archive
518 assert subproject.archive
519 project.reload
519 project.reload
520
520
521 assert !subproject.active?
521 assert !subproject.active?
522 assert_equal [parent_version_1, parent_version_2].sort,
522 assert_equal [parent_version_1, parent_version_2].sort,
523 project.rolled_up_versions.sort
523 project.rolled_up_versions.sort
524 end
524 end
525
525
526 def test_shared_versions_none_sharing
526 def test_shared_versions_none_sharing
527 p = Project.find(5)
527 p = Project.find(5)
528 v = Version.create!(:name => 'none_sharing', :project => p, :sharing => 'none')
528 v = Version.create!(:name => 'none_sharing', :project => p, :sharing => 'none')
529 assert p.shared_versions.include?(v)
529 assert p.shared_versions.include?(v)
530 assert !p.children.first.shared_versions.include?(v)
530 assert !p.children.first.shared_versions.include?(v)
531 assert !p.root.shared_versions.include?(v)
531 assert !p.root.shared_versions.include?(v)
532 assert !p.siblings.first.shared_versions.include?(v)
532 assert !p.siblings.first.shared_versions.include?(v)
533 assert !p.root.siblings.first.shared_versions.include?(v)
533 assert !p.root.siblings.first.shared_versions.include?(v)
534 end
534 end
535
535
536 def test_shared_versions_descendants_sharing
536 def test_shared_versions_descendants_sharing
537 p = Project.find(5)
537 p = Project.find(5)
538 v = Version.create!(:name => 'descendants_sharing', :project => p, :sharing => 'descendants')
538 v = Version.create!(:name => 'descendants_sharing', :project => p, :sharing => 'descendants')
539 assert p.shared_versions.include?(v)
539 assert p.shared_versions.include?(v)
540 assert p.children.first.shared_versions.include?(v)
540 assert p.children.first.shared_versions.include?(v)
541 assert !p.root.shared_versions.include?(v)
541 assert !p.root.shared_versions.include?(v)
542 assert !p.siblings.first.shared_versions.include?(v)
542 assert !p.siblings.first.shared_versions.include?(v)
543 assert !p.root.siblings.first.shared_versions.include?(v)
543 assert !p.root.siblings.first.shared_versions.include?(v)
544 end
544 end
545
545
546 def test_shared_versions_hierarchy_sharing
546 def test_shared_versions_hierarchy_sharing
547 p = Project.find(5)
547 p = Project.find(5)
548 v = Version.create!(:name => 'hierarchy_sharing', :project => p, :sharing => 'hierarchy')
548 v = Version.create!(:name => 'hierarchy_sharing', :project => p, :sharing => 'hierarchy')
549 assert p.shared_versions.include?(v)
549 assert p.shared_versions.include?(v)
550 assert p.children.first.shared_versions.include?(v)
550 assert p.children.first.shared_versions.include?(v)
551 assert p.root.shared_versions.include?(v)
551 assert p.root.shared_versions.include?(v)
552 assert !p.siblings.first.shared_versions.include?(v)
552 assert !p.siblings.first.shared_versions.include?(v)
553 assert !p.root.siblings.first.shared_versions.include?(v)
553 assert !p.root.siblings.first.shared_versions.include?(v)
554 end
554 end
555
555
556 def test_shared_versions_tree_sharing
556 def test_shared_versions_tree_sharing
557 p = Project.find(5)
557 p = Project.find(5)
558 v = Version.create!(:name => 'tree_sharing', :project => p, :sharing => 'tree')
558 v = Version.create!(:name => 'tree_sharing', :project => p, :sharing => 'tree')
559 assert p.shared_versions.include?(v)
559 assert p.shared_versions.include?(v)
560 assert p.children.first.shared_versions.include?(v)
560 assert p.children.first.shared_versions.include?(v)
561 assert p.root.shared_versions.include?(v)
561 assert p.root.shared_versions.include?(v)
562 assert p.siblings.first.shared_versions.include?(v)
562 assert p.siblings.first.shared_versions.include?(v)
563 assert !p.root.siblings.first.shared_versions.include?(v)
563 assert !p.root.siblings.first.shared_versions.include?(v)
564 end
564 end
565
565
566 def test_shared_versions_system_sharing
566 def test_shared_versions_system_sharing
567 p = Project.find(5)
567 p = Project.find(5)
568 v = Version.create!(:name => 'system_sharing', :project => p, :sharing => 'system')
568 v = Version.create!(:name => 'system_sharing', :project => p, :sharing => 'system')
569 assert p.shared_versions.include?(v)
569 assert p.shared_versions.include?(v)
570 assert p.children.first.shared_versions.include?(v)
570 assert p.children.first.shared_versions.include?(v)
571 assert p.root.shared_versions.include?(v)
571 assert p.root.shared_versions.include?(v)
572 assert p.siblings.first.shared_versions.include?(v)
572 assert p.siblings.first.shared_versions.include?(v)
573 assert p.root.siblings.first.shared_versions.include?(v)
573 assert p.root.siblings.first.shared_versions.include?(v)
574 end
574 end
575
575
576 def test_shared_versions
576 def test_shared_versions
577 parent = Project.find(1)
577 parent = Project.find(1)
578 child = parent.children.find(3)
578 child = parent.children.find(3)
579 private_child = parent.children.find(5)
579 private_child = parent.children.find(5)
580
580
581 assert_equal [1,2,3], parent.version_ids.sort
581 assert_equal [1,2,3], parent.version_ids.sort
582 assert_equal [4], child.version_ids
582 assert_equal [4], child.version_ids
583 assert_equal [6], private_child.version_ids
583 assert_equal [6], private_child.version_ids
584 assert_equal [7], Version.where(:sharing => 'system').collect(&:id)
584 assert_equal [7], Version.where(:sharing => 'system').collect(&:id)
585
585
586 assert_equal 6, parent.shared_versions.size
586 assert_equal 6, parent.shared_versions.size
587 parent.shared_versions.each do |version|
587 parent.shared_versions.each do |version|
588 assert_kind_of Version, version
588 assert_kind_of Version, version
589 end
589 end
590
590
591 assert_equal [1,2,3,4,6,7], parent.shared_versions.collect(&:id).sort
591 assert_equal [1,2,3,4,6,7], parent.shared_versions.collect(&:id).sort
592 end
592 end
593
593
594 def test_shared_versions_should_ignore_archived_subprojects
594 def test_shared_versions_should_ignore_archived_subprojects
595 parent = Project.find(1)
595 parent = Project.find(1)
596 child = parent.children.find(3)
596 child = parent.children.find(3)
597 child.archive
597 child.archive
598 parent.reload
598 parent.reload
599
599
600 assert_equal [1,2,3], parent.version_ids.sort
600 assert_equal [1,2,3], parent.version_ids.sort
601 assert_equal [4], child.version_ids
601 assert_equal [4], child.version_ids
602 assert !parent.shared_versions.collect(&:id).include?(4)
602 assert !parent.shared_versions.collect(&:id).include?(4)
603 end
603 end
604
604
605 def test_shared_versions_visible_to_user
605 def test_shared_versions_visible_to_user
606 user = User.find(3)
606 user = User.find(3)
607 parent = Project.find(1)
607 parent = Project.find(1)
608 child = parent.children.find(5)
608 child = parent.children.find(5)
609
609
610 assert_equal [1,2,3], parent.version_ids.sort
610 assert_equal [1,2,3], parent.version_ids.sort
611 assert_equal [6], child.version_ids
611 assert_equal [6], child.version_ids
612
612
613 versions = parent.shared_versions.visible(user)
613 versions = parent.shared_versions.visible(user)
614
614
615 assert_equal 4, versions.size
615 assert_equal 4, versions.size
616 versions.each do |version|
616 versions.each do |version|
617 assert_kind_of Version, version
617 assert_kind_of Version, version
618 end
618 end
619
619
620 assert !versions.collect(&:id).include?(6)
620 assert !versions.collect(&:id).include?(6)
621 end
621 end
622
622
623 def test_shared_versions_for_new_project_should_include_system_shared_versions
623 def test_shared_versions_for_new_project_should_include_system_shared_versions
624 p = Project.find(5)
624 p = Project.find(5)
625 v = Version.create!(:name => 'system_sharing', :project => p, :sharing => 'system')
625 v = Version.create!(:name => 'system_sharing', :project => p, :sharing => 'system')
626
626
627 assert_include v, Project.new.shared_versions
627 assert_include v, Project.new.shared_versions
628 end
628 end
629
629
630 def test_next_identifier
630 def test_next_identifier
631 ProjectCustomField.delete_all
631 ProjectCustomField.delete_all
632 Project.create!(:name => 'last', :identifier => 'p2008040')
632 Project.create!(:name => 'last', :identifier => 'p2008040')
633 assert_equal 'p2008041', Project.next_identifier
633 assert_equal 'p2008041', Project.next_identifier
634 end
634 end
635
635
636 def test_next_identifier_first_project
636 def test_next_identifier_first_project
637 Project.delete_all
637 Project.delete_all
638 assert_nil Project.next_identifier
638 assert_nil Project.next_identifier
639 end
639 end
640
640
641 def test_enabled_module_names
641 def test_enabled_module_names
642 with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
642 with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
643 project = Project.new
643 project = Project.new
644
644
645 project.enabled_module_names = %w(issue_tracking news)
645 project.enabled_module_names = %w(issue_tracking news)
646 assert_equal %w(issue_tracking news), project.enabled_module_names.sort
646 assert_equal %w(issue_tracking news), project.enabled_module_names.sort
647 end
647 end
648 end
648 end
649
649
650 def test_enabled_modules_names_with_nil_should_clear_modules
651 p = Project.find(1)
652 p.enabled_module_names = nil
653 assert_equal [], p.enabled_modules
654 end
655
650 test "enabled_modules should define module by names and preserve ids" do
656 test "enabled_modules should define module by names and preserve ids" do
651 @project = Project.find(1)
657 @project = Project.find(1)
652 # Remove one module
658 # Remove one module
653 modules = @project.enabled_modules.slice(0..-2)
659 modules = @project.enabled_modules.slice(0..-2)
654 assert modules.any?
660 assert modules.any?
655 assert_difference 'EnabledModule.count', -1 do
661 assert_difference 'EnabledModule.count', -1 do
656 @project.enabled_module_names = modules.collect(&:name)
662 @project.enabled_module_names = modules.collect(&:name)
657 end
663 end
658 @project.reload
664 @project.reload
659 # Ids should be preserved
665 # Ids should be preserved
660 assert_equal @project.enabled_module_ids.sort, modules.collect(&:id).sort
666 assert_equal @project.enabled_module_ids.sort, modules.collect(&:id).sort
661 end
667 end
662
668
663 test "enabled_modules should enable a module" do
669 test "enabled_modules should enable a module" do
664 @project = Project.find(1)
670 @project = Project.find(1)
665 @project.enabled_module_names = []
671 @project.enabled_module_names = []
666 @project.reload
672 @project.reload
667 assert_equal [], @project.enabled_module_names
673 assert_equal [], @project.enabled_module_names
668 #with string
674 #with string
669 @project.enable_module!("issue_tracking")
675 @project.enable_module!("issue_tracking")
670 assert_equal ["issue_tracking"], @project.enabled_module_names
676 assert_equal ["issue_tracking"], @project.enabled_module_names
671 #with symbol
677 #with symbol
672 @project.enable_module!(:gantt)
678 @project.enable_module!(:gantt)
673 assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
679 assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
674 #don't add a module twice
680 #don't add a module twice
675 @project.enable_module!("issue_tracking")
681 @project.enable_module!("issue_tracking")
676 assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
682 assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
677 end
683 end
678
684
679 test "enabled_modules should disable a module" do
685 test "enabled_modules should disable a module" do
680 @project = Project.find(1)
686 @project = Project.find(1)
681 #with string
687 #with string
682 assert @project.enabled_module_names.include?("issue_tracking")
688 assert @project.enabled_module_names.include?("issue_tracking")
683 @project.disable_module!("issue_tracking")
689 @project.disable_module!("issue_tracking")
684 assert ! @project.reload.enabled_module_names.include?("issue_tracking")
690 assert ! @project.reload.enabled_module_names.include?("issue_tracking")
685 #with symbol
691 #with symbol
686 assert @project.enabled_module_names.include?("gantt")
692 assert @project.enabled_module_names.include?("gantt")
687 @project.disable_module!(:gantt)
693 @project.disable_module!(:gantt)
688 assert ! @project.reload.enabled_module_names.include?("gantt")
694 assert ! @project.reload.enabled_module_names.include?("gantt")
689 #with EnabledModule object
695 #with EnabledModule object
690 first_module = @project.enabled_modules.first
696 first_module = @project.enabled_modules.first
691 @project.disable_module!(first_module)
697 @project.disable_module!(first_module)
692 assert ! @project.reload.enabled_module_names.include?(first_module.name)
698 assert ! @project.reload.enabled_module_names.include?(first_module.name)
693 end
699 end
694
700
695 def test_enabled_module_names_should_not_recreate_enabled_modules
701 def test_enabled_module_names_should_not_recreate_enabled_modules
696 project = Project.find(1)
702 project = Project.find(1)
697 # Remove one module
703 # Remove one module
698 modules = project.enabled_modules.slice(0..-2)
704 modules = project.enabled_modules.slice(0..-2)
699 assert modules.any?
705 assert modules.any?
700 assert_difference 'EnabledModule.count', -1 do
706 assert_difference 'EnabledModule.count', -1 do
701 project.enabled_module_names = modules.collect(&:name)
707 project.enabled_module_names = modules.collect(&:name)
702 end
708 end
703 project.reload
709 project.reload
704 # Ids should be preserved
710 # Ids should be preserved
705 assert_equal project.enabled_module_ids.sort, modules.collect(&:id).sort
711 assert_equal project.enabled_module_ids.sort, modules.collect(&:id).sort
706 end
712 end
707
713
708 def test_copy_from_existing_project
714 def test_copy_from_existing_project
709 source_project = Project.find(1)
715 source_project = Project.find(1)
710 copied_project = Project.copy_from(1)
716 copied_project = Project.copy_from(1)
711
717
712 assert copied_project
718 assert copied_project
713 # Cleared attributes
719 # Cleared attributes
714 assert copied_project.id.blank?
720 assert copied_project.id.blank?
715 assert copied_project.name.blank?
721 assert copied_project.name.blank?
716 assert copied_project.identifier.blank?
722 assert copied_project.identifier.blank?
717
723
718 # Duplicated attributes
724 # Duplicated attributes
719 assert_equal source_project.description, copied_project.description
725 assert_equal source_project.description, copied_project.description
720 assert_equal source_project.enabled_modules, copied_project.enabled_modules
726 assert_equal source_project.enabled_modules, copied_project.enabled_modules
721 assert_equal source_project.trackers, copied_project.trackers
727 assert_equal source_project.trackers, copied_project.trackers
722
728
723 # Default attributes
729 # Default attributes
724 assert_equal 1, copied_project.status
730 assert_equal 1, copied_project.status
725 end
731 end
726
732
727 def test_activities_should_use_the_system_activities
733 def test_activities_should_use_the_system_activities
728 project = Project.find(1)
734 project = Project.find(1)
729 assert_equal project.activities.to_a, TimeEntryActivity.where(:active => true).to_a
735 assert_equal project.activities.to_a, TimeEntryActivity.where(:active => true).to_a
730 assert_kind_of ActiveRecord::Relation, project.activities
736 assert_kind_of ActiveRecord::Relation, project.activities
731 end
737 end
732
738
733
739
734 def test_activities_should_use_the_project_specific_activities
740 def test_activities_should_use_the_project_specific_activities
735 project = Project.find(1)
741 project = Project.find(1)
736 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project})
742 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project})
737 assert overridden_activity.save!
743 assert overridden_activity.save!
738
744
739 assert project.activities.include?(overridden_activity), "Project specific Activity not found"
745 assert project.activities.include?(overridden_activity), "Project specific Activity not found"
740 assert_kind_of ActiveRecord::Relation, project.activities
746 assert_kind_of ActiveRecord::Relation, project.activities
741 end
747 end
742
748
743 def test_activities_should_not_include_the_inactive_project_specific_activities
749 def test_activities_should_not_include_the_inactive_project_specific_activities
744 project = Project.find(1)
750 project = Project.find(1)
745 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.first, :active => false})
751 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.first, :active => false})
746 assert overridden_activity.save!
752 assert overridden_activity.save!
747
753
748 assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity found"
754 assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity found"
749 end
755 end
750
756
751 def test_activities_should_not_include_project_specific_activities_from_other_projects
757 def test_activities_should_not_include_project_specific_activities_from_other_projects
752 project = Project.find(1)
758 project = Project.find(1)
753 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(2)})
759 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(2)})
754 assert overridden_activity.save!
760 assert overridden_activity.save!
755
761
756 assert !project.activities.include?(overridden_activity), "Project specific Activity found on a different project"
762 assert !project.activities.include?(overridden_activity), "Project specific Activity found on a different project"
757 end
763 end
758
764
759 def test_activities_should_handle_nils
765 def test_activities_should_handle_nils
760 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(1), :parent => TimeEntryActivity.first})
766 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(1), :parent => TimeEntryActivity.first})
761 TimeEntryActivity.delete_all
767 TimeEntryActivity.delete_all
762
768
763 # No activities
769 # No activities
764 project = Project.find(1)
770 project = Project.find(1)
765 assert project.activities.empty?
771 assert project.activities.empty?
766
772
767 # No system, one overridden
773 # No system, one overridden
768 assert overridden_activity.save!
774 assert overridden_activity.save!
769 project.reload
775 project.reload
770 assert_equal [overridden_activity], project.activities
776 assert_equal [overridden_activity], project.activities
771 end
777 end
772
778
773 def test_activities_should_override_system_activities_with_project_activities
779 def test_activities_should_override_system_activities_with_project_activities
774 project = Project.find(1)
780 project = Project.find(1)
775 parent_activity = TimeEntryActivity.first
781 parent_activity = TimeEntryActivity.first
776 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => parent_activity})
782 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => parent_activity})
777 assert overridden_activity.save!
783 assert overridden_activity.save!
778
784
779 assert project.activities.include?(overridden_activity), "Project specific Activity not found"
785 assert project.activities.include?(overridden_activity), "Project specific Activity not found"
780 assert !project.activities.include?(parent_activity), "System Activity found when it should have been overridden"
786 assert !project.activities.include?(parent_activity), "System Activity found when it should have been overridden"
781 end
787 end
782
788
783 def test_activities_should_include_inactive_activities_if_specified
789 def test_activities_should_include_inactive_activities_if_specified
784 project = Project.find(1)
790 project = Project.find(1)
785 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.first, :active => false})
791 overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.first, :active => false})
786 assert overridden_activity.save!
792 assert overridden_activity.save!
787
793
788 assert project.activities(true).include?(overridden_activity), "Inactive Project specific Activity not found"
794 assert project.activities(true).include?(overridden_activity), "Inactive Project specific Activity not found"
789 end
795 end
790
796
791 test 'activities should not include active System activities if the project has an override that is inactive' do
797 test 'activities should not include active System activities if the project has an override that is inactive' do
792 project = Project.find(1)
798 project = Project.find(1)
793 system_activity = TimeEntryActivity.find_by_name('Design')
799 system_activity = TimeEntryActivity.find_by_name('Design')
794 assert system_activity.active?
800 assert system_activity.active?
795 overridden_activity = TimeEntryActivity.create!(:name => "Project", :project => project, :parent => system_activity, :active => false)
801 overridden_activity = TimeEntryActivity.create!(:name => "Project", :project => project, :parent => system_activity, :active => false)
796 assert overridden_activity.save!
802 assert overridden_activity.save!
797
803
798 assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity not found"
804 assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity not found"
799 assert !project.activities.include?(system_activity), "System activity found when the project has an inactive override"
805 assert !project.activities.include?(system_activity), "System activity found when the project has an inactive override"
800 end
806 end
801
807
802 def test_close_completed_versions
808 def test_close_completed_versions
803 Version.update_all("status = 'open'")
809 Version.update_all("status = 'open'")
804 project = Project.find(1)
810 project = Project.find(1)
805 assert_not_nil project.versions.detect {|v| v.completed? && v.status == 'open'}
811 assert_not_nil project.versions.detect {|v| v.completed? && v.status == 'open'}
806 assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'}
812 assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'}
807 project.close_completed_versions
813 project.close_completed_versions
808 project.reload
814 project.reload
809 assert_nil project.versions.detect {|v| v.completed? && v.status != 'closed'}
815 assert_nil project.versions.detect {|v| v.completed? && v.status != 'closed'}
810 assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'}
816 assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'}
811 end
817 end
812
818
813 test "#start_date should be nil if there are no issues on the project" do
819 test "#start_date should be nil if there are no issues on the project" do
814 project = Project.generate!
820 project = Project.generate!
815 assert_nil project.start_date
821 assert_nil project.start_date
816 end
822 end
817
823
818 test "#start_date should be nil when issues have no start date" do
824 test "#start_date should be nil when issues have no start date" do
819 project = Project.generate!
825 project = Project.generate!
820 project.trackers << Tracker.generate!
826 project.trackers << Tracker.generate!
821 early = 7.days.ago.to_date
827 early = 7.days.ago.to_date
822 Issue.generate!(:project => project, :start_date => nil)
828 Issue.generate!(:project => project, :start_date => nil)
823
829
824 assert_nil project.start_date
830 assert_nil project.start_date
825 end
831 end
826
832
827 test "#start_date should be the earliest start date of it's issues" do
833 test "#start_date should be the earliest start date of it's issues" do
828 project = Project.generate!
834 project = Project.generate!
829 project.trackers << Tracker.generate!
835 project.trackers << Tracker.generate!
830 early = 7.days.ago.to_date
836 early = 7.days.ago.to_date
831 Issue.generate!(:project => project, :start_date => Date.today)
837 Issue.generate!(:project => project, :start_date => Date.today)
832 Issue.generate!(:project => project, :start_date => early)
838 Issue.generate!(:project => project, :start_date => early)
833
839
834 assert_equal early, project.start_date
840 assert_equal early, project.start_date
835 end
841 end
836
842
837 test "#due_date should be nil if there are no issues on the project" do
843 test "#due_date should be nil if there are no issues on the project" do
838 project = Project.generate!
844 project = Project.generate!
839 assert_nil project.due_date
845 assert_nil project.due_date
840 end
846 end
841
847
842 test "#due_date should be nil if there are no issues with due dates" do
848 test "#due_date should be nil if there are no issues with due dates" do
843 project = Project.generate!
849 project = Project.generate!
844 project.trackers << Tracker.generate!
850 project.trackers << Tracker.generate!
845 Issue.generate!(:project => project, :due_date => nil)
851 Issue.generate!(:project => project, :due_date => nil)
846
852
847 assert_nil project.due_date
853 assert_nil project.due_date
848 end
854 end
849
855
850 test "#due_date should be the latest due date of it's issues" do
856 test "#due_date should be the latest due date of it's issues" do
851 project = Project.generate!
857 project = Project.generate!
852 project.trackers << Tracker.generate!
858 project.trackers << Tracker.generate!
853 future = 7.days.from_now.to_date
859 future = 7.days.from_now.to_date
854 Issue.generate!(:project => project, :due_date => future)
860 Issue.generate!(:project => project, :due_date => future)
855 Issue.generate!(:project => project, :due_date => Date.today)
861 Issue.generate!(:project => project, :due_date => Date.today)
856
862
857 assert_equal future, project.due_date
863 assert_equal future, project.due_date
858 end
864 end
859
865
860 test "#due_date should be the latest due date of it's versions" do
866 test "#due_date should be the latest due date of it's versions" do
861 project = Project.generate!
867 project = Project.generate!
862 future = 7.days.from_now.to_date
868 future = 7.days.from_now.to_date
863 project.versions << Version.generate!(:effective_date => future)
869 project.versions << Version.generate!(:effective_date => future)
864 project.versions << Version.generate!(:effective_date => Date.today)
870 project.versions << Version.generate!(:effective_date => Date.today)
865
871
866 assert_equal future, project.due_date
872 assert_equal future, project.due_date
867 end
873 end
868
874
869 test "#due_date should pick the latest date from it's issues and versions" do
875 test "#due_date should pick the latest date from it's issues and versions" do
870 project = Project.generate!
876 project = Project.generate!
871 project.trackers << Tracker.generate!
877 project.trackers << Tracker.generate!
872 future = 7.days.from_now.to_date
878 future = 7.days.from_now.to_date
873 far_future = 14.days.from_now.to_date
879 far_future = 14.days.from_now.to_date
874 Issue.generate!(:project => project, :due_date => far_future)
880 Issue.generate!(:project => project, :due_date => far_future)
875 project.versions << Version.generate!(:effective_date => future)
881 project.versions << Version.generate!(:effective_date => future)
876
882
877 assert_equal far_future, project.due_date
883 assert_equal far_future, project.due_date
878 end
884 end
879
885
880 test "#completed_percent with no versions should be 100" do
886 test "#completed_percent with no versions should be 100" do
881 project = Project.generate!
887 project = Project.generate!
882 assert_equal 100, project.completed_percent
888 assert_equal 100, project.completed_percent
883 end
889 end
884
890
885 test "#completed_percent with versions should return 0 if the versions have no issues" do
891 test "#completed_percent with versions should return 0 if the versions have no issues" do
886 project = Project.generate!
892 project = Project.generate!
887 Version.generate!(:project => project)
893 Version.generate!(:project => project)
888 Version.generate!(:project => project)
894 Version.generate!(:project => project)
889
895
890 assert_equal 0, project.completed_percent
896 assert_equal 0, project.completed_percent
891 end
897 end
892
898
893 test "#completed_percent with versions should return 100 if the version has only closed issues" do
899 test "#completed_percent with versions should return 100 if the version has only closed issues" do
894 project = Project.generate!
900 project = Project.generate!
895 project.trackers << Tracker.generate!
901 project.trackers << Tracker.generate!
896 v1 = Version.generate!(:project => project)
902 v1 = Version.generate!(:project => project)
897 Issue.generate!(:project => project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v1)
903 Issue.generate!(:project => project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v1)
898 v2 = Version.generate!(:project => project)
904 v2 = Version.generate!(:project => project)
899 Issue.generate!(:project => project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v2)
905 Issue.generate!(:project => project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v2)
900
906
901 assert_equal 100, project.completed_percent
907 assert_equal 100, project.completed_percent
902 end
908 end
903
909
904 test "#completed_percent with versions should return the averaged completed percent of the versions (not weighted)" do
910 test "#completed_percent with versions should return the averaged completed percent of the versions (not weighted)" do
905 project = Project.generate!
911 project = Project.generate!
906 project.trackers << Tracker.generate!
912 project.trackers << Tracker.generate!
907 v1 = Version.generate!(:project => project)
913 v1 = Version.generate!(:project => project)
908 Issue.generate!(:project => project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v1)
914 Issue.generate!(:project => project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v1)
909 v2 = Version.generate!(:project => project)
915 v2 = Version.generate!(:project => project)
910 Issue.generate!(:project => project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v2)
916 Issue.generate!(:project => project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v2)
911
917
912 assert_equal 50, project.completed_percent
918 assert_equal 50, project.completed_percent
913 end
919 end
914
920
915 test "#notified_users" do
921 test "#notified_users" do
916 project = Project.generate!
922 project = Project.generate!
917 role = Role.generate!
923 role = Role.generate!
918
924
919 user_with_membership_notification = User.generate!(:mail_notification => 'selected')
925 user_with_membership_notification = User.generate!(:mail_notification => 'selected')
920 Member.create!(:project => project, :roles => [role], :principal => user_with_membership_notification, :mail_notification => true)
926 Member.create!(:project => project, :roles => [role], :principal => user_with_membership_notification, :mail_notification => true)
921
927
922 all_events_user = User.generate!(:mail_notification => 'all')
928 all_events_user = User.generate!(:mail_notification => 'all')
923 Member.create!(:project => project, :roles => [role], :principal => all_events_user)
929 Member.create!(:project => project, :roles => [role], :principal => all_events_user)
924
930
925 no_events_user = User.generate!(:mail_notification => 'none')
931 no_events_user = User.generate!(:mail_notification => 'none')
926 Member.create!(:project => project, :roles => [role], :principal => no_events_user)
932 Member.create!(:project => project, :roles => [role], :principal => no_events_user)
927
933
928 only_my_events_user = User.generate!(:mail_notification => 'only_my_events')
934 only_my_events_user = User.generate!(:mail_notification => 'only_my_events')
929 Member.create!(:project => project, :roles => [role], :principal => only_my_events_user)
935 Member.create!(:project => project, :roles => [role], :principal => only_my_events_user)
930
936
931 only_assigned_user = User.generate!(:mail_notification => 'only_assigned')
937 only_assigned_user = User.generate!(:mail_notification => 'only_assigned')
932 Member.create!(:project => project, :roles => [role], :principal => only_assigned_user)
938 Member.create!(:project => project, :roles => [role], :principal => only_assigned_user)
933
939
934 only_owned_user = User.generate!(:mail_notification => 'only_owner')
940 only_owned_user = User.generate!(:mail_notification => 'only_owner')
935 Member.create!(:project => project, :roles => [role], :principal => only_owned_user)
941 Member.create!(:project => project, :roles => [role], :principal => only_owned_user)
936
942
937 assert project.notified_users.include?(user_with_membership_notification), "should include members with a mail notification"
943 assert project.notified_users.include?(user_with_membership_notification), "should include members with a mail notification"
938 assert project.notified_users.include?(all_events_user), "should include users with the 'all' notification option"
944 assert project.notified_users.include?(all_events_user), "should include users with the 'all' notification option"
939 assert !project.notified_users.include?(no_events_user), "should not include users with the 'none' notification option"
945 assert !project.notified_users.include?(no_events_user), "should not include users with the 'none' notification option"
940 assert !project.notified_users.include?(only_my_events_user), "should not include users with the 'only_my_events' notification option"
946 assert !project.notified_users.include?(only_my_events_user), "should not include users with the 'only_my_events' notification option"
941 assert !project.notified_users.include?(only_assigned_user), "should not include users with the 'only_assigned' notification option"
947 assert !project.notified_users.include?(only_assigned_user), "should not include users with the 'only_assigned' notification option"
942 assert !project.notified_users.include?(only_owned_user), "should not include users with the 'only_owner' notification option"
948 assert !project.notified_users.include?(only_owned_user), "should not include users with the 'only_owner' notification option"
943 end
949 end
944
950
945 def test_override_roles_without_builtin_group_memberships
951 def test_override_roles_without_builtin_group_memberships
946 project = Project.generate!
952 project = Project.generate!
947 assert_equal [Role.anonymous], project.override_roles(Role.anonymous)
953 assert_equal [Role.anonymous], project.override_roles(Role.anonymous)
948 assert_equal [Role.non_member], project.override_roles(Role.non_member)
954 assert_equal [Role.non_member], project.override_roles(Role.non_member)
949 end
955 end
956
957 def test_css_classes
958 p = Project.new
959 assert_kind_of String, p.css_classes
960 assert_not_include 'archived', p.css_classes.split
961 assert_not_include 'closed', p.css_classes.split
962 end
963
964 def test_css_classes_for_archived_project
965 p = Project.new
966 p.status = Project::STATUS_ARCHIVED
967 assert_include 'archived', p.css_classes.split
968 end
969
970 def test_css_classes_for_closed_project
971 p = Project.new
972 p.status = Project::STATUS_CLOSED
973 assert_include 'closed', p.css_classes.split
974 end
950 end
975 end
@@ -1,245 +1,251
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 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 VersionTest < ActiveSupport::TestCase
20 class VersionTest < ActiveSupport::TestCase
21 fixtures :projects, :users, :issues, :issue_statuses, :trackers,
21 fixtures :projects, :users, :issues, :issue_statuses, :trackers,
22 :enumerations, :versions, :projects_trackers
22 :enumerations, :versions, :projects_trackers
23
23
24 def test_create
24 def test_create
25 v = Version.new(:project => Project.find(1), :name => '1.1',
25 v = Version.new(:project => Project.find(1), :name => '1.1',
26 :effective_date => '2011-03-25')
26 :effective_date => '2011-03-25')
27 assert v.save
27 assert v.save
28 assert_equal 'open', v.status
28 assert_equal 'open', v.status
29 assert_equal 'none', v.sharing
29 assert_equal 'none', v.sharing
30 end
30 end
31
31
32 def test_invalid_effective_date_validation
32 def test_invalid_effective_date_validation
33 v = Version.new(:project => Project.find(1), :name => '1.1',
33 v = Version.new(:project => Project.find(1), :name => '1.1',
34 :effective_date => '99999-01-01')
34 :effective_date => '99999-01-01')
35 assert !v.valid?
35 assert !v.valid?
36 v.effective_date = '2012-11-33'
36 v.effective_date = '2012-11-33'
37 assert !v.valid?
37 assert !v.valid?
38 v.effective_date = '2012-31-11'
38 v.effective_date = '2012-31-11'
39 assert !v.valid?
39 assert !v.valid?
40 v.effective_date = '-2012-31-11'
40 v.effective_date = '-2012-31-11'
41 assert !v.valid?
41 assert !v.valid?
42 v.effective_date = 'ABC'
42 v.effective_date = 'ABC'
43 assert !v.valid?
43 assert !v.valid?
44 assert_include I18n.translate('activerecord.errors.messages.not_a_date'),
44 assert_include I18n.translate('activerecord.errors.messages.not_a_date'),
45 v.errors[:effective_date]
45 v.errors[:effective_date]
46 end
46 end
47
47
48 def test_progress_should_be_0_with_no_assigned_issues
48 def test_progress_should_be_0_with_no_assigned_issues
49 project = Project.find(1)
49 project = Project.find(1)
50 v = Version.create!(:project => project, :name => 'Progress')
50 v = Version.create!(:project => project, :name => 'Progress')
51 assert_equal 0, v.completed_percent
51 assert_equal 0, v.completed_percent
52 assert_equal 0, v.closed_percent
52 assert_equal 0, v.closed_percent
53 end
53 end
54
54
55 def test_progress_should_be_0_with_unbegun_assigned_issues
55 def test_progress_should_be_0_with_unbegun_assigned_issues
56 project = Project.find(1)
56 project = Project.find(1)
57 v = Version.create!(:project => project, :name => 'Progress')
57 v = Version.create!(:project => project, :name => 'Progress')
58 add_issue(v)
58 add_issue(v)
59 add_issue(v, :done_ratio => 0)
59 add_issue(v, :done_ratio => 0)
60 assert_progress_equal 0, v.completed_percent
60 assert_progress_equal 0, v.completed_percent
61 assert_progress_equal 0, v.closed_percent
61 assert_progress_equal 0, v.closed_percent
62 end
62 end
63
63
64 def test_progress_should_be_100_with_closed_assigned_issues
64 def test_progress_should_be_100_with_closed_assigned_issues
65 project = Project.find(1)
65 project = Project.find(1)
66 status = IssueStatus.where(:is_closed => true).first
66 status = IssueStatus.where(:is_closed => true).first
67 v = Version.create!(:project => project, :name => 'Progress')
67 v = Version.create!(:project => project, :name => 'Progress')
68 add_issue(v, :status => status)
68 add_issue(v, :status => status)
69 add_issue(v, :status => status, :done_ratio => 20)
69 add_issue(v, :status => status, :done_ratio => 20)
70 add_issue(v, :status => status, :done_ratio => 70, :estimated_hours => 25)
70 add_issue(v, :status => status, :done_ratio => 70, :estimated_hours => 25)
71 add_issue(v, :status => status, :estimated_hours => 15)
71 add_issue(v, :status => status, :estimated_hours => 15)
72 assert_progress_equal 100.0, v.completed_percent
72 assert_progress_equal 100.0, v.completed_percent
73 assert_progress_equal 100.0, v.closed_percent
73 assert_progress_equal 100.0, v.closed_percent
74 end
74 end
75
75
76 def test_progress_should_consider_done_ratio_of_open_assigned_issues
76 def test_progress_should_consider_done_ratio_of_open_assigned_issues
77 project = Project.find(1)
77 project = Project.find(1)
78 v = Version.create!(:project => project, :name => 'Progress')
78 v = Version.create!(:project => project, :name => 'Progress')
79 add_issue(v)
79 add_issue(v)
80 add_issue(v, :done_ratio => 20)
80 add_issue(v, :done_ratio => 20)
81 add_issue(v, :done_ratio => 70)
81 add_issue(v, :done_ratio => 70)
82 assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_percent
82 assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_percent
83 assert_progress_equal 0, v.closed_percent
83 assert_progress_equal 0, v.closed_percent
84 end
84 end
85
85
86 def test_progress_should_consider_closed_issues_as_completed
86 def test_progress_should_consider_closed_issues_as_completed
87 project = Project.find(1)
87 project = Project.find(1)
88 v = Version.create!(:project => project, :name => 'Progress')
88 v = Version.create!(:project => project, :name => 'Progress')
89 add_issue(v)
89 add_issue(v)
90 add_issue(v, :done_ratio => 20)
90 add_issue(v, :done_ratio => 20)
91 add_issue(v, :status => IssueStatus.where(:is_closed => true).first)
91 add_issue(v, :status => IssueStatus.where(:is_closed => true).first)
92 assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_percent
92 assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_percent
93 assert_progress_equal (100.0)/3, v.closed_percent
93 assert_progress_equal (100.0)/3, v.closed_percent
94 end
94 end
95
95
96 def test_progress_should_consider_estimated_hours_to_weight_issues
96 def test_progress_should_consider_estimated_hours_to_weight_issues
97 project = Project.find(1)
97 project = Project.find(1)
98 v = Version.create!(:project => project, :name => 'Progress')
98 v = Version.create!(:project => project, :name => 'Progress')
99 add_issue(v, :estimated_hours => 10)
99 add_issue(v, :estimated_hours => 10)
100 add_issue(v, :estimated_hours => 20, :done_ratio => 30)
100 add_issue(v, :estimated_hours => 20, :done_ratio => 30)
101 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
101 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
102 add_issue(v, :estimated_hours => 25, :status => IssueStatus.where(:is_closed => true).first)
102 add_issue(v, :estimated_hours => 25, :status => IssueStatus.where(:is_closed => true).first)
103 assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_percent
103 assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_percent
104 assert_progress_equal 25.0/95.0*100, v.closed_percent
104 assert_progress_equal 25.0/95.0*100, v.closed_percent
105 end
105 end
106
106
107 def test_progress_should_consider_average_estimated_hours_to_weight_unestimated_issues
107 def test_progress_should_consider_average_estimated_hours_to_weight_unestimated_issues
108 project = Project.find(1)
108 project = Project.find(1)
109 v = Version.create!(:project => project, :name => 'Progress')
109 v = Version.create!(:project => project, :name => 'Progress')
110 add_issue(v, :done_ratio => 20)
110 add_issue(v, :done_ratio => 20)
111 add_issue(v, :status => IssueStatus.where(:is_closed => true).first)
111 add_issue(v, :status => IssueStatus.where(:is_closed => true).first)
112 add_issue(v, :estimated_hours => 10, :done_ratio => 30)
112 add_issue(v, :estimated_hours => 10, :done_ratio => 30)
113 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
113 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
114 assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_percent
114 assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_percent
115 assert_progress_equal 25.0/100.0*100, v.closed_percent
115 assert_progress_equal 25.0/100.0*100, v.closed_percent
116 end
116 end
117
117
118 def test_should_sort_scheduled_then_unscheduled_versions
118 def test_should_sort_scheduled_then_unscheduled_versions
119 Version.delete_all
119 Version.delete_all
120 v4 = Version.create!(:project_id => 1, :name => 'v4')
120 v4 = Version.create!(:project_id => 1, :name => 'v4')
121 v3 = Version.create!(:project_id => 1, :name => 'v2', :effective_date => '2012-07-14')
121 v3 = Version.create!(:project_id => 1, :name => 'v2', :effective_date => '2012-07-14')
122 v2 = Version.create!(:project_id => 1, :name => 'v1')
122 v2 = Version.create!(:project_id => 1, :name => 'v1')
123 v1 = Version.create!(:project_id => 1, :name => 'v3', :effective_date => '2012-08-02')
123 v1 = Version.create!(:project_id => 1, :name => 'v3', :effective_date => '2012-08-02')
124 v5 = Version.create!(:project_id => 1, :name => 'v5', :effective_date => '2012-07-02')
124 v5 = Version.create!(:project_id => 1, :name => 'v5', :effective_date => '2012-07-02')
125
125
126 assert_equal [v5, v3, v1, v2, v4], [v1, v2, v3, v4, v5].sort
126 assert_equal [v5, v3, v1, v2, v4], [v1, v2, v3, v4, v5].sort
127 assert_equal [v5, v3, v1, v2, v4], Version.sorted.to_a
127 assert_equal [v5, v3, v1, v2, v4], Version.sorted.to_a
128 end
128 end
129
129
130 def test_should_sort_versions_with_same_date_by_name
131 v1 = Version.new(:effective_date => '2014-12-03', :name => 'v2')
132 v2 = Version.new(:effective_date => '2014-12-03', :name => 'v1')
133 assert_equal [v2, v1], [v1, v2].sort
134 end
135
130 def test_completed_should_be_false_when_due_today
136 def test_completed_should_be_false_when_due_today
131 version = Version.create!(:project_id => 1, :effective_date => Date.today, :name => 'Due today')
137 version = Version.create!(:project_id => 1, :effective_date => Date.today, :name => 'Due today')
132 assert_equal false, version.completed?
138 assert_equal false, version.completed?
133 end
139 end
134
140
135 test "#behind_schedule? should be false if there are no issues assigned" do
141 test "#behind_schedule? should be false if there are no issues assigned" do
136 version = Version.generate!(:effective_date => Date.yesterday)
142 version = Version.generate!(:effective_date => Date.yesterday)
137 assert_equal false, version.behind_schedule?
143 assert_equal false, version.behind_schedule?
138 end
144 end
139
145
140 test "#behind_schedule? should be false if there is no effective_date" do
146 test "#behind_schedule? should be false if there is no effective_date" do
141 version = Version.generate!(:effective_date => nil)
147 version = Version.generate!(:effective_date => nil)
142 assert_equal false, version.behind_schedule?
148 assert_equal false, version.behind_schedule?
143 end
149 end
144
150
145 test "#behind_schedule? should be false if all of the issues are ahead of schedule" do
151 test "#behind_schedule? should be false if all of the issues are ahead of schedule" do
146 version = Version.create!(:project_id => 1, :name => 'test', :effective_date => 7.days.from_now.to_date)
152 version = Version.create!(:project_id => 1, :name => 'test', :effective_date => 7.days.from_now.to_date)
147 add_issue(version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
153 add_issue(version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
148 add_issue(version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
154 add_issue(version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
149 assert_equal 60, version.completed_percent
155 assert_equal 60, version.completed_percent
150 assert_equal false, version.behind_schedule?
156 assert_equal false, version.behind_schedule?
151 end
157 end
152
158
153 test "#behind_schedule? should be true if any of the issues are behind schedule" do
159 test "#behind_schedule? should be true if any of the issues are behind schedule" do
154 version = Version.create!(:project_id => 1, :name => 'test', :effective_date => 7.days.from_now.to_date)
160 version = Version.create!(:project_id => 1, :name => 'test', :effective_date => 7.days.from_now.to_date)
155 add_issue(version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
161 add_issue(version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
156 add_issue(version, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
162 add_issue(version, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
157 assert_equal 40, version.completed_percent
163 assert_equal 40, version.completed_percent
158 assert_equal true, version.behind_schedule?
164 assert_equal true, version.behind_schedule?
159 end
165 end
160
166
161 test "#behind_schedule? should be false if all of the issues are complete" do
167 test "#behind_schedule? should be false if all of the issues are complete" do
162 version = Version.create!(:project_id => 1, :name => 'test', :effective_date => 7.days.from_now.to_date)
168 version = Version.create!(:project_id => 1, :name => 'test', :effective_date => 7.days.from_now.to_date)
163 add_issue(version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
169 add_issue(version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
164 add_issue(version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
170 add_issue(version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
165 assert_equal 100, version.completed_percent
171 assert_equal 100, version.completed_percent
166 assert_equal false, version.behind_schedule?
172 assert_equal false, version.behind_schedule?
167 end
173 end
168
174
169 test "#estimated_hours should return 0 with no assigned issues" do
175 test "#estimated_hours should return 0 with no assigned issues" do
170 version = Version.generate!
176 version = Version.generate!
171 assert_equal 0, version.estimated_hours
177 assert_equal 0, version.estimated_hours
172 end
178 end
173
179
174 test "#estimated_hours should return 0 with no estimated hours" do
180 test "#estimated_hours should return 0 with no estimated hours" do
175 version = Version.create!(:project_id => 1, :name => 'test')
181 version = Version.create!(:project_id => 1, :name => 'test')
176 add_issue(version)
182 add_issue(version)
177 assert_equal 0, version.estimated_hours
183 assert_equal 0, version.estimated_hours
178 end
184 end
179
185
180 test "#estimated_hours should return return the sum of estimated hours" do
186 test "#estimated_hours should return return the sum of estimated hours" do
181 version = Version.create!(:project_id => 1, :name => 'test')
187 version = Version.create!(:project_id => 1, :name => 'test')
182 add_issue(version, :estimated_hours => 2.5)
188 add_issue(version, :estimated_hours => 2.5)
183 add_issue(version, :estimated_hours => 5)
189 add_issue(version, :estimated_hours => 5)
184 assert_equal 7.5, version.estimated_hours
190 assert_equal 7.5, version.estimated_hours
185 end
191 end
186
192
187 test "#estimated_hours should return the sum of leaves estimated hours" do
193 test "#estimated_hours should return the sum of leaves estimated hours" do
188 version = Version.create!(:project_id => 1, :name => 'test')
194 version = Version.create!(:project_id => 1, :name => 'test')
189 parent = add_issue(version)
195 parent = add_issue(version)
190 add_issue(version, :estimated_hours => 2.5, :parent_issue_id => parent.id)
196 add_issue(version, :estimated_hours => 2.5, :parent_issue_id => parent.id)
191 add_issue(version, :estimated_hours => 5, :parent_issue_id => parent.id)
197 add_issue(version, :estimated_hours => 5, :parent_issue_id => parent.id)
192 assert_equal 7.5, version.estimated_hours
198 assert_equal 7.5, version.estimated_hours
193 end
199 end
194
200
195 test "should update all issue's fixed_version associations in case the hierarchy changed XXX" do
201 test "should update all issue's fixed_version associations in case the hierarchy changed XXX" do
196 User.current = User.find(1) # Need the admin's permissions
202 User.current = User.find(1) # Need the admin's permissions
197
203
198 @version = Version.find(7)
204 @version = Version.find(7)
199 # Separate hierarchy
205 # Separate hierarchy
200 project_1_issue = Issue.find(1)
206 project_1_issue = Issue.find(1)
201 project_1_issue.fixed_version = @version
207 project_1_issue.fixed_version = @version
202 assert project_1_issue.save, project_1_issue.errors.full_messages.to_s
208 assert project_1_issue.save, project_1_issue.errors.full_messages.to_s
203
209
204 project_5_issue = Issue.find(6)
210 project_5_issue = Issue.find(6)
205 project_5_issue.fixed_version = @version
211 project_5_issue.fixed_version = @version
206 assert project_5_issue.save
212 assert project_5_issue.save
207
213
208 # Project
214 # Project
209 project_2_issue = Issue.find(4)
215 project_2_issue = Issue.find(4)
210 project_2_issue.fixed_version = @version
216 project_2_issue.fixed_version = @version
211 assert project_2_issue.save
217 assert project_2_issue.save
212
218
213 # Update the sharing
219 # Update the sharing
214 @version.sharing = 'none'
220 @version.sharing = 'none'
215 assert @version.save
221 assert @version.save
216
222
217 # Project 1 now out of the shared scope
223 # Project 1 now out of the shared scope
218 project_1_issue.reload
224 project_1_issue.reload
219 assert_equal nil, project_1_issue.fixed_version,
225 assert_equal nil, project_1_issue.fixed_version,
220 "Fixed version is still set after changing the Version's sharing"
226 "Fixed version is still set after changing the Version's sharing"
221
227
222 # Project 5 now out of the shared scope
228 # Project 5 now out of the shared scope
223 project_5_issue.reload
229 project_5_issue.reload
224 assert_equal nil, project_5_issue.fixed_version,
230 assert_equal nil, project_5_issue.fixed_version,
225 "Fixed version is still set after changing the Version's sharing"
231 "Fixed version is still set after changing the Version's sharing"
226
232
227 # Project 2 issue remains
233 # Project 2 issue remains
228 project_2_issue.reload
234 project_2_issue.reload
229 assert_equal @version, project_2_issue.fixed_version
235 assert_equal @version, project_2_issue.fixed_version
230 end
236 end
231
237
232 private
238 private
233
239
234 def add_issue(version, attributes={})
240 def add_issue(version, attributes={})
235 Issue.create!({:project => version.project,
241 Issue.create!({:project => version.project,
236 :fixed_version => version,
242 :fixed_version => version,
237 :subject => 'Test',
243 :subject => 'Test',
238 :author => User.first,
244 :author => User.first,
239 :tracker => version.project.trackers.first}.merge(attributes))
245 :tracker => version.project.trackers.first}.merge(attributes))
240 end
246 end
241
247
242 def assert_progress_equal(expected_float, actual_float, message="")
248 def assert_progress_equal(expected_float, actual_float, message="")
243 assert_in_delta(expected_float, actual_float, 0.000001, message="")
249 assert_in_delta(expected_float, actual_float, 0.000001, message="")
244 end
250 end
245 end
251 end
General Comments 0
You need to be logged in to leave comments. Login now