##// END OF EJS Templates
Removed some test contexts....
Jean-Philippe Lang -
r13264:4989c9f6a845
parent child
Show More
@@ -1,54 +1,43
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::HttpBasicLoginTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 22 :enumerations, :users, :issue_categories,
23 23 :projects_trackers,
24 24 :roles,
25 25 :member_roles,
26 26 :members,
27 27 :enabled_modules
28 28
29 29 def setup
30 30 Setting.rest_api_enabled = '1'
31 31 Setting.login_required = '1'
32 project = Project.find('onlinestore')
33 EnabledModule.create(:project => project, :name => 'news')
32 34 end
33 35
34 36 def teardown
35 37 Setting.rest_api_enabled = '0'
36 38 Setting.login_required = '0'
37 39 end
38 40
39 # Using the NewsController because it's a simple API.
40 context "get /news" do
41 setup do
42 project = Project.find('onlinestore')
43 EnabledModule.create(:project => project, :name => 'news')
44 end
45
46 context "in :xml format" do
47 should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.xml")
48 end
49
50 context "in :json format" do
51 should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.json")
52 end
53 end
41 should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.xml")
42 should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.json")
54 43 end
@@ -1,50 +1,41
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::HttpBasicLoginWithApiTokenTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 22 :enumerations, :users, :issue_categories,
23 23 :projects_trackers,
24 24 :roles,
25 25 :member_roles,
26 26 :members,
27 27 :enabled_modules
28 28
29 29 def setup
30 30 Setting.rest_api_enabled = '1'
31 31 Setting.login_required = '1'
32 32 end
33 33
34 34 def teardown
35 35 Setting.rest_api_enabled = '0'
36 36 Setting.login_required = '0'
37 37 end
38 38
39 # Using the NewsController because it's a simple API.
40 context "get /news" do
41
42 context "in :xml format" do
43 should_allow_http_basic_auth_with_key(:get, "/news.xml")
44 end
45
46 context "in :json format" do
47 should_allow_http_basic_auth_with_key(:get, "/news.json")
48 end
49 end
39 should_allow_http_basic_auth_with_key(:get, "/news.xml")
40 should_allow_http_basic_auth_with_key(:get, "/news.json")
50 41 end
This diff has been collapsed as it changes many lines, (811 lines changed) Show them Hide them
@@ -1,799 +1,632
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
21 21 fixtures :projects,
22 22 :users,
23 23 :roles,
24 24 :members,
25 25 :member_roles,
26 26 :issues,
27 27 :issue_statuses,
28 28 :issue_relations,
29 29 :versions,
30 30 :trackers,
31 31 :projects_trackers,
32 32 :issue_categories,
33 33 :enabled_modules,
34 34 :enumerations,
35 35 :attachments,
36 36 :workflows,
37 37 :custom_fields,
38 38 :custom_values,
39 39 :custom_fields_projects,
40 40 :custom_fields_trackers,
41 41 :time_entries,
42 42 :journals,
43 43 :journal_details,
44 44 :queries,
45 45 :attachments
46 46
47 47 def setup
48 48 Setting.rest_api_enabled = '1'
49 49 end
50 50
51 context "/issues" do
52 # Use a private project to make sure auth is really working and not just
53 # only showing public issues.
54 should_allow_api_authentication(:get, "/projects/private-child/issues.xml")
55
56 should "contain metadata" do
57 get '/issues.xml'
51 # Use a private project to make sure auth is really working and not just
52 # only showing public issues.
53 should_allow_api_authentication(:get, "/projects/private-child/issues.xml")
54 should_allow_api_authentication(:get, "/projects/private-child/issues.json")
55
56 should_allow_api_authentication(:get, "/issues/6.xml")
57 should_allow_api_authentication(:get, "/issues/6.json")
58
59 should_allow_api_authentication(
60 :post,
61 '/issues.xml',
62 {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}},
63 {:success_code => :created}
64 )
65 should_allow_api_authentication(:post,
66 '/issues.json',
67 {:issue => {:project_id => 1, :subject => 'API test',
68 :tracker_id => 2, :status_id => 3}},
69 {:success_code => :created})
70
71 should_allow_api_authentication(:put,
72 '/issues/6.xml',
73 {:issue => {:subject => 'API update', :notes => 'A new note'}},
74 {:success_code => :ok})
75 should_allow_api_authentication(:put,
76 '/issues/6.json',
77 {:issue => {:subject => 'API update', :notes => 'A new note'}},
78 {:success_code => :ok})
79
80 should_allow_api_authentication(:delete,
81 '/issues/6.xml',
82 {},
83 {:success_code => :ok})
84 should_allow_api_authentication(:delete,
85 '/issues/6.json',
86 {},
87 {:success_code => :ok})
88
89 test "GET /issues.xml should contain metadata" do
90 get '/issues.xml'
91 assert_select 'issues[type=array][total_count=?][limit="25"][offset="0"]',
92 assigns(:issue_count).to_s
93 end
58 94
59 assert_select 'issues[type=array][total_count=?][limit="25"][offset="0"]', assigns(:issue_count).to_s
60 end
95 test "GET /issues.xml with nometa param should not contain metadata" do
96 get '/issues.xml?nometa=1'
97 assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
98 end
61 99
62 context "with offset and limit" do
63 should "use the params" do
64 get '/issues.xml?offset=2&limit=3'
100 test "GET /issues.xml with nometa header should not contain metadata" do
101 get '/issues.xml', {}, {'X-Redmine-Nometa' => '1'}
102 assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
103 end
65 104
66 assert_equal 3, assigns(:limit)
67 assert_equal 2, assigns(:offset)
68 assert_select 'issues issue', 3
69 end
70 end
105 test "GET /issues.xml with offset and limit" do
106 get '/issues.xml?offset=2&limit=3'
71 107
72 context "with nometa param" do
73 should "not contain metadata" do
74 get '/issues.xml?nometa=1'
108 assert_equal 3, assigns(:limit)
109 assert_equal 2, assigns(:offset)
110 assert_select 'issues issue', 3
111 end
75 112
76 assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
77 end
78 end
113 test "GET /issues.xml with relations" do
114 get '/issues.xml?include=relations'
79 115
80 context "with nometa header" do
81 should "not contain metadata" do
82 get '/issues.xml', {}, {'X-Redmine-Nometa' => '1'}
116 assert_response :success
117 assert_equal 'application/xml', @response.content_type
83 118
84 assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
85 end
119 assert_select 'issue id:content(3)' do
120 assert_select '~ relations relation', 1
121 assert_select '~ relations relation[id="2"][issue_id="2"][issue_to_id="3"][relation_type=relates]'
86 122 end
87 123
88 context "with relations" do
89 should "display relations" do
90 get '/issues.xml?include=relations'
91
92 assert_response :success
93 assert_equal 'application/xml', @response.content_type
124 assert_select 'issue id:content(1)' do
125 assert_select '~ relations'
126 assert_select '~ relations relation', 0
127 end
128 end
94 129
95 assert_select 'issue id:content(3)' do
96 assert_select '~ relations relation', 1
97 assert_select '~ relations relation[id="2"][issue_id="2"][issue_to_id="3"][relation_type=relates]'
98 end
130 test "GET /issues.xml with invalid query params" do
131 get '/issues.xml', {:f => ['start_date'], :op => {:start_date => '='}}
99 132
100 assert_select 'issue id:content(1)' do
101 assert_select '~ relations'
102 assert_select '~ relations relation', 0
103 end
104 end
105 end
133 assert_response :unprocessable_entity
134 assert_equal 'application/xml', @response.content_type
135 assert_select 'errors error', :text => "Start date can't be blank"
136 end
106 137
107 context "with invalid query params" do
108 should "return errors" do
109 get '/issues.xml', {:f => ['start_date'], :op => {:start_date => '='}}
138 test "GET /issues.xml with custom field filter" do
139 get '/issues.xml',
140 {:set_filter => 1, :f => ['cf_1'], :op => {:cf_1 => '='}, :v => {:cf_1 => ['MySQL']}}
110 141
111 assert_response :unprocessable_entity
112 assert_equal 'application/xml', @response.content_type
113 assert_select 'errors error', :text => "Start date can't be blank"
114 end
115 end
142 expected_ids = Issue.visible.
143 joins(:custom_values).
144 where(:custom_values => {:custom_field_id => 1, :value => 'MySQL'}).map(&:id)
145 assert expected_ids.any?
116 146
117 context "with custom field filter" do
118 should "show only issues with the custom field value" do
119 get '/issues.xml',
120 {:set_filter => 1, :f => ['cf_1'], :op => {:cf_1 => '='},
121 :v => {:cf_1 => ['MySQL']}}
122 expected_ids = Issue.visible.
123 joins(:custom_values).
124 where(:custom_values => {:custom_field_id => 1, :value => 'MySQL'}).map(&:id)
125 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
126 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
127 end
128 end
147 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
148 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
129 149 end
150 end
130 151
131 context "with custom field filter (shorthand method)" do
132 should "show only issues with the custom field value" do
133 get '/issues.xml', { :cf_1 => 'MySQL' }
152 test "GET /issues.xml with custom field filter (shorthand method)" do
153 get '/issues.xml', {:cf_1 => 'MySQL'}
134 154
135 expected_ids = Issue.visible.
136 joins(:custom_values).
137 where(:custom_values => {:custom_field_id => 1, :value => 'MySQL'}).map(&:id)
155 expected_ids = Issue.visible.
156 joins(:custom_values).
157 where(:custom_values => {:custom_field_id => 1, :value => 'MySQL'}).map(&:id)
158 assert expected_ids.any?
138 159
139 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
140 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
141 end
142 end
160 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
161 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
143 162 end
144 163 end
145 164
146 165 def test_index_should_include_issue_attributes
147 166 get '/issues.xml'
148 167 assert_select 'issues>issue>is_private', :text => 'false'
149 168 end
150 169
151 170 def test_index_should_allow_timestamp_filtering
152 171 Issue.delete_all
153 172 Issue.generate!(:subject => '1').update_column(:updated_on, Time.parse("2014-01-02T10:25:00Z"))
154 173 Issue.generate!(:subject => '2').update_column(:updated_on, Time.parse("2014-01-02T12:13:00Z"))
155 174
156 175 get '/issues.xml',
157 176 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '<='},
158 177 :v => {:updated_on => ['2014-01-02T12:00:00Z']}}
159 178 assert_select 'issues>issue', :count => 1
160 179 assert_select 'issues>issue>subject', :text => '1'
161 180
162 181 get '/issues.xml',
163 182 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '>='},
164 183 :v => {:updated_on => ['2014-01-02T12:00:00Z']}}
165 184 assert_select 'issues>issue', :count => 1
166 185 assert_select 'issues>issue>subject', :text => '2'
167 186
168 187 get '/issues.xml',
169 188 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '>='},
170 189 :v => {:updated_on => ['2014-01-02T08:00:00Z']}}
171 190 assert_select 'issues>issue', :count => 2
172 191 end
173 192
174 context "/index.json" do
175 should_allow_api_authentication(:get, "/projects/private-child/issues.json")
176 end
193 test "GET /issues.xml with filter" do
194 get '/issues.xml?status_id=5'
177 195
178 context "/index.xml with filter" do
179 should "show only issues with the status_id" do
180 get '/issues.xml?status_id=5'
196 expected_ids = Issue.visible.where(:status_id => 5).map(&:id)
197 assert expected_ids.any?
181 198
182 expected_ids = Issue.visible.where(:status_id => 5).map(&:id)
183
184 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
185 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
186 end
199 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
200 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
187 201 end
188 202 end
189 203
190 context "/index.json with filter" do
191 should "show only issues with the status_id" do
192 get '/issues.json?status_id=5'
193
194 json = ActiveSupport::JSON.decode(response.body)
195 status_ids_used = json['issues'].collect {|j| j['status']['id'] }
196 assert_equal 3, status_ids_used.length
197 assert status_ids_used.all? {|id| id == 5 }
198 end
204 test "GET /issues.json with filter" do
205 get '/issues.json?status_id=5'
199 206
207 json = ActiveSupport::JSON.decode(response.body)
208 status_ids_used = json['issues'].collect {|j| j['status']['id'] }
209 assert_equal 3, status_ids_used.length
210 assert status_ids_used.all? {|id| id == 5 }
200 211 end
201 212
202 # Issue 6 is on a private project
203 context "/issues/6.xml" do
204 should_allow_api_authentication(:get, "/issues/6.xml")
205 end
213 test "GET /issues/:id.xml with journals" do
214 get '/issues/1.xml?include=journals'
206 215
207 context "/issues/6.json" do
208 should_allow_api_authentication(:get, "/issues/6.json")
216 assert_select 'issue journals[type=array]' do
217 assert_select 'journal[id="1"]' do
218 assert_select 'details[type=array]' do
219 assert_select 'detail[name=status_id]' do
220 assert_select 'old_value', :text => '1'
221 assert_select 'new_value', :text => '2'
222 end
223 end
224 end
225 end
209 226 end
210 227
211 context "GET /issues/:id" do
212 context "with journals" do
213 context ".xml" do
214 should "display journals" do
215 get '/issues/1.xml?include=journals'
228 test "GET /issues/:id.xml with custom fields" do
229 get '/issues/3.xml'
216 230
217 assert_select 'issue journals[type=array]' do
218 assert_select 'journal[id="1"]' do
219 assert_select 'details[type=array]' do
220 assert_select 'detail[name=status_id]' do
221 assert_select 'old_value', :text => '1'
222 assert_select 'new_value', :text => '2'
223 end
224 end
225 end
226 end
227 end
231 assert_select 'issue custom_fields[type=array]' do
232 assert_select 'custom_field[id="1"]' do
233 assert_select 'value', :text => 'MySQL'
228 234 end
229 235 end
236 assert_nothing_raised do
237 Hash.from_xml(response.body).to_xml
238 end
239 end
230 240
231 context "with custom fields" do
232 context ".xml" do
233 should "display custom fields" do
234 get '/issues/3.xml'
241 test "GET /issues/:id.xml with multi custom fields" do
242 field = CustomField.find(1)
243 field.update_attribute :multiple, true
244 issue = Issue.find(3)
245 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
246 issue.save!
235 247
236 assert_select 'issue custom_fields[type=array]' do
237 assert_select 'custom_field[id="1"]' do
238 assert_select 'value', :text => 'MySQL'
239 end
240 end
248 get '/issues/3.xml'
249 assert_response :success
241 250
242 assert_nothing_raised do
243 Hash.from_xml(response.body).to_xml
244 end
245 end
251 assert_select 'issue custom_fields[type=array]' do
252 assert_select 'custom_field[id="1"]' do
253 assert_select 'value[type=array] value', 2
246 254 end
247 255 end
256 xml = Hash.from_xml(response.body)
257 custom_fields = xml['issue']['custom_fields']
258 assert_kind_of Array, custom_fields
259 field = custom_fields.detect {|f| f['id'] == '1'}
260 assert_kind_of Hash, field
261 assert_equal ['MySQL', 'Oracle'], field['value'].sort
262 end
248 263
249 context "with multi custom fields" do
250 setup do
251 field = CustomField.find(1)
252 field.update_attribute :multiple, true
253 issue = Issue.find(3)
254 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
255 issue.save!
256 end
264 test "GET /issues/:id.json with multi custom fields" do
265 field = CustomField.find(1)
266 field.update_attribute :multiple, true
267 issue = Issue.find(3)
268 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
269 issue.save!
257 270
258 context ".xml" do
259 should "display custom fields" do
260 get '/issues/3.xml'
261 assert_response :success
271 get '/issues/3.json'
272 assert_response :success
262 273
263 assert_select 'issue custom_fields[type=array]' do
264 assert_select 'custom_field[id="1"]' do
265 assert_select 'value[type=array] value', 2
266 end
267 end
274 json = ActiveSupport::JSON.decode(response.body)
275 custom_fields = json['issue']['custom_fields']
276 assert_kind_of Array, custom_fields
277 field = custom_fields.detect {|f| f['id'] == 1}
278 assert_kind_of Hash, field
279 assert_equal ['MySQL', 'Oracle'], field['value'].sort
280 end
268 281
269 xml = Hash.from_xml(response.body)
270 custom_fields = xml['issue']['custom_fields']
271 assert_kind_of Array, custom_fields
272 field = custom_fields.detect {|f| f['id'] == '1'}
273 assert_kind_of Hash, field
274 assert_equal ['MySQL', 'Oracle'], field['value'].sort
275 end
276 end
282 test "GET /issues/:id.xml with empty value for multi custom field" do
283 field = CustomField.find(1)
284 field.update_attribute :multiple, true
285 issue = Issue.find(3)
286 issue.custom_field_values = {1 => ['']}
287 issue.save!
277 288
278 context ".json" do
279 should "display custom fields" do
280 get '/issues/3.json'
281 assert_response :success
282 json = ActiveSupport::JSON.decode(response.body)
283 custom_fields = json['issue']['custom_fields']
284 assert_kind_of Array, custom_fields
285 field = custom_fields.detect {|f| f['id'] == 1}
286 assert_kind_of Hash, field
287 assert_equal ['MySQL', 'Oracle'], field['value'].sort
288 end
289 end
290 end
289 get '/issues/3.xml'
291 290
292 context "with empty value for multi custom field" do
293 setup do
294 field = CustomField.find(1)
295 field.update_attribute :multiple, true
296 issue = Issue.find(3)
297 issue.custom_field_values = {1 => ['']}
298 issue.save!
291 assert_select 'issue custom_fields[type=array]' do
292 assert_select 'custom_field[id="1"]' do
293 assert_select 'value[type=array]:empty'
299 294 end
295 end
296 xml = Hash.from_xml(response.body)
297 custom_fields = xml['issue']['custom_fields']
298 assert_kind_of Array, custom_fields
299 field = custom_fields.detect {|f| f['id'] == '1'}
300 assert_kind_of Hash, field
301 assert_equal [], field['value']
302 end
300 303
301 context ".xml" do
302 should "display custom fields" do
303 get '/issues/3.xml'
304 test "GET /issues/:id.json with empty value for multi custom field" do
305 field = CustomField.find(1)
306 field.update_attribute :multiple, true
307 issue = Issue.find(3)
308 issue.custom_field_values = {1 => ['']}
309 issue.save!
304 310
305 assert_select 'issue custom_fields[type=array]' do
306 assert_select 'custom_field[id="1"]' do
307 assert_select 'value[type=array]:empty'
308 end
309 end
311 get '/issues/3.json'
312 assert_response :success
313 json = ActiveSupport::JSON.decode(response.body)
314 custom_fields = json['issue']['custom_fields']
315 assert_kind_of Array, custom_fields
316 field = custom_fields.detect {|f| f['id'] == 1}
317 assert_kind_of Hash, field
318 assert_equal [], field['value'].sort
319 end
310 320
311 xml = Hash.from_xml(response.body)
312 custom_fields = xml['issue']['custom_fields']
313 assert_kind_of Array, custom_fields
314 field = custom_fields.detect {|f| f['id'] == '1'}
315 assert_kind_of Hash, field
316 assert_equal [], field['value']
317 end
318 end
321 test "GET /issues/:id.xml with attachments" do
322 get '/issues/3.xml?include=attachments'
319 323
320 context ".json" do
321 should "display custom fields" do
322 get '/issues/3.json'
323 assert_response :success
324 json = ActiveSupport::JSON.decode(response.body)
325 custom_fields = json['issue']['custom_fields']
326 assert_kind_of Array, custom_fields
327 field = custom_fields.detect {|f| f['id'] == 1}
328 assert_kind_of Hash, field
329 assert_equal [], field['value'].sort
330 end
324 assert_select 'issue attachments[type=array]' do
325 assert_select 'attachment', 5
326 assert_select 'attachment id:content(4)' do
327 assert_select '~ filename', :text => 'source.rb'
328 assert_select '~ content_url', :text => 'http://www.example.com/attachments/download/4/source.rb'
331 329 end
332 330 end
331 end
333 332
334 context "with attachments" do
335 context ".xml" do
336 should "display attachments" do
337 get '/issues/3.xml?include=attachments'
338
339 assert_select 'issue attachments[type=array]' do
340 assert_select 'attachment', 5
341 assert_select 'attachment id:content(4)' do
342 assert_select '~ filename', :text => 'source.rb'
343 assert_select '~ content_url', :text => 'http://www.example.com/attachments/download/4/source.rb'
344 end
345 end
346 end
347 end
348 end
333 test "GET /issues/:id.xml with subtasks" do
334 issue = Issue.generate_with_descendants!(:project_id => 1)
335 get "/issues/#{issue.id}.xml?include=children"
349 336
350 context "with subtasks" do
351 setup do
352 @c1 = Issue.create!(
353 :status_id => 1, :subject => "child c1",
354 :tracker_id => 1, :project_id => 1, :author_id => 1,
355 :parent_issue_id => 1
356 )
357 @c2 = Issue.create!(
358 :status_id => 1, :subject => "child c2",
359 :tracker_id => 1, :project_id => 1, :author_id => 1,
360 :parent_issue_id => 1
361 )
362 @c3 = Issue.create!(
363 :status_id => 1, :subject => "child c3",
364 :tracker_id => 1, :project_id => 1, :author_id => 1,
365 :parent_issue_id => @c1.id
366 )
367 end
337 assert_select 'issue children[type=array]' do
338 assert_select 'issue', 2
339 assert_select 'issue children', 1
340 end
341 end
368 342
369 context ".xml" do
370 should "display children" do
371 get '/issues/1.xml?include=children'
372
373 assert_select 'issue children[type=array]' do
374 assert_select 'issue', 2
375 assert_select 'issue[id=?]', @c1.id.to_s do
376 assert_select 'subject', :text => 'child c1'
377 assert_select 'children' do
378 assert_select 'issue[id=?]', @c3.id.to_s
379 end
380 end
381 end
382 end
343 test "GET /issues/:id.json with subtasks" do
344 issue = Issue.generate_with_descendants!(:project_id => 1)
345 get "/issues/#{issue.id}.json?include=children"
383 346
384 context ".json" do
385 should "display children" do
386 get '/issues/1.json?include=children'
387
388 json = ActiveSupport::JSON.decode(response.body)
389 assert_equal([
390 {
391 'id' => @c1.id, 'subject' => 'child c1', 'tracker' => {'id' => 1, 'name' => 'Bug'},
392 'children' => [{'id' => @c3.id, 'subject' => 'child c3',
393 'tracker' => {'id' => 1, 'name' => 'Bug'} }]
394 },
395 { 'id' => @c2.id, 'subject' => 'child c2', 'tracker' => {'id' => 1, 'name' => 'Bug'} }
396 ],
397 json['issue']['children'])
398 end
399 end
400 end
401 end
347 json = ActiveSupport::JSON.decode(response.body)
348 assert_equal 2, json['issue']['children'].size
349 assert_equal 1, json['issue']['children'].select {|child| child.key?('children')}.size
402 350 end
403 351
404 352 def test_show_should_include_issue_attributes
405 353 get '/issues/1.xml'
406 354 assert_select 'issue>is_private', :text => 'false'
407 355 end
408 356
409 357 test "GET /issues/:id.xml?include=watchers should include watchers" do
410 358 Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
411 359
412 360 get '/issues/1.xml?include=watchers', {}, credentials('jsmith')
413 361
414 362 assert_response :ok
415 363 assert_equal 'application/xml', response.content_type
416 364 assert_select 'issue' do
417 365 assert_select 'watchers', Issue.find(1).watchers.count
418 366 assert_select 'watchers' do
419 367 assert_select 'user[id=3]'
420 368 end
421 369 end
422 370 end
423 371
424 context "POST /issues.xml" do
425 should_allow_api_authentication(
426 :post,
427 '/issues.xml',
428 {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}},
429 {:success_code => :created}
430 )
431 should "create an issue with the attributes" do
432 assert_difference('Issue.count') do
433 post '/issues.xml',
434 {:issue => {:project_id => 1, :subject => 'API test',
435 :tracker_id => 2, :status_id => 3}}, credentials('jsmith')
436 end
437 issue = Issue.order('id DESC').first
438 assert_equal 1, issue.project_id
439 assert_equal 2, issue.tracker_id
440 assert_equal 3, issue.status_id
441 assert_equal 'API test', issue.subject
442
443 assert_response :created
444 assert_equal 'application/xml', @response.content_type
445 assert_select 'issue > id', :text => issue.id.to_s
372 test "POST /issues.xml should create an issue with the attributes" do
373 assert_difference('Issue.count') do
374 post '/issues.xml',
375 {:issue => {:project_id => 1, :subject => 'API test',
376 :tracker_id => 2, :status_id => 3}}, credentials('jsmith')
446 377 end
378 issue = Issue.order('id DESC').first
379 assert_equal 1, issue.project_id
380 assert_equal 2, issue.tracker_id
381 assert_equal 3, issue.status_id
382 assert_equal 'API test', issue.subject
383
384 assert_response :created
385 assert_equal 'application/xml', @response.content_type
386 assert_select 'issue > id', :text => issue.id.to_s
447 387 end
448 388
449 389 test "POST /issues.xml with watcher_user_ids should create issue with watchers" do
450 390 assert_difference('Issue.count') do
451 391 post '/issues.xml',
452 392 {:issue => {:project_id => 1, :subject => 'Watchers',
453 393 :tracker_id => 2, :status_id => 3, :watcher_user_ids => [3, 1]}}, credentials('jsmith')
454 394 assert_response :created
455 395 end
456 396 issue = Issue.order('id desc').first
457 397 assert_equal 2, issue.watchers.size
458 398 assert_equal [1, 3], issue.watcher_user_ids.sort
459 399 end
460 400
461 context "POST /issues.xml with failure" do
462 should "have an errors tag" do
463 assert_no_difference('Issue.count') do
464 post '/issues.xml', {:issue => {:project_id => 1}}, credentials('jsmith')
465 end
466
467 assert_select 'errors error', :text => "Subject can't be blank"
468 end
469 end
470
471 context "POST /issues.json" do
472 should_allow_api_authentication(:post,
473 '/issues.json',
474 {:issue => {:project_id => 1, :subject => 'API test',
475 :tracker_id => 2, :status_id => 3}},
476 {:success_code => :created})
477
478 should "create an issue with the attributes" do
479 assert_difference('Issue.count') do
480 post '/issues.json',
481 {:issue => {:project_id => 1, :subject => 'API test',
482 :tracker_id => 2, :status_id => 3}},
483 credentials('jsmith')
484 end
485
486 issue = Issue.order('id DESC').first
487 assert_equal 1, issue.project_id
488 assert_equal 2, issue.tracker_id
489 assert_equal 3, issue.status_id
490 assert_equal 'API test', issue.subject
401 test "POST /issues.xml with failure should return errors" do
402 assert_no_difference('Issue.count') do
403 post '/issues.xml', {:issue => {:project_id => 1}}, credentials('jsmith')
491 404 end
492 405
406 assert_select 'errors error', :text => "Subject can't be blank"
493 407 end
494 408
495 context "POST /issues.json with failure" do
496 should "have an errors element" do
497 assert_no_difference('Issue.count') do
498 post '/issues.json', {:issue => {:project_id => 1}}, credentials('jsmith')
499 end
500
501 json = ActiveSupport::JSON.decode(response.body)
502 assert json['errors'].include?("Subject can't be blank")
503 end
504 end
505
506 # Issue 6 is on a private project
507 context "PUT /issues/6.xml" do
508 setup do
509 @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}}
510 end
511
512 should_allow_api_authentication(:put,
513 '/issues/6.xml',
514 {:issue => {:subject => 'API update', :notes => 'A new note'}},
515 {:success_code => :ok})
516
517 should "not create a new issue" do
518 assert_no_difference('Issue.count') do
519 put '/issues/6.xml', @parameters, credentials('jsmith')
520 end
521 end
522
523 should "create a new journal" do
524 assert_difference('Journal.count') do
525 put '/issues/6.xml', @parameters, credentials('jsmith')
526 end
527 end
528
529 should "add the note to the journal" do
530 put '/issues/6.xml', @parameters, credentials('jsmith')
531
532 journal = Journal.last
533 assert_equal "A new note", journal.notes
534 end
535
536 should "update the issue" do
537 put '/issues/6.xml', @parameters, credentials('jsmith')
538
539 issue = Issue.find(6)
540 assert_equal "API update", issue.subject
409 test "POST /issues.json should create an issue with the attributes" do
410 assert_difference('Issue.count') do
411 post '/issues.json',
412 {:issue => {:project_id => 1, :subject => 'API test',
413 :tracker_id => 2, :status_id => 3}},
414 credentials('jsmith')
541 415 end
542 416
417 issue = Issue.order('id DESC').first
418 assert_equal 1, issue.project_id
419 assert_equal 2, issue.tracker_id
420 assert_equal 3, issue.status_id
421 assert_equal 'API test', issue.subject
543 422 end
544 423
545 context "PUT /issues/3.xml with custom fields" do
546 setup do
547 @parameters = {
548 :issue => {:custom_fields => [{'id' => '1', 'value' => 'PostgreSQL' },
549 {'id' => '2', 'value' => '150'}]}
550 }
424 test "POST /issues.json with failure should return errors" do
425 assert_no_difference('Issue.count') do
426 post '/issues.json', {:issue => {:project_id => 1}}, credentials('jsmith')
551 427 end
552 428
553 should "update custom fields" do
554 assert_no_difference('Issue.count') do
555 put '/issues/3.xml', @parameters, credentials('jsmith')
556 end
557
558 issue = Issue.find(3)
559 assert_equal '150', issue.custom_value_for(2).value
560 assert_equal 'PostgreSQL', issue.custom_value_for(1).value
561 end
429 json = ActiveSupport::JSON.decode(response.body)
430 assert json['errors'].include?("Subject can't be blank")
562 431 end
563 432
564 context "PUT /issues/3.xml with multi custom fields" do
565 setup do
566 field = CustomField.find(1)
567 field.update_attribute :multiple, true
568 @parameters = {
569 :issue => {:custom_fields => [{'id' => '1', 'value' => ['MySQL', 'PostgreSQL'] },
570 {'id' => '2', 'value' => '150'}]}
571 }
433 test "PUT /issues/:id.xml" do
434 assert_difference('Journal.count') do
435 put '/issues/6.xml',
436 {:issue => {:subject => 'API update', :notes => 'A new note'}},
437 credentials('jsmith')
572 438 end
573 439
574 should "update custom fields" do
575 assert_no_difference('Issue.count') do
576 put '/issues/3.xml', @parameters, credentials('jsmith')
577 end
578
579 issue = Issue.find(3)
580 assert_equal '150', issue.custom_value_for(2).value
581 assert_equal ['MySQL', 'PostgreSQL'], issue.custom_field_value(1).sort
582 end
440 issue = Issue.find(6)
441 assert_equal "API update", issue.subject
442 journal = Journal.last
443 assert_equal "A new note", journal.notes
583 444 end
584 445
585 context "PUT /issues/3.xml with project change" do
586 setup do
587 @parameters = {:issue => {:project_id => 2, :subject => 'Project changed'}}
588 end
589
590 should "update project" do
591 assert_no_difference('Issue.count') do
592 put '/issues/3.xml', @parameters, credentials('jsmith')
593 end
594
595 issue = Issue.find(3)
596 assert_equal 2, issue.project_id
597 assert_equal 'Project changed', issue.subject
598 end
446 test "PUT /issues/:id.xml with custom fields" do
447 put '/issues/3.xml',
448 {:issue => {:custom_fields => [
449 {'id' => '1', 'value' => 'PostgreSQL' },
450 {'id' => '2', 'value' => '150'}
451 ]}},
452 credentials('jsmith')
453
454 issue = Issue.find(3)
455 assert_equal '150', issue.custom_value_for(2).value
456 assert_equal 'PostgreSQL', issue.custom_value_for(1).value
599 457 end
600 458
601 context "PUT /issues/6.xml with failed update" do
602 setup do
603 @parameters = {:issue => {:subject => ''}}
604 end
605
606 should "not create a new issue" do
607 assert_no_difference('Issue.count') do
608 put '/issues/6.xml', @parameters, credentials('jsmith')
609 end
610 end
611
612 should "not create a new journal" do
613 assert_no_difference('Journal.count') do
614 put '/issues/6.xml', @parameters, credentials('jsmith')
615 end
616 end
459 test "PUT /issues/:id.xml with multi custom fields" do
460 field = CustomField.find(1)
461 field.update_attribute :multiple, true
617 462
618 should "have an errors tag" do
619 put '/issues/6.xml', @parameters, credentials('jsmith')
463 put '/issues/3.xml',
464 {:issue => {:custom_fields => [
465 {'id' => '1', 'value' => ['MySQL', 'PostgreSQL'] },
466 {'id' => '2', 'value' => '150'}
467 ]}},
468 credentials('jsmith')
620 469
621 assert_select 'errors error', :text => "Subject can't be blank"
622 end
470 issue = Issue.find(3)
471 assert_equal '150', issue.custom_value_for(2).value
472 assert_equal ['MySQL', 'PostgreSQL'], issue.custom_field_value(1).sort
623 473 end
624 474
625 context "PUT /issues/6.json" do
626 setup do
627 @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}}
628 end
629
630 should_allow_api_authentication(:put,
631 '/issues/6.json',
632 {:issue => {:subject => 'API update', :notes => 'A new note'}},
633 {:success_code => :ok})
475 test "PUT /issues/:id.xml with project change" do
476 put '/issues/3.xml',
477 {:issue => {:project_id => 2, :subject => 'Project changed'}},
478 credentials('jsmith')
634 479
635 should "update the issue" do
636 assert_no_difference('Issue.count') do
637 assert_difference('Journal.count') do
638 put '/issues/6.json', @parameters, credentials('jsmith')
480 issue = Issue.find(3)
481 assert_equal 2, issue.project_id
482 assert_equal 'Project changed', issue.subject
483 end
639 484
640 assert_response :ok
641 assert_equal '', response.body
642 end
643 end
485 test "PUT /issues/:id.xml with failed update" do
486 put '/issues/6.xml', {:issue => {:subject => ''}}, credentials('jsmith')
644 487
645 issue = Issue.find(6)
646 assert_equal "API update", issue.subject
647 journal = Journal.last
648 assert_equal "A new note", journal.notes
649 end
488 assert_response :unprocessable_entity
489 assert_select 'errors error', :text => "Subject can't be blank"
650 490 end
651 491
652 context "PUT /issues/6.json with failed update" do
653 should "return errors" do
654 assert_no_difference('Issue.count') do
655 assert_no_difference('Journal.count') do
656 put '/issues/6.json', {:issue => {:subject => ''}}, credentials('jsmith')
657
658 assert_response :unprocessable_entity
659 end
660 end
492 test "PUT /issues/:id.json" do
493 assert_difference('Journal.count') do
494 put '/issues/6.json',
495 {:issue => {:subject => 'API update', :notes => 'A new note'}},
496 credentials('jsmith')
661 497
662 json = ActiveSupport::JSON.decode(response.body)
663 assert json['errors'].include?("Subject can't be blank")
498 assert_response :ok
499 assert_equal '', response.body
664 500 end
501
502 issue = Issue.find(6)
503 assert_equal "API update", issue.subject
504 journal = Journal.last
505 assert_equal "A new note", journal.notes
665 506 end
666 507
667 context "DELETE /issues/1.xml" do
668 should_allow_api_authentication(:delete,
669 '/issues/6.xml',
670 {},
671 {:success_code => :ok})
508 test "PUT /issues/:id.json with failed update" do
509 put '/issues/6.json', {:issue => {:subject => ''}}, credentials('jsmith')
672 510
673 should "delete the issue" do
674 assert_difference('Issue.count', -1) do
675 delete '/issues/6.xml', {}, credentials('jsmith')
511 assert_response :unprocessable_entity
512 json = ActiveSupport::JSON.decode(response.body)
513 assert json['errors'].include?("Subject can't be blank")
514 end
676 515
677 assert_response :ok
678 assert_equal '', response.body
679 end
516 test "DELETE /issues/:id.xml" do
517 assert_difference('Issue.count', -1) do
518 delete '/issues/6.xml', {}, credentials('jsmith')
680 519
681 assert_nil Issue.find_by_id(6)
520 assert_response :ok
521 assert_equal '', response.body
682 522 end
523 assert_nil Issue.find_by_id(6)
683 524 end
684 525
685 context "DELETE /issues/1.json" do
686 should_allow_api_authentication(:delete,
687 '/issues/6.json',
688 {},
689 {:success_code => :ok})
690
691 should "delete the issue" do
692 assert_difference('Issue.count', -1) do
693 delete '/issues/6.json', {}, credentials('jsmith')
526 test "DELETE /issues/:id.json" do
527 assert_difference('Issue.count', -1) do
528 delete '/issues/6.json', {}, credentials('jsmith')
694 529
695 assert_response :ok
696 assert_equal '', response.body
697 end
698
699 assert_nil Issue.find_by_id(6)
530 assert_response :ok
531 assert_equal '', response.body
700 532 end
533 assert_nil Issue.find_by_id(6)
701 534 end
702 535
703 536 test "POST /issues/:id/watchers.xml should add watcher" do
704 537 assert_difference 'Watcher.count' do
705 538 post '/issues/1/watchers.xml', {:user_id => 3}, credentials('jsmith')
706 539
707 540 assert_response :ok
708 541 assert_equal '', response.body
709 542 end
710 543 watcher = Watcher.order('id desc').first
711 544 assert_equal Issue.find(1), watcher.watchable
712 545 assert_equal User.find(3), watcher.user
713 546 end
714 547
715 548 test "DELETE /issues/:id/watchers/:user_id.xml should remove watcher" do
716 549 Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
717 550
718 551 assert_difference 'Watcher.count', -1 do
719 552 delete '/issues/1/watchers/3.xml', {}, credentials('jsmith')
720 553
721 554 assert_response :ok
722 555 assert_equal '', response.body
723 556 end
724 557 assert_equal false, Issue.find(1).watched_by?(User.find(3))
725 558 end
726 559
727 560 def test_create_issue_with_uploaded_file
728 561 set_tmp_attachments_directory
729 562 # upload the file
730 563 assert_difference 'Attachment.count' do
731 564 post '/uploads.xml', 'test_create_with_upload',
732 565 {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
733 566 assert_response :created
734 567 end
735 568 xml = Hash.from_xml(response.body)
736 569 token = xml['upload']['token']
737 570 attachment = Attachment.order('id DESC').first
738 571
739 572 # create the issue with the upload's token
740 573 assert_difference 'Issue.count' do
741 574 post '/issues.xml',
742 575 {:issue => {:project_id => 1, :subject => 'Uploaded file',
743 576 :uploads => [{:token => token, :filename => 'test.txt',
744 577 :content_type => 'text/plain'}]}},
745 578 credentials('jsmith')
746 579 assert_response :created
747 580 end
748 581 issue = Issue.order('id DESC').first
749 582 assert_equal 1, issue.attachments.count
750 583 assert_equal attachment, issue.attachments.first
751 584
752 585 attachment.reload
753 586 assert_equal 'test.txt', attachment.filename
754 587 assert_equal 'text/plain', attachment.content_type
755 588 assert_equal 'test_create_with_upload'.size, attachment.filesize
756 589 assert_equal 2, attachment.author_id
757 590
758 591 # get the issue with its attachments
759 592 get "/issues/#{issue.id}.xml", :include => 'attachments'
760 593 assert_response :success
761 594 xml = Hash.from_xml(response.body)
762 595 attachments = xml['issue']['attachments']
763 596 assert_kind_of Array, attachments
764 597 assert_equal 1, attachments.size
765 598 url = attachments.first['content_url']
766 599 assert_not_nil url
767 600
768 601 # download the attachment
769 602 get url
770 603 assert_response :success
771 604 end
772 605
773 606 def test_update_issue_with_uploaded_file
774 607 set_tmp_attachments_directory
775 608 # upload the file
776 609 assert_difference 'Attachment.count' do
777 610 post '/uploads.xml', 'test_upload_with_upload',
778 611 {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
779 612 assert_response :created
780 613 end
781 614 xml = Hash.from_xml(response.body)
782 615 token = xml['upload']['token']
783 616 attachment = Attachment.order('id DESC').first
784 617
785 618 # update the issue with the upload's token
786 619 assert_difference 'Journal.count' do
787 620 put '/issues/1.xml',
788 621 {:issue => {:notes => 'Attachment added',
789 622 :uploads => [{:token => token, :filename => 'test.txt',
790 623 :content_type => 'text/plain'}]}},
791 624 credentials('jsmith')
792 625 assert_response :ok
793 626 assert_equal '', @response.body
794 627 end
795 628
796 629 issue = Issue.find(1)
797 630 assert_include attachment, issue.attachments
798 631 end
799 632 end
@@ -1,1271 +1,1236
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class UserTest < ActiveSupport::TestCase
21 21 fixtures :users, :members, :projects, :roles, :member_roles, :auth_sources,
22 22 :trackers, :issue_statuses,
23 23 :projects_trackers,
24 24 :watchers,
25 25 :issue_categories, :enumerations, :issues,
26 26 :journals, :journal_details,
27 27 :groups_users,
28 28 :enabled_modules
29 29
30 30 include Redmine::I18n
31 31
32 32 def setup
33 33 @admin = User.find(1)
34 34 @jsmith = User.find(2)
35 35 @dlopper = User.find(3)
36 36 end
37 37
38 38 def test_sorted_scope_should_sort_user_by_display_name
39 39 # Use .active to ignore anonymous with localized display name
40 40 assert_equal User.active.map(&:name).map(&:downcase).sort,
41 41 User.active.sorted.map(&:name).map(&:downcase)
42 42 end
43 43
44 44 def test_generate
45 45 User.generate!(:firstname => 'Testing connection')
46 46 User.generate!(:firstname => 'Testing connection')
47 47 assert_equal 2, User.where(:firstname => 'Testing connection').count
48 48 end
49 49
50 50 def test_truth
51 51 assert_kind_of User, @jsmith
52 52 end
53 53
54 54 def test_mail_should_be_stripped
55 55 u = User.new
56 56 u.mail = " foo@bar.com "
57 57 assert_equal "foo@bar.com", u.mail
58 58 end
59 59
60 60 def test_mail_validation
61 61 u = User.new
62 62 u.mail = ''
63 63 assert !u.valid?
64 64 assert_include I18n.translate('activerecord.errors.messages.blank'), u.errors[:mail]
65 65 end
66 66
67 67 def test_login_length_validation
68 68 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
69 69 user.login = "x" * (User::LOGIN_LENGTH_LIMIT+1)
70 70 assert !user.valid?
71 71
72 72 user.login = "x" * (User::LOGIN_LENGTH_LIMIT)
73 73 assert user.valid?
74 74 assert user.save
75 75 end
76 76
77 77 def test_generate_password_should_respect_minimum_password_length
78 78 with_settings :password_min_length => 15 do
79 79 user = User.generate!(:generate_password => true)
80 80 assert user.password.length >= 15
81 81 end
82 82 end
83 83
84 84 def test_generate_password_should_not_generate_password_with_less_than_10_characters
85 85 with_settings :password_min_length => 4 do
86 86 user = User.generate!(:generate_password => true)
87 87 assert user.password.length >= 10
88 88 end
89 89 end
90 90
91 91 def test_generate_password_on_create_should_set_password
92 92 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
93 93 user.login = "newuser"
94 94 user.generate_password = true
95 95 assert user.save
96 96
97 97 password = user.password
98 98 assert user.check_password?(password)
99 99 end
100 100
101 101 def test_generate_password_on_update_should_update_password
102 102 user = User.find(2)
103 103 hash = user.hashed_password
104 104 user.generate_password = true
105 105 assert user.save
106 106
107 107 password = user.password
108 108 assert user.check_password?(password)
109 109 assert_not_equal hash, user.reload.hashed_password
110 110 end
111 111
112 112 def test_create
113 113 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
114 114
115 115 user.login = "jsmith"
116 116 user.password, user.password_confirmation = "password", "password"
117 117 # login uniqueness
118 118 assert !user.save
119 119 assert_equal 1, user.errors.count
120 120
121 121 user.login = "newuser"
122 122 user.password, user.password_confirmation = "password", "pass"
123 123 # password confirmation
124 124 assert !user.save
125 125 assert_equal 1, user.errors.count
126 126
127 127 user.password, user.password_confirmation = "password", "password"
128 128 assert user.save
129 129 end
130 130
131 131 def test_user_before_create_should_set_the_mail_notification_to_the_default_setting
132 132 @user1 = User.generate!
133 133 assert_equal 'only_my_events', @user1.mail_notification
134 134 with_settings :default_notification_option => 'all' do
135 135 @user2 = User.generate!
136 136 assert_equal 'all', @user2.mail_notification
137 137 end
138 138 end
139 139
140 140 def test_user_login_should_be_case_insensitive
141 141 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
142 142 u.login = 'newuser'
143 143 u.password, u.password_confirmation = "password", "password"
144 144 assert u.save
145 145 u = User.new(:firstname => "Similar", :lastname => "User",
146 146 :mail => "similaruser@somenet.foo")
147 147 u.login = 'NewUser'
148 148 u.password, u.password_confirmation = "password", "password"
149 149 assert !u.save
150 150 assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:login]
151 151 end
152 152
153 153 def test_mail_uniqueness_should_not_be_case_sensitive
154 154 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
155 155 u.login = 'newuser1'
156 156 u.password, u.password_confirmation = "password", "password"
157 157 assert u.save
158 158
159 159 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
160 160 u.login = 'newuser2'
161 161 u.password, u.password_confirmation = "password", "password"
162 162 assert !u.save
163 163 assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:mail]
164 164 end
165 165
166 166 def test_update
167 167 assert_equal "admin", @admin.login
168 168 @admin.login = "john"
169 169 assert @admin.save, @admin.errors.full_messages.join("; ")
170 170 @admin.reload
171 171 assert_equal "john", @admin.login
172 172 end
173 173
174 174 def test_update_should_not_fail_for_legacy_user_with_different_case_logins
175 175 u1 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser1@somenet.foo")
176 176 u1.login = 'newuser1'
177 177 assert u1.save
178 178
179 179 u2 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser2@somenet.foo")
180 180 u2.login = 'newuser1'
181 181 assert u2.save(:validate => false)
182 182
183 183 user = User.find(u2.id)
184 184 user.firstname = "firstname"
185 185 assert user.save, "Save failed"
186 186 end
187 187
188 188 def test_destroy_should_delete_members_and_roles
189 189 members = Member.where(:user_id => 2)
190 190 ms = members.count
191 191 rs = members.collect(&:roles).flatten.size
192 192 assert ms > 0
193 193 assert rs > 0
194 194 assert_difference 'Member.count', - ms do
195 195 assert_difference 'MemberRole.count', - rs do
196 196 User.find(2).destroy
197 197 end
198 198 end
199 199 assert_nil User.find_by_id(2)
200 200 assert_equal 0, Member.where(:user_id => 2).count
201 201 end
202 202
203 203 def test_destroy_should_update_attachments
204 204 attachment = Attachment.create!(:container => Project.find(1),
205 205 :file => uploaded_test_file("testfile.txt", "text/plain"),
206 206 :author_id => 2)
207 207
208 208 User.find(2).destroy
209 209 assert_nil User.find_by_id(2)
210 210 assert_equal User.anonymous, attachment.reload.author
211 211 end
212 212
213 213 def test_destroy_should_update_comments
214 214 comment = Comment.create!(
215 215 :commented => News.create!(:project_id => 1,
216 216 :author_id => 1, :title => 'foo', :description => 'foo'),
217 217 :author => User.find(2),
218 218 :comments => 'foo'
219 219 )
220 220
221 221 User.find(2).destroy
222 222 assert_nil User.find_by_id(2)
223 223 assert_equal User.anonymous, comment.reload.author
224 224 end
225 225
226 226 def test_destroy_should_update_issues
227 227 issue = Issue.create!(:project_id => 1, :author_id => 2,
228 228 :tracker_id => 1, :subject => 'foo')
229 229
230 230 User.find(2).destroy
231 231 assert_nil User.find_by_id(2)
232 232 assert_equal User.anonymous, issue.reload.author
233 233 end
234 234
235 235 def test_destroy_should_unassign_issues
236 236 issue = Issue.create!(:project_id => 1, :author_id => 1,
237 237 :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
238 238
239 239 User.find(2).destroy
240 240 assert_nil User.find_by_id(2)
241 241 assert_nil issue.reload.assigned_to
242 242 end
243 243
244 244 def test_destroy_should_update_journals
245 245 issue = Issue.create!(:project_id => 1, :author_id => 2,
246 246 :tracker_id => 1, :subject => 'foo')
247 247 issue.init_journal(User.find(2), "update")
248 248 issue.save!
249 249
250 250 User.find(2).destroy
251 251 assert_nil User.find_by_id(2)
252 252 assert_equal User.anonymous, issue.journals.first.reload.user
253 253 end
254 254
255 255 def test_destroy_should_update_journal_details_old_value
256 256 issue = Issue.create!(:project_id => 1, :author_id => 1,
257 257 :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
258 258 issue.init_journal(User.find(1), "update")
259 259 issue.assigned_to_id = nil
260 260 assert_difference 'JournalDetail.count' do
261 261 issue.save!
262 262 end
263 263 journal_detail = JournalDetail.order('id DESC').first
264 264 assert_equal '2', journal_detail.old_value
265 265
266 266 User.find(2).destroy
267 267 assert_nil User.find_by_id(2)
268 268 assert_equal User.anonymous.id.to_s, journal_detail.reload.old_value
269 269 end
270 270
271 271 def test_destroy_should_update_journal_details_value
272 272 issue = Issue.create!(:project_id => 1, :author_id => 1,
273 273 :tracker_id => 1, :subject => 'foo')
274 274 issue.init_journal(User.find(1), "update")
275 275 issue.assigned_to_id = 2
276 276 assert_difference 'JournalDetail.count' do
277 277 issue.save!
278 278 end
279 279 journal_detail = JournalDetail.order('id DESC').first
280 280 assert_equal '2', journal_detail.value
281 281
282 282 User.find(2).destroy
283 283 assert_nil User.find_by_id(2)
284 284 assert_equal User.anonymous.id.to_s, journal_detail.reload.value
285 285 end
286 286
287 287 def test_destroy_should_update_messages
288 288 board = Board.create!(:project_id => 1, :name => 'Board', :description => 'Board')
289 289 message = Message.create!(:board_id => board.id, :author_id => 2,
290 290 :subject => 'foo', :content => 'foo')
291 291 User.find(2).destroy
292 292 assert_nil User.find_by_id(2)
293 293 assert_equal User.anonymous, message.reload.author
294 294 end
295 295
296 296 def test_destroy_should_update_news
297 297 news = News.create!(:project_id => 1, :author_id => 2,
298 298 :title => 'foo', :description => 'foo')
299 299 User.find(2).destroy
300 300 assert_nil User.find_by_id(2)
301 301 assert_equal User.anonymous, news.reload.author
302 302 end
303 303
304 304 def test_destroy_should_delete_private_queries
305 305 query = Query.new(:name => 'foo', :visibility => Query::VISIBILITY_PRIVATE)
306 306 query.project_id = 1
307 307 query.user_id = 2
308 308 query.save!
309 309
310 310 User.find(2).destroy
311 311 assert_nil User.find_by_id(2)
312 312 assert_nil Query.find_by_id(query.id)
313 313 end
314 314
315 315 def test_destroy_should_update_public_queries
316 316 query = Query.new(:name => 'foo', :visibility => Query::VISIBILITY_PUBLIC)
317 317 query.project_id = 1
318 318 query.user_id = 2
319 319 query.save!
320 320
321 321 User.find(2).destroy
322 322 assert_nil User.find_by_id(2)
323 323 assert_equal User.anonymous, query.reload.user
324 324 end
325 325
326 326 def test_destroy_should_update_time_entries
327 327 entry = TimeEntry.new(:hours => '2', :spent_on => Date.today,
328 328 :activity => TimeEntryActivity.create!(:name => 'foo'))
329 329 entry.project_id = 1
330 330 entry.user_id = 2
331 331 entry.save!
332 332
333 333 User.find(2).destroy
334 334 assert_nil User.find_by_id(2)
335 335 assert_equal User.anonymous, entry.reload.user
336 336 end
337 337
338 338 def test_destroy_should_delete_tokens
339 339 token = Token.create!(:user_id => 2, :value => 'foo')
340 340
341 341 User.find(2).destroy
342 342 assert_nil User.find_by_id(2)
343 343 assert_nil Token.find_by_id(token.id)
344 344 end
345 345
346 346 def test_destroy_should_delete_watchers
347 347 issue = Issue.create!(:project_id => 1, :author_id => 1,
348 348 :tracker_id => 1, :subject => 'foo')
349 349 watcher = Watcher.create!(:user_id => 2, :watchable => issue)
350 350
351 351 User.find(2).destroy
352 352 assert_nil User.find_by_id(2)
353 353 assert_nil Watcher.find_by_id(watcher.id)
354 354 end
355 355
356 356 def test_destroy_should_update_wiki_contents
357 357 wiki_content = WikiContent.create!(
358 358 :text => 'foo',
359 359 :author_id => 2,
360 360 :page => WikiPage.create!(:title => 'Foo',
361 361 :wiki => Wiki.create!(:project_id => 3,
362 362 :start_page => 'Start'))
363 363 )
364 364 wiki_content.text = 'bar'
365 365 assert_difference 'WikiContent::Version.count' do
366 366 wiki_content.save!
367 367 end
368 368
369 369 User.find(2).destroy
370 370 assert_nil User.find_by_id(2)
371 371 assert_equal User.anonymous, wiki_content.reload.author
372 372 wiki_content.versions.each do |version|
373 373 assert_equal User.anonymous, version.reload.author
374 374 end
375 375 end
376 376
377 377 def test_destroy_should_nullify_issue_categories
378 378 category = IssueCategory.create!(:project_id => 1, :assigned_to_id => 2, :name => 'foo')
379 379
380 380 User.find(2).destroy
381 381 assert_nil User.find_by_id(2)
382 382 assert_nil category.reload.assigned_to_id
383 383 end
384 384
385 385 def test_destroy_should_nullify_changesets
386 386 changeset = Changeset.create!(
387 387 :repository => Repository::Subversion.create!(
388 388 :project_id => 1,
389 389 :url => 'file:///tmp',
390 390 :identifier => 'tmp'
391 391 ),
392 392 :revision => '12',
393 393 :committed_on => Time.now,
394 394 :committer => 'jsmith'
395 395 )
396 396 assert_equal 2, changeset.user_id
397 397
398 398 User.find(2).destroy
399 399 assert_nil User.find_by_id(2)
400 400 assert_nil changeset.reload.user_id
401 401 end
402 402
403 403 def test_anonymous_user_should_not_be_destroyable
404 404 assert_no_difference 'User.count' do
405 405 assert_equal false, User.anonymous.destroy
406 406 end
407 407 end
408 408
409 409 def test_password_change_should_destroy_tokens
410 410 recovery_token = Token.create!(:user_id => 2, :action => 'recovery')
411 411 autologin_token = Token.create!(:user_id => 2, :action => 'autologin')
412 412
413 413 user = User.find(2)
414 414 user.password, user.password_confirmation = "a new password", "a new password"
415 415 assert user.save
416 416
417 417 assert_nil Token.find_by_id(recovery_token.id)
418 418 assert_nil Token.find_by_id(autologin_token.id)
419 419 end
420 420
421 421 def test_mail_change_should_destroy_tokens
422 422 recovery_token = Token.create!(:user_id => 2, :action => 'recovery')
423 423 autologin_token = Token.create!(:user_id => 2, :action => 'autologin')
424 424
425 425 user = User.find(2)
426 426 user.mail = "user@somwehere.com"
427 427 assert user.save
428 428
429 429 assert_nil Token.find_by_id(recovery_token.id)
430 430 assert_equal autologin_token, Token.find_by_id(autologin_token.id)
431 431 end
432 432
433 433 def test_change_on_other_fields_should_not_destroy_tokens
434 434 recovery_token = Token.create!(:user_id => 2, :action => 'recovery')
435 435 autologin_token = Token.create!(:user_id => 2, :action => 'autologin')
436 436
437 437 user = User.find(2)
438 438 user.firstname = "Bobby"
439 439 assert user.save
440 440
441 441 assert_equal recovery_token, Token.find_by_id(recovery_token.id)
442 442 assert_equal autologin_token, Token.find_by_id(autologin_token.id)
443 443 end
444 444
445 445 def test_validate_login_presence
446 446 @admin.login = ""
447 447 assert !@admin.save
448 448 assert_equal 1, @admin.errors.count
449 449 end
450 450
451 451 def test_validate_mail_notification_inclusion
452 452 u = User.new
453 453 u.mail_notification = 'foo'
454 454 u.save
455 455 assert_not_equal [], u.errors[:mail_notification]
456 456 end
457 457
458 458 def test_password
459 459 user = User.try_to_login("admin", "admin")
460 460 assert_kind_of User, user
461 461 assert_equal "admin", user.login
462 462 user.password = "hello123"
463 463 assert user.save
464 464
465 465 user = User.try_to_login("admin", "hello123")
466 466 assert_kind_of User, user
467 467 assert_equal "admin", user.login
468 468 end
469 469
470 470 def test_validate_password_length
471 471 with_settings :password_min_length => '100' do
472 472 user = User.new(:firstname => "new100",
473 473 :lastname => "user100", :mail => "newuser100@somenet.foo")
474 474 user.login = "newuser100"
475 475 user.password, user.password_confirmation = "password100", "password100"
476 476 assert !user.save
477 477 assert_equal 1, user.errors.count
478 478 end
479 479 end
480 480
481 481 def test_name_format
482 482 assert_equal 'John S.', @jsmith.name(:firstname_lastinitial)
483 483 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
484 484 assert_equal 'J. Smith', @jsmith.name(:firstinitial_lastname)
485 485 assert_equal 'J.-P. Lang', User.new(:firstname => 'Jean-Philippe', :lastname => 'Lang').name(:firstinitial_lastname)
486 486 end
487 487
488 488 def test_name_should_use_setting_as_default_format
489 489 with_settings :user_format => :firstname_lastname do
490 490 assert_equal 'John Smith', @jsmith.reload.name
491 491 end
492 492 with_settings :user_format => :username do
493 493 assert_equal 'jsmith', @jsmith.reload.name
494 494 end
495 495 with_settings :user_format => :lastname do
496 496 assert_equal 'Smith', @jsmith.reload.name
497 497 end
498 498 end
499 499
500 500 def test_today_should_return_the_day_according_to_user_time_zone
501 501 preference = User.find(1).pref
502 502 date = Date.new(2012, 05, 15)
503 503 time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
504 504 Date.stubs(:today).returns(date)
505 505 Time.stubs(:now).returns(time)
506 506
507 507 preference.update_attribute :time_zone, 'Baku' # UTC+4
508 508 assert_equal '2012-05-16', User.find(1).today.to_s
509 509
510 510 preference.update_attribute :time_zone, 'La Paz' # UTC-4
511 511 assert_equal '2012-05-15', User.find(1).today.to_s
512 512
513 513 preference.update_attribute :time_zone, ''
514 514 assert_equal '2012-05-15', User.find(1).today.to_s
515 515 end
516 516
517 517 def test_time_to_date_should_return_the_date_according_to_user_time_zone
518 518 preference = User.find(1).pref
519 519 time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
520 520
521 521 preference.update_attribute :time_zone, 'Baku' # UTC+4
522 522 assert_equal '2012-05-16', User.find(1).time_to_date(time).to_s
523 523
524 524 preference.update_attribute :time_zone, 'La Paz' # UTC-4
525 525 assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
526 526
527 527 preference.update_attribute :time_zone, ''
528 528 assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
529 529 end
530 530
531 531 def test_fields_for_order_statement_should_return_fields_according_user_format_setting
532 532 with_settings :user_format => 'lastname_coma_firstname' do
533 533 assert_equal ['users.lastname', 'users.firstname', 'users.id'],
534 534 User.fields_for_order_statement
535 535 end
536 536 end
537 537
538 538 def test_fields_for_order_statement_width_table_name_should_prepend_table_name
539 539 with_settings :user_format => 'lastname_firstname' do
540 540 assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'],
541 541 User.fields_for_order_statement('authors')
542 542 end
543 543 end
544 544
545 545 def test_fields_for_order_statement_with_blank_format_should_return_default
546 546 with_settings :user_format => '' do
547 547 assert_equal ['users.firstname', 'users.lastname', 'users.id'],
548 548 User.fields_for_order_statement
549 549 end
550 550 end
551 551
552 552 def test_fields_for_order_statement_with_invalid_format_should_return_default
553 553 with_settings :user_format => 'foo' do
554 554 assert_equal ['users.firstname', 'users.lastname', 'users.id'],
555 555 User.fields_for_order_statement
556 556 end
557 557 end
558 558
559 559 test ".try_to_login with good credentials should return the user" do
560 560 user = User.try_to_login("admin", "admin")
561 561 assert_kind_of User, user
562 562 assert_equal "admin", user.login
563 563 end
564 564
565 565 test ".try_to_login with wrong credentials should return nil" do
566 566 assert_nil User.try_to_login("admin", "foo")
567 567 end
568 568
569 569 def test_try_to_login_with_locked_user_should_return_nil
570 570 @jsmith.status = User::STATUS_LOCKED
571 571 @jsmith.save!
572 572
573 573 user = User.try_to_login("jsmith", "jsmith")
574 574 assert_equal nil, user
575 575 end
576 576
577 577 def test_try_to_login_with_locked_user_and_not_active_only_should_return_user
578 578 @jsmith.status = User::STATUS_LOCKED
579 579 @jsmith.save!
580 580
581 581 user = User.try_to_login("jsmith", "jsmith", false)
582 582 assert_equal @jsmith, user
583 583 end
584 584
585 585 test ".try_to_login should fall-back to case-insensitive if user login is not found as-typed" do
586 586 user = User.try_to_login("AdMin", "admin")
587 587 assert_kind_of User, user
588 588 assert_equal "admin", user.login
589 589 end
590 590
591 591 test ".try_to_login should select the exact matching user first" do
592 592 case_sensitive_user = User.generate! do |user|
593 593 user.password = "admin123"
594 594 end
595 595 # bypass validations to make it appear like existing data
596 596 case_sensitive_user.update_attribute(:login, 'ADMIN')
597 597
598 598 user = User.try_to_login("ADMIN", "admin123")
599 599 assert_kind_of User, user
600 600 assert_equal "ADMIN", user.login
601 601 end
602 602
603 603 if ldap_configured?
604 context "#try_to_login using LDAP" do
605 context "with failed connection to the LDAP server" do
606 should "return nil" do
607 @auth_source = AuthSourceLdap.find(1)
608 AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError, 'Cannot connect')
604 test "#try_to_login using LDAP with failed connection to the LDAP server" do
605 auth_source = AuthSourceLdap.find(1)
606 AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError, 'Cannot connect')
609 607
610 assert_equal nil, User.try_to_login('edavis', 'wrong')
611 end
612 end
608 assert_equal nil, User.try_to_login('edavis', 'wrong')
609 end
613 610
614 context "with an unsuccessful authentication" do
615 should "return nil" do
616 assert_equal nil, User.try_to_login('edavis', 'wrong')
617 end
618 end
611 test "#try_to_login using LDAP" do
612 assert_equal nil, User.try_to_login('edavis', 'wrong')
613 end
619 614
620 context "binding with user's account" do
621 setup do
622 @auth_source = AuthSourceLdap.find(1)
623 @auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
624 @auth_source.account_password = ''
625 @auth_source.save!
615 test "#try_to_login using LDAP binding with user's account" do
616 auth_source = AuthSourceLdap.find(1)
617 auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
618 auth_source.account_password = ''
619 auth_source.save!
626 620
627 @ldap_user = User.new(:mail => 'example1@redmine.org', :firstname => 'LDAP', :lastname => 'user', :auth_source_id => 1)
628 @ldap_user.login = 'example1'
629 @ldap_user.save!
630 end
621 ldap_user = User.new(:mail => 'example1@redmine.org', :firstname => 'LDAP', :lastname => 'user', :auth_source_id => 1)
622 ldap_user.login = 'example1'
623 ldap_user.save!
631 624
632 context "with a successful authentication" do
633 should "return the user" do
634 assert_equal @ldap_user, User.try_to_login('example1', '123456')
635 end
636 end
625 assert_equal @ldap_user, User.try_to_login('example1', '123456')
626 assert_nil User.try_to_login('example1', '11111')
627 end
637 628
638 context "with an unsuccessful authentication" do
639 should "return nil" do
640 assert_nil User.try_to_login('example1', '11111')
641 end
642 end
629 test "#try_to_login using LDAP on the fly registration" do
630 AuthSourceLdap.find(1).update_attribute :onthefly_register, true
631
632 assert_difference('User.count') do
633 assert User.try_to_login('edavis', '123456')
643 634 end
644 635
645 context "on the fly registration" do
646 setup do
647 @auth_source = AuthSourceLdap.find(1)
648 @auth_source.update_attribute :onthefly_register, true
649 end
636 assert_no_difference('User.count') do
637 assert User.try_to_login('edavis', '123456')
638 end
650 639
651 context "with a successful authentication" do
652 should "create a new user account if it doesn't exist" do
653 assert_difference('User.count') do
654 user = User.try_to_login('edavis', '123456')
655 assert !user.admin?
656 end
657 end
658
659 should "retrieve existing user" do
660 user = User.try_to_login('edavis', '123456')
661 user.admin = true
662 user.save!
663
664 assert_no_difference('User.count') do
665 user = User.try_to_login('edavis', '123456')
666 assert user.admin?
667 end
668 end
669 end
640 assert_nil User.try_to_login('example1', '11111')
641 end
670 642
671 context "binding with user's account" do
672 setup do
673 @auth_source = AuthSourceLdap.find(1)
674 @auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
675 @auth_source.account_password = ''
676 @auth_source.save!
677 end
678
679 context "with a successful authentication" do
680 should "create a new user account if it doesn't exist" do
681 assert_difference('User.count') do
682 user = User.try_to_login('example1', '123456')
683 assert_kind_of User, user
684 end
685 end
686 end
687
688 context "with an unsuccessful authentication" do
689 should "return nil" do
690 assert_nil User.try_to_login('example1', '11111')
691 end
692 end
693 end
643 test "#try_to_login using LDAP on the fly registration and binding with user's account" do
644 auth_source = AuthSourceLdap.find(1)
645 auth_source.update_attribute :onthefly_register, true
646 auth_source = AuthSourceLdap.find(1)
647 auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
648 auth_source.account_password = ''
649 auth_source.save!
650
651 assert_difference('User.count') do
652 assert User.try_to_login('example1', '123456')
694 653 end
654
655 assert_no_difference('User.count') do
656 assert User.try_to_login('edavis', '123456')
657 end
658
659 assert_nil User.try_to_login('example1', '11111')
695 660 end
696 661
697 662 else
698 663 puts "Skipping LDAP tests."
699 664 end
700 665
701 666 def test_create_anonymous
702 667 AnonymousUser.delete_all
703 668 anon = User.anonymous
704 669 assert !anon.new_record?
705 670 assert_kind_of AnonymousUser, anon
706 671 end
707 672
708 673 def test_ensure_single_anonymous_user
709 674 AnonymousUser.delete_all
710 675 anon1 = User.anonymous
711 676 assert !anon1.new_record?
712 677 assert_kind_of AnonymousUser, anon1
713 678 anon2 = AnonymousUser.create(
714 679 :lastname => 'Anonymous', :firstname => '',
715 680 :mail => '', :login => '', :status => 0)
716 681 assert_equal 1, anon2.errors.count
717 682 end
718 683
719 684 def test_rss_key
720 685 assert_nil @jsmith.rss_token
721 686 key = @jsmith.rss_key
722 687 assert_equal 40, key.length
723 688
724 689 @jsmith.reload
725 690 assert_equal key, @jsmith.rss_key
726 691 end
727 692
728 693 def test_rss_key_should_not_be_generated_twice
729 694 assert_difference 'Token.count', 1 do
730 695 key1 = @jsmith.rss_key
731 696 key2 = @jsmith.rss_key
732 697 assert_equal key1, key2
733 698 end
734 699 end
735 700
736 701 def test_api_key_should_not_be_generated_twice
737 702 assert_difference 'Token.count', 1 do
738 703 key1 = @jsmith.api_key
739 704 key2 = @jsmith.api_key
740 705 assert_equal key1, key2
741 706 end
742 707 end
743 708
744 709 test "#api_key should generate a new one if the user doesn't have one" do
745 710 user = User.generate!(:api_token => nil)
746 711 assert_nil user.api_token
747 712
748 713 key = user.api_key
749 714 assert_equal 40, key.length
750 715 user.reload
751 716 assert_equal key, user.api_key
752 717 end
753 718
754 719 test "#api_key should return the existing api token value" do
755 720 user = User.generate!
756 721 token = Token.create!(:action => 'api')
757 722 user.api_token = token
758 723 assert user.save
759 724
760 725 assert_equal token.value, user.api_key
761 726 end
762 727
763 728 test "#find_by_api_key should return nil if no matching key is found" do
764 729 assert_nil User.find_by_api_key('zzzzzzzzz')
765 730 end
766 731
767 732 test "#find_by_api_key should return nil if the key is found for an inactive user" do
768 733 user = User.generate!
769 734 user.status = User::STATUS_LOCKED
770 735 token = Token.create!(:action => 'api')
771 736 user.api_token = token
772 737 user.save
773 738
774 739 assert_nil User.find_by_api_key(token.value)
775 740 end
776 741
777 742 test "#find_by_api_key should return the user if the key is found for an active user" do
778 743 user = User.generate!
779 744 token = Token.create!(:action => 'api')
780 745 user.api_token = token
781 746 user.save
782 747
783 748 assert_equal user, User.find_by_api_key(token.value)
784 749 end
785 750
786 751 def test_default_admin_account_changed_should_return_false_if_account_was_not_changed
787 752 user = User.find_by_login("admin")
788 753 user.password = "admin"
789 754 assert user.save(:validate => false)
790 755
791 756 assert_equal false, User.default_admin_account_changed?
792 757 end
793 758
794 759 def test_default_admin_account_changed_should_return_true_if_password_was_changed
795 760 user = User.find_by_login("admin")
796 761 user.password = "newpassword"
797 762 user.save!
798 763
799 764 assert_equal true, User.default_admin_account_changed?
800 765 end
801 766
802 767 def test_default_admin_account_changed_should_return_true_if_account_is_disabled
803 768 user = User.find_by_login("admin")
804 769 user.password = "admin"
805 770 user.status = User::STATUS_LOCKED
806 771 assert user.save(:validate => false)
807 772
808 773 assert_equal true, User.default_admin_account_changed?
809 774 end
810 775
811 776 def test_default_admin_account_changed_should_return_true_if_account_does_not_exist
812 777 user = User.find_by_login("admin")
813 778 user.destroy
814 779
815 780 assert_equal true, User.default_admin_account_changed?
816 781 end
817 782
818 783 def test_membership_with_project_should_return_membership
819 784 project = Project.find(1)
820 785
821 786 membership = @jsmith.membership(project)
822 787 assert_kind_of Member, membership
823 788 assert_equal @jsmith, membership.user
824 789 assert_equal project, membership.project
825 790 end
826 791
827 792 def test_membership_with_project_id_should_return_membership
828 793 project = Project.find(1)
829 794
830 795 membership = @jsmith.membership(1)
831 796 assert_kind_of Member, membership
832 797 assert_equal @jsmith, membership.user
833 798 assert_equal project, membership.project
834 799 end
835 800
836 801 def test_membership_for_non_member_should_return_nil
837 802 project = Project.find(1)
838 803
839 804 user = User.generate!
840 805 membership = user.membership(1)
841 806 assert_nil membership
842 807 end
843 808
844 809 def test_roles_for_project_with_member_on_public_project_should_return_roles_and_non_member
845 810 roles = @jsmith.roles_for_project(Project.find(1))
846 811 assert_kind_of Role, roles.first
847 812 assert_equal ["Manager"], roles.map(&:name)
848 813 end
849 814
850 815 def test_roles_for_project_with_member_on_private_project_should_return_roles
851 816 Project.find(1).update_attribute :is_public, false
852 817
853 818 roles = @jsmith.roles_for_project(Project.find(1))
854 819 assert_kind_of Role, roles.first
855 820 assert_equal ["Manager"], roles.map(&:name)
856 821 end
857 822
858 823 def test_roles_for_project_with_non_member_with_public_project_should_return_non_member
859 824 set_language_if_valid 'en'
860 825 roles = User.find(8).roles_for_project(Project.find(1))
861 826 assert_equal ["Non member"], roles.map(&:name)
862 827 end
863 828
864 829 def test_roles_for_project_with_non_member_with_public_project_and_override_should_return_override_roles
865 830 project = Project.find(1)
866 831 Member.create!(:project => project, :principal => Group.non_member, :role_ids => [1, 2])
867 832 roles = User.find(8).roles_for_project(project)
868 833 assert_equal ["Developer", "Manager"], roles.map(&:name).sort
869 834 end
870 835
871 836 def test_roles_for_project_with_non_member_with_private_project_should_return_no_roles
872 837 Project.find(1).update_attribute :is_public, false
873 838
874 839 roles = User.find(8).roles_for_project(Project.find(1))
875 840 assert_equal [], roles.map(&:name)
876 841 end
877 842
878 843 def test_roles_for_project_with_non_member_with_private_project_and_override_should_return_no_roles
879 844 project = Project.find(1)
880 845 project.update_attribute :is_public, false
881 846 Member.create!(:project => project, :principal => Group.non_member, :role_ids => [1, 2])
882 847 roles = User.find(8).roles_for_project(project)
883 848 assert_equal [], roles.map(&:name).sort
884 849 end
885 850
886 851 def test_roles_for_project_with_anonymous_with_public_project_should_return_anonymous
887 852 set_language_if_valid 'en'
888 853 roles = User.anonymous.roles_for_project(Project.find(1))
889 854 assert_equal ["Anonymous"], roles.map(&:name)
890 855 end
891 856
892 857 def test_roles_for_project_with_anonymous_with_public_project_and_override_should_return_override_roles
893 858 project = Project.find(1)
894 859 Member.create!(:project => project, :principal => Group.anonymous, :role_ids => [1, 2])
895 860 roles = User.anonymous.roles_for_project(project)
896 861 assert_equal ["Developer", "Manager"], roles.map(&:name).sort
897 862 end
898 863
899 864 def test_roles_for_project_with_anonymous_with_private_project_should_return_no_roles
900 865 Project.find(1).update_attribute :is_public, false
901 866
902 867 roles = User.anonymous.roles_for_project(Project.find(1))
903 868 assert_equal [], roles.map(&:name)
904 869 end
905 870
906 871 def test_roles_for_project_with_anonymous_with_private_project_and_override_should_return_no_roles
907 872 project = Project.find(1)
908 873 project.update_attribute :is_public, false
909 874 Member.create!(:project => project, :principal => Group.anonymous, :role_ids => [1, 2])
910 875 roles = User.anonymous.roles_for_project(project)
911 876 assert_equal [], roles.map(&:name).sort
912 877 end
913 878
914 879 def test_projects_by_role_for_user_with_role
915 880 user = User.find(2)
916 881 assert_kind_of Hash, user.projects_by_role
917 882 assert_equal 2, user.projects_by_role.size
918 883 assert_equal [1,5], user.projects_by_role[Role.find(1)].collect(&:id).sort
919 884 assert_equal [2], user.projects_by_role[Role.find(2)].collect(&:id).sort
920 885 end
921 886
922 887 def test_accessing_projects_by_role_with_no_projects_should_return_an_empty_array
923 888 user = User.find(2)
924 889 assert_equal [], user.projects_by_role[Role.find(3)]
925 890 # should not update the hash
926 891 assert_nil user.projects_by_role.values.detect(&:blank?)
927 892 end
928 893
929 894 def test_projects_by_role_for_user_with_no_role
930 895 user = User.generate!
931 896 assert_equal({}, user.projects_by_role)
932 897 end
933 898
934 899 def test_projects_by_role_for_anonymous
935 900 assert_equal({}, User.anonymous.projects_by_role)
936 901 end
937 902
938 903 def test_valid_notification_options
939 904 # without memberships
940 905 assert_equal 5, User.find(7).valid_notification_options.size
941 906 # with memberships
942 907 assert_equal 6, User.find(2).valid_notification_options.size
943 908 end
944 909
945 910 def test_valid_notification_options_class_method
946 911 assert_equal 5, User.valid_notification_options.size
947 912 assert_equal 5, User.valid_notification_options(User.find(7)).size
948 913 assert_equal 6, User.valid_notification_options(User.find(2)).size
949 914 end
950 915
951 916 def test_notified_project_ids_setter_should_coerce_to_unique_integer_array
952 917 @jsmith.notified_project_ids = ["1", "123", "2u", "wrong", "12", 6, 12, -35, ""]
953 918 assert_equal [1, 123, 2, 12, 6], @jsmith.notified_projects_ids
954 919 end
955 920
956 921 def test_mail_notification_all
957 922 @jsmith.mail_notification = 'all'
958 923 @jsmith.notified_project_ids = []
959 924 @jsmith.save
960 925 @jsmith.reload
961 926 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
962 927 end
963 928
964 929 def test_mail_notification_selected
965 930 @jsmith.mail_notification = 'selected'
966 931 @jsmith.notified_project_ids = [1]
967 932 @jsmith.save
968 933 @jsmith.reload
969 934 assert Project.find(1).recipients.include?(@jsmith.mail)
970 935 end
971 936
972 937 def test_mail_notification_only_my_events
973 938 @jsmith.mail_notification = 'only_my_events'
974 939 @jsmith.notified_project_ids = []
975 940 @jsmith.save
976 941 @jsmith.reload
977 942 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
978 943 end
979 944
980 945 def test_comments_sorting_preference
981 946 assert !@jsmith.wants_comments_in_reverse_order?
982 947 @jsmith.pref.comments_sorting = 'asc'
983 948 assert !@jsmith.wants_comments_in_reverse_order?
984 949 @jsmith.pref.comments_sorting = 'desc'
985 950 assert @jsmith.wants_comments_in_reverse_order?
986 951 end
987 952
988 953 def test_find_by_mail_should_be_case_insensitive
989 954 u = User.find_by_mail('JSmith@somenet.foo')
990 955 assert_not_nil u
991 956 assert_equal 'jsmith@somenet.foo', u.mail
992 957 end
993 958
994 959 def test_random_password
995 960 u = User.new
996 961 u.random_password
997 962 assert !u.password.blank?
998 963 assert !u.password_confirmation.blank?
999 964 end
1000 965
1001 966 test "#change_password_allowed? should be allowed if no auth source is set" do
1002 967 user = User.generate!
1003 968 assert user.change_password_allowed?
1004 969 end
1005 970
1006 971 test "#change_password_allowed? should delegate to the auth source" do
1007 972 user = User.generate!
1008 973
1009 974 allowed_auth_source = AuthSource.generate!
1010 975 def allowed_auth_source.allow_password_changes?; true; end
1011 976
1012 977 denied_auth_source = AuthSource.generate!
1013 978 def denied_auth_source.allow_password_changes?; false; end
1014 979
1015 980 assert user.change_password_allowed?
1016 981
1017 982 user.auth_source = allowed_auth_source
1018 983 assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
1019 984
1020 985 user.auth_source = denied_auth_source
1021 986 assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
1022 987 end
1023 988
1024 989 def test_own_account_deletable_should_be_true_with_unsubscrive_enabled
1025 990 with_settings :unsubscribe => '1' do
1026 991 assert_equal true, User.find(2).own_account_deletable?
1027 992 end
1028 993 end
1029 994
1030 995 def test_own_account_deletable_should_be_false_with_unsubscrive_disabled
1031 996 with_settings :unsubscribe => '0' do
1032 997 assert_equal false, User.find(2).own_account_deletable?
1033 998 end
1034 999 end
1035 1000
1036 1001 def test_own_account_deletable_should_be_false_for_a_single_admin
1037 1002 User.delete_all(["admin = ? AND id <> ?", true, 1])
1038 1003
1039 1004 with_settings :unsubscribe => '1' do
1040 1005 assert_equal false, User.find(1).own_account_deletable?
1041 1006 end
1042 1007 end
1043 1008
1044 1009 def test_own_account_deletable_should_be_true_for_an_admin_if_other_admin_exists
1045 1010 User.generate! do |user|
1046 1011 user.admin = true
1047 1012 end
1048 1013
1049 1014 with_settings :unsubscribe => '1' do
1050 1015 assert_equal true, User.find(1).own_account_deletable?
1051 1016 end
1052 1017 end
1053 1018
1054 1019 context "#allowed_to?" do
1055 1020 context "with a unique project" do
1056 1021 should "return false if project is archived" do
1057 1022 project = Project.find(1)
1058 1023 Project.any_instance.stubs(:status).returns(Project::STATUS_ARCHIVED)
1059 1024 assert_equal false, @admin.allowed_to?(:view_issues, Project.find(1))
1060 1025 end
1061 1026
1062 1027 should "return false for write action if project is closed" do
1063 1028 project = Project.find(1)
1064 1029 Project.any_instance.stubs(:status).returns(Project::STATUS_CLOSED)
1065 1030 assert_equal false, @admin.allowed_to?(:edit_project, Project.find(1))
1066 1031 end
1067 1032
1068 1033 should "return true for read action if project is closed" do
1069 1034 project = Project.find(1)
1070 1035 Project.any_instance.stubs(:status).returns(Project::STATUS_CLOSED)
1071 1036 assert_equal true, @admin.allowed_to?(:view_project, Project.find(1))
1072 1037 end
1073 1038
1074 1039 should "return false if related module is disabled" do
1075 1040 project = Project.find(1)
1076 1041 project.enabled_module_names = ["issue_tracking"]
1077 1042 assert_equal true, @admin.allowed_to?(:add_issues, project)
1078 1043 assert_equal false, @admin.allowed_to?(:view_wiki_pages, project)
1079 1044 end
1080 1045
1081 1046 should "authorize nearly everything for admin users" do
1082 1047 project = Project.find(1)
1083 1048 assert ! @admin.member_of?(project)
1084 1049 %w(edit_issues delete_issues manage_news add_documents manage_wiki).each do |p|
1085 1050 assert_equal true, @admin.allowed_to?(p.to_sym, project)
1086 1051 end
1087 1052 end
1088 1053
1089 1054 should "authorize normal users depending on their roles" do
1090 1055 project = Project.find(1)
1091 1056 assert_equal true, @jsmith.allowed_to?(:delete_messages, project) #Manager
1092 1057 assert_equal false, @dlopper.allowed_to?(:delete_messages, project) #Developper
1093 1058 end
1094 1059 end
1095 1060
1096 1061 context "with multiple projects" do
1097 1062 should "return false if array is empty" do
1098 1063 assert_equal false, @admin.allowed_to?(:view_project, [])
1099 1064 end
1100 1065
1101 1066 should "return true only if user has permission on all these projects" do
1102 1067 assert_equal true, @admin.allowed_to?(:view_project, Project.all.to_a)
1103 1068 assert_equal false, @dlopper.allowed_to?(:view_project, Project.all.to_a) #cannot see Project(2)
1104 1069 assert_equal true, @jsmith.allowed_to?(:edit_issues, @jsmith.projects.to_a) #Manager or Developer everywhere
1105 1070 assert_equal false, @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects.to_a) #Dev cannot delete_issue_watchers
1106 1071 end
1107 1072
1108 1073 should "behave correctly with arrays of 1 project" do
1109 1074 assert_equal false, User.anonymous.allowed_to?(:delete_issues, [Project.first])
1110 1075 end
1111 1076 end
1112 1077
1113 1078 context "with options[:global]" do
1114 1079 should "authorize if user has at least one role that has this permission" do
1115 1080 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
1116 1081 @anonymous = User.find(6)
1117 1082 assert_equal true, @jsmith.allowed_to?(:delete_issue_watchers, nil, :global => true)
1118 1083 assert_equal false, @dlopper2.allowed_to?(:delete_issue_watchers, nil, :global => true)
1119 1084 assert_equal true, @dlopper2.allowed_to?(:add_issues, nil, :global => true)
1120 1085 assert_equal false, @anonymous.allowed_to?(:add_issues, nil, :global => true)
1121 1086 assert_equal true, @anonymous.allowed_to?(:view_issues, nil, :global => true)
1122 1087 end
1123 1088 end
1124 1089 end
1125 1090
1126 1091 # this is just a proxy method, the test only calls it to ensure it doesn't break trivially
1127 1092 context "#allowed_to_globally?" do
1128 1093 should "proxy to #allowed_to? and reflect global permissions" do
1129 1094 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
1130 1095 @anonymous = User.find(6)
1131 1096 assert_equal true, @jsmith.allowed_to_globally?(:delete_issue_watchers)
1132 1097 assert_equal false, @dlopper2.allowed_to_globally?(:delete_issue_watchers)
1133 1098 assert_equal true, @dlopper2.allowed_to_globally?(:add_issues)
1134 1099 assert_equal false, @anonymous.allowed_to_globally?(:add_issues)
1135 1100 assert_equal true, @anonymous.allowed_to_globally?(:view_issues)
1136 1101 end
1137 1102 end
1138 1103
1139 1104 context "User#notify_about?" do
1140 1105 context "Issues" do
1141 1106 setup do
1142 1107 @project = Project.find(1)
1143 1108 @author = User.generate!
1144 1109 @assignee = User.generate!
1145 1110 @issue = Issue.generate!(:project => @project, :assigned_to => @assignee, :author => @author)
1146 1111 end
1147 1112
1148 1113 should "be true for a user with :all" do
1149 1114 @author.update_attribute(:mail_notification, 'all')
1150 1115 assert @author.notify_about?(@issue)
1151 1116 end
1152 1117
1153 1118 should "be false for a user with :none" do
1154 1119 @author.update_attribute(:mail_notification, 'none')
1155 1120 assert ! @author.notify_about?(@issue)
1156 1121 end
1157 1122
1158 1123 should "be false for a user with :only_my_events and isn't an author, creator, or assignee" do
1159 1124 @user = User.generate!(:mail_notification => 'only_my_events')
1160 1125 Member.create!(:user => @user, :project => @project, :role_ids => [1])
1161 1126 assert ! @user.notify_about?(@issue)
1162 1127 end
1163 1128
1164 1129 should "be true for a user with :only_my_events and is the author" do
1165 1130 @author.update_attribute(:mail_notification, 'only_my_events')
1166 1131 assert @author.notify_about?(@issue)
1167 1132 end
1168 1133
1169 1134 should "be true for a user with :only_my_events and is the assignee" do
1170 1135 @assignee.update_attribute(:mail_notification, 'only_my_events')
1171 1136 assert @assignee.notify_about?(@issue)
1172 1137 end
1173 1138
1174 1139 should "be true for a user with :only_assigned and is the assignee" do
1175 1140 @assignee.update_attribute(:mail_notification, 'only_assigned')
1176 1141 assert @assignee.notify_about?(@issue)
1177 1142 end
1178 1143
1179 1144 should "be false for a user with :only_assigned and is not the assignee" do
1180 1145 @author.update_attribute(:mail_notification, 'only_assigned')
1181 1146 assert ! @author.notify_about?(@issue)
1182 1147 end
1183 1148
1184 1149 should "be true for a user with :only_owner and is the author" do
1185 1150 @author.update_attribute(:mail_notification, 'only_owner')
1186 1151 assert @author.notify_about?(@issue)
1187 1152 end
1188 1153
1189 1154 should "be false for a user with :only_owner and is not the author" do
1190 1155 @assignee.update_attribute(:mail_notification, 'only_owner')
1191 1156 assert ! @assignee.notify_about?(@issue)
1192 1157 end
1193 1158
1194 1159 should "be true for a user with :selected and is the author" do
1195 1160 @author.update_attribute(:mail_notification, 'selected')
1196 1161 assert @author.notify_about?(@issue)
1197 1162 end
1198 1163
1199 1164 should "be true for a user with :selected and is the assignee" do
1200 1165 @assignee.update_attribute(:mail_notification, 'selected')
1201 1166 assert @assignee.notify_about?(@issue)
1202 1167 end
1203 1168
1204 1169 should "be false for a user with :selected and is not the author or assignee" do
1205 1170 @user = User.generate!(:mail_notification => 'selected')
1206 1171 Member.create!(:user => @user, :project => @project, :role_ids => [1])
1207 1172 assert ! @user.notify_about?(@issue)
1208 1173 end
1209 1174 end
1210 1175 end
1211 1176
1212 1177 def test_notify_about_news
1213 1178 user = User.generate!
1214 1179 news = News.new
1215 1180
1216 1181 User::MAIL_NOTIFICATION_OPTIONS.map(&:first).each do |option|
1217 1182 user.mail_notification = option
1218 1183 assert_equal (option != 'none'), user.notify_about?(news)
1219 1184 end
1220 1185 end
1221 1186
1222 1187 def test_salt_unsalted_passwords
1223 1188 # Restore a user with an unsalted password
1224 1189 user = User.find(1)
1225 1190 user.salt = nil
1226 1191 user.hashed_password = User.hash_password("unsalted")
1227 1192 user.save!
1228 1193
1229 1194 User.salt_unsalted_passwords!
1230 1195
1231 1196 user.reload
1232 1197 # Salt added
1233 1198 assert !user.salt.blank?
1234 1199 # Password still valid
1235 1200 assert user.check_password?("unsalted")
1236 1201 assert_equal user, User.try_to_login(user.login, "unsalted")
1237 1202 end
1238 1203
1239 1204 if Object.const_defined?(:OpenID)
1240 1205 def test_setting_identity_url
1241 1206 normalized_open_id_url = 'http://example.com/'
1242 1207 u = User.new( :identity_url => 'http://example.com/' )
1243 1208 assert_equal normalized_open_id_url, u.identity_url
1244 1209 end
1245 1210
1246 1211 def test_setting_identity_url_without_trailing_slash
1247 1212 normalized_open_id_url = 'http://example.com/'
1248 1213 u = User.new( :identity_url => 'http://example.com' )
1249 1214 assert_equal normalized_open_id_url, u.identity_url
1250 1215 end
1251 1216
1252 1217 def test_setting_identity_url_without_protocol
1253 1218 normalized_open_id_url = 'http://example.com/'
1254 1219 u = User.new( :identity_url => 'example.com' )
1255 1220 assert_equal normalized_open_id_url, u.identity_url
1256 1221 end
1257 1222
1258 1223 def test_setting_blank_identity_url
1259 1224 u = User.new( :identity_url => 'example.com' )
1260 1225 u.identity_url = ''
1261 1226 assert u.identity_url.blank?
1262 1227 end
1263 1228
1264 1229 def test_setting_invalid_identity_url
1265 1230 u = User.new( :identity_url => 'this is not an openid url' )
1266 1231 assert u.identity_url.blank?
1267 1232 end
1268 1233 else
1269 1234 puts "Skipping openid tests."
1270 1235 end
1271 1236 end
General Comments 0
You need to be logged in to leave comments. Login now