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&tracker_id=2', :content => count.to_s |
|
34 | assert_select 'a[href=?]', '/workflows/edit?role_id=1&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