##// END OF EJS Templates
Fixed that activities option tags on the time entry bulk edit form are escaped....
Jean-Philippe Lang -
r9460:ee8dcab9db0a
parent child
Show More
@@ -1,50 +1,50
1 1 <h2><%= l(:label_bulk_edit_selected_time_entries) %></h2>
2 2
3 3 <ul>
4 4 <%= @time_entries.collect {|i| content_tag('li',
5 5 link_to(h("#{i.spent_on.strftime("%Y-%m-%d")} - #{i.project}: #{l(:label_f_hour_plural, :value => i.hours)}"),
6 6 { :action => 'edit', :id => i })
7 7 )}.join("\n").html_safe %>
8 8 </ul>
9 9
10 10 <%= form_tag(:action => 'bulk_update') do %>
11 11 <%= @time_entries.collect {|i| hidden_field_tag('ids[]', i.id)}.join.html_safe %>
12 12 <div class="box tabular">
13 13 <div>
14 14 <p>
15 15 <label><%= l(:field_issue) %></label>
16 16 <%= text_field :time_entry, :issue_id, :size => 6 %>
17 17 </p>
18 18
19 19 <p>
20 20 <label><%= l(:field_spent_on) %></label>
21 21 <%= text_field :time_entry, :spent_on, :size => 10 %><%= calendar_for('time_entry_spent_on') %>
22 22 </p>
23 23
24 24 <p>
25 25 <label><%= l(:field_hours) %></label>
26 26 <%= text_field :time_entry, :hours, :size => 6 %>
27 27 </p>
28 28
29 29 <% if @available_activities.any? %>
30 30 <p>
31 31 <label><%= l(:field_activity) %></label>
32 <%= select_tag('time_entry[activity_id]', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@available_activities, :id, :name)) %>
32 <%= select_tag('time_entry[activity_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@available_activities, :id, :name)) %>
33 33 </p>
34 34 <% end %>
35 35
36 36 <p>
37 37 <label><%= l(:field_comments) %></label>
38 38 <%= text_field(:time_entry, :comments, :size => 100) %>
39 39 </p>
40 40
41 41 <% @custom_fields.each do |custom_field| %>
42 42 <p><label><%= h(custom_field.name) %></label> <%= custom_field_tag_for_bulk_edit('time_entry', custom_field, @projects) %></p>
43 43 <% end %>
44 44
45 45 <%= call_hook(:view_time_entries_bulk_edit_details_bottom, { :time_entries => @time_entries }) %>
46 46 </div>
47 47 </div>
48 48
49 49 <p><%= submit_tag l(:button_submit) %></p>
50 50 <% end %>
@@ -1,742 +1,748
1 1 # -*- coding: utf-8 -*-
2 2 # Redmine - project management software
3 3 # Copyright (C) 2006-2012 Jean-Philippe Lang
4 4 #
5 5 # This program is free software; you can redistribute it and/or
6 6 # modify it under the terms of the GNU General Public License
7 7 # as published by the Free Software Foundation; either version 2
8 8 # of the License, or (at your option) any later version.
9 9 #
10 10 # This program is distributed in the hope that it will be useful,
11 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 # GNU General Public License for more details.
14 14 #
15 15 # You should have received a copy of the GNU General Public License
16 16 # along with this program; if not, write to the Free Software
17 17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 18
19 19 require File.expand_path('../../test_helper', __FILE__)
20 20 require 'timelog_controller'
21 21
22 22 # Re-raise errors caught by the controller.
23 23 class TimelogController; def rescue_action(e) raise e end; end
24 24
25 25 class TimelogControllerTest < ActionController::TestCase
26 26 fixtures :projects, :enabled_modules, :roles, :members,
27 27 :member_roles, :issues, :time_entries, :users,
28 28 :trackers, :enumerations, :issue_statuses,
29 29 :custom_fields, :custom_values
30 30
31 31 include Redmine::I18n
32 32
33 33 def setup
34 34 @controller = TimelogController.new
35 35 @request = ActionController::TestRequest.new
36 36 @response = ActionController::TestResponse.new
37 37 end
38 38
39 39 def test_get_new
40 40 @request.session[:user_id] = 3
41 41 get :new, :project_id => 1
42 42 assert_response :success
43 43 assert_template 'new'
44 44 # Default activity selected
45 45 assert_tag :tag => 'option', :attributes => { :selected => 'selected' },
46 46 :content => 'Development'
47 47 end
48 48
49 49 def test_get_new_should_only_show_active_time_entry_activities
50 50 @request.session[:user_id] = 3
51 51 get :new, :project_id => 1
52 52 assert_response :success
53 53 assert_template 'new'
54 54 assert_no_tag 'select', :attributes => {:name => 'time_entry[project_id]'}
55 55 assert_no_tag 'option', :content => 'Inactive Activity'
56 56 end
57 57
58 58 def test_new_without_project
59 59 @request.session[:user_id] = 3
60 60 get :new
61 61 assert_response :success
62 62 assert_template 'new'
63 63 assert_tag 'select', :attributes => {:name => 'time_entry[project_id]'}
64 64 end
65 65
66 66 def test_new_without_project_should_deny_without_permission
67 67 Role.all.each {|role| role.remove_permission! :log_time}
68 68 @request.session[:user_id] = 3
69 69
70 70 get :new
71 71 assert_response 403
72 72 end
73 73
74 74 def test_get_edit_existing_time
75 75 @request.session[:user_id] = 2
76 76 get :edit, :id => 2, :project_id => nil
77 77 assert_response :success
78 78 assert_template 'edit'
79 79 # Default activity selected
80 80 assert_tag :tag => 'form', :attributes => { :action => '/projects/ecookbook/time_entries/2' }
81 81 end
82 82
83 83 def test_get_edit_with_an_existing_time_entry_with_inactive_activity
84 84 te = TimeEntry.find(1)
85 85 te.activity = TimeEntryActivity.find_by_name("Inactive Activity")
86 86 te.save!
87 87
88 88 @request.session[:user_id] = 1
89 89 get :edit, :project_id => 1, :id => 1
90 90 assert_response :success
91 91 assert_template 'edit'
92 92 # Blank option since nothing is pre-selected
93 93 assert_tag :tag => 'option', :content => '--- Please select ---'
94 94 end
95 95
96 96 def test_post_create
97 97 # TODO: should POST to issues’ time log instead of project. change form
98 98 # and routing
99 99 @request.session[:user_id] = 3
100 100 post :create, :project_id => 1,
101 101 :time_entry => {:comments => 'Some work on TimelogControllerTest',
102 102 # Not the default activity
103 103 :activity_id => '11',
104 104 :spent_on => '2008-03-14',
105 105 :issue_id => '1',
106 106 :hours => '7.3'}
107 107 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
108 108
109 109 i = Issue.find(1)
110 110 t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
111 111 assert_not_nil t
112 112 assert_equal 11, t.activity_id
113 113 assert_equal 7.3, t.hours
114 114 assert_equal 3, t.user_id
115 115 assert_equal i, t.issue
116 116 assert_equal i.project, t.project
117 117 end
118 118
119 119 def test_post_create_with_blank_issue
120 120 # TODO: should POST to issues’ time log instead of project. change form
121 121 # and routing
122 122 @request.session[:user_id] = 3
123 123 post :create, :project_id => 1,
124 124 :time_entry => {:comments => 'Some work on TimelogControllerTest',
125 125 # Not the default activity
126 126 :activity_id => '11',
127 127 :issue_id => '',
128 128 :spent_on => '2008-03-14',
129 129 :hours => '7.3'}
130 130 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
131 131
132 132 t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
133 133 assert_not_nil t
134 134 assert_equal 11, t.activity_id
135 135 assert_equal 7.3, t.hours
136 136 assert_equal 3, t.user_id
137 137 end
138 138
139 139 def test_create_and_continue
140 140 @request.session[:user_id] = 2
141 141 post :create, :project_id => 1,
142 142 :time_entry => {:activity_id => '11',
143 143 :issue_id => '',
144 144 :spent_on => '2008-03-14',
145 145 :hours => '7.3'},
146 146 :continue => '1'
147 147 assert_redirected_to '/projects/ecookbook/time_entries/new'
148 148 end
149 149
150 150 def test_create_and_continue_with_issue_id
151 151 @request.session[:user_id] = 2
152 152 post :create, :project_id => 1,
153 153 :time_entry => {:activity_id => '11',
154 154 :issue_id => '1',
155 155 :spent_on => '2008-03-14',
156 156 :hours => '7.3'},
157 157 :continue => '1'
158 158 assert_redirected_to '/projects/ecookbook/issues/1/time_entries/new'
159 159 end
160 160
161 161 def test_create_and_continue_without_project
162 162 @request.session[:user_id] = 2
163 163 post :create, :time_entry => {:project_id => '1',
164 164 :activity_id => '11',
165 165 :issue_id => '',
166 166 :spent_on => '2008-03-14',
167 167 :hours => '7.3'},
168 168 :continue => '1'
169 169
170 170 assert_redirected_to '/time_entries/new'
171 171 end
172 172
173 173 def test_create_without_log_time_permission_should_be_denied
174 174 @request.session[:user_id] = 2
175 175 Role.find_by_name('Manager').remove_permission! :log_time
176 176 post :create, :project_id => 1,
177 177 :time_entry => {:activity_id => '11',
178 178 :issue_id => '',
179 179 :spent_on => '2008-03-14',
180 180 :hours => '7.3'}
181 181
182 182 assert_response 403
183 183 end
184 184
185 185 def test_create_with_failure
186 186 @request.session[:user_id] = 2
187 187 post :create, :project_id => 1,
188 188 :time_entry => {:activity_id => '',
189 189 :issue_id => '',
190 190 :spent_on => '2008-03-14',
191 191 :hours => '7.3'}
192 192
193 193 assert_response :success
194 194 assert_template 'new'
195 195 end
196 196
197 197 def test_create_without_project
198 198 @request.session[:user_id] = 2
199 199 assert_difference 'TimeEntry.count' do
200 200 post :create, :time_entry => {:project_id => '1',
201 201 :activity_id => '11',
202 202 :issue_id => '',
203 203 :spent_on => '2008-03-14',
204 204 :hours => '7.3'}
205 205 end
206 206
207 207 assert_redirected_to '/projects/ecookbook/time_entries'
208 208 time_entry = TimeEntry.first(:order => 'id DESC')
209 209 assert_equal 1, time_entry.project_id
210 210 end
211 211
212 212 def test_create_without_project_should_fail_with_issue_not_inside_project
213 213 @request.session[:user_id] = 2
214 214 assert_no_difference 'TimeEntry.count' do
215 215 post :create, :time_entry => {:project_id => '1',
216 216 :activity_id => '11',
217 217 :issue_id => '5',
218 218 :spent_on => '2008-03-14',
219 219 :hours => '7.3'}
220 220 end
221 221
222 222 assert_response :success
223 223 assert assigns(:time_entry).errors[:issue_id].present?
224 224 end
225 225
226 226 def test_create_without_project_should_deny_without_permission
227 227 @request.session[:user_id] = 2
228 228 Project.find(3).disable_module!(:time_tracking)
229 229
230 230 assert_no_difference 'TimeEntry.count' do
231 231 post :create, :time_entry => {:project_id => '3',
232 232 :activity_id => '11',
233 233 :issue_id => '',
234 234 :spent_on => '2008-03-14',
235 235 :hours => '7.3'}
236 236 end
237 237
238 238 assert_response 403
239 239 end
240 240
241 241 def test_create_without_project_with_failure
242 242 @request.session[:user_id] = 2
243 243 assert_no_difference 'TimeEntry.count' do
244 244 post :create, :time_entry => {:project_id => '1',
245 245 :activity_id => '11',
246 246 :issue_id => '',
247 247 :spent_on => '2008-03-14',
248 248 :hours => ''}
249 249 end
250 250
251 251 assert_response :success
252 252 assert_tag 'select', :attributes => {:name => 'time_entry[project_id]'},
253 253 :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}}
254 254 end
255 255
256 256 def test_update
257 257 entry = TimeEntry.find(1)
258 258 assert_equal 1, entry.issue_id
259 259 assert_equal 2, entry.user_id
260 260
261 261 @request.session[:user_id] = 1
262 262 put :update, :id => 1,
263 263 :time_entry => {:issue_id => '2',
264 264 :hours => '8'}
265 265 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
266 266 entry.reload
267 267
268 268 assert_equal 8, entry.hours
269 269 assert_equal 2, entry.issue_id
270 270 assert_equal 2, entry.user_id
271 271 end
272 272
273 273 def test_get_bulk_edit
274 274 @request.session[:user_id] = 2
275 275 get :bulk_edit, :ids => [1, 2]
276 276 assert_response :success
277 277 assert_template 'bulk_edit'
278 278
279 279 # System wide custom field
280 280 assert_tag :select, :attributes => {:name => 'time_entry[custom_field_values][10]'}
281
282 # Activities
283 assert_select 'select[name=?]', 'time_entry[activity_id]' do
284 assert_select 'option[value=]', :text => '(No change)'
285 assert_select 'option[value=9]', :text => 'Design'
286 end
281 287 end
282 288
283 289 def test_get_bulk_edit_on_different_projects
284 290 @request.session[:user_id] = 2
285 291 get :bulk_edit, :ids => [1, 2, 6]
286 292 assert_response :success
287 293 assert_template 'bulk_edit'
288 294 end
289 295
290 296 def test_bulk_update
291 297 @request.session[:user_id] = 2
292 298 # update time entry activity
293 299 post :bulk_update, :ids => [1, 2], :time_entry => { :activity_id => 9}
294 300
295 301 assert_response 302
296 302 # check that the issues were updated
297 303 assert_equal [9, 9], TimeEntry.find_all_by_id([1, 2]).collect {|i| i.activity_id}
298 304 end
299 305
300 306 def test_bulk_update_with_failure
301 307 @request.session[:user_id] = 2
302 308 post :bulk_update, :ids => [1, 2], :time_entry => { :hours => 'A'}
303 309
304 310 assert_response 302
305 311 assert_match /Failed to save 2 time entrie/, flash[:error]
306 312 end
307 313
308 314 def test_bulk_update_on_different_projects
309 315 @request.session[:user_id] = 2
310 316 # makes user a manager on the other project
311 317 Member.create!(:user_id => 2, :project_id => 3, :role_ids => [1])
312 318
313 319 # update time entry activity
314 320 post :bulk_update, :ids => [1, 2, 4], :time_entry => { :activity_id => 9 }
315 321
316 322 assert_response 302
317 323 # check that the issues were updated
318 324 assert_equal [9, 9, 9], TimeEntry.find_all_by_id([1, 2, 4]).collect {|i| i.activity_id}
319 325 end
320 326
321 327 def test_bulk_update_on_different_projects_without_rights
322 328 @request.session[:user_id] = 3
323 329 user = User.find(3)
324 330 action = { :controller => "timelog", :action => "bulk_update" }
325 331 assert user.allowed_to?(action, TimeEntry.find(1).project)
326 332 assert ! user.allowed_to?(action, TimeEntry.find(5).project)
327 333 post :bulk_update, :ids => [1, 5], :time_entry => { :activity_id => 9 }
328 334 assert_response 403
329 335 end
330 336
331 337 def test_bulk_update_custom_field
332 338 @request.session[:user_id] = 2
333 339 post :bulk_update, :ids => [1, 2], :time_entry => { :custom_field_values => {'10' => '0'} }
334 340
335 341 assert_response 302
336 342 assert_equal ["0", "0"], TimeEntry.find_all_by_id([1, 2]).collect {|i| i.custom_value_for(10).value}
337 343 end
338 344
339 345 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
340 346 @request.session[:user_id] = 2
341 347 post :bulk_update, :ids => [1,2], :back_url => '/time_entries'
342 348
343 349 assert_response :redirect
344 350 assert_redirected_to '/time_entries'
345 351 end
346 352
347 353 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
348 354 @request.session[:user_id] = 2
349 355 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
350 356
351 357 assert_response :redirect
352 358 assert_redirected_to :controller => 'timelog', :action => 'index', :project_id => Project.find(1).identifier
353 359 end
354 360
355 361 def test_post_bulk_update_without_edit_permission_should_be_denied
356 362 @request.session[:user_id] = 2
357 363 Role.find_by_name('Manager').remove_permission! :edit_time_entries
358 364 post :bulk_update, :ids => [1,2]
359 365
360 366 assert_response 403
361 367 end
362 368
363 369 def test_destroy
364 370 @request.session[:user_id] = 2
365 371 delete :destroy, :id => 1
366 372 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
367 373 assert_equal I18n.t(:notice_successful_delete), flash[:notice]
368 374 assert_nil TimeEntry.find_by_id(1)
369 375 end
370 376
371 377 def test_destroy_should_fail
372 378 # simulate that this fails (e.g. due to a plugin), see #5700
373 379 TimeEntry.any_instance.expects(:destroy).returns(false)
374 380
375 381 @request.session[:user_id] = 2
376 382 delete :destroy, :id => 1
377 383 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
378 384 assert_equal I18n.t(:notice_unable_delete_time_entry), flash[:error]
379 385 assert_not_nil TimeEntry.find_by_id(1)
380 386 end
381 387
382 388 def test_index_all_projects
383 389 get :index
384 390 assert_response :success
385 391 assert_template 'index'
386 392 assert_not_nil assigns(:total_hours)
387 393 assert_equal "162.90", "%.2f" % assigns(:total_hours)
388 394 assert_tag :form,
389 395 :attributes => {:action => "/time_entries", :id => 'query_form'}
390 396 end
391 397
392 398 def test_index_all_projects_should_show_log_time_link
393 399 @request.session[:user_id] = 2
394 400 get :index
395 401 assert_response :success
396 402 assert_template 'index'
397 403 assert_tag 'a', :attributes => {:href => '/time_entries/new'}, :content => /Log time/
398 404 end
399 405
400 406 def test_index_at_project_level
401 407 get :index, :project_id => 'ecookbook'
402 408 assert_response :success
403 409 assert_template 'index'
404 410 assert_not_nil assigns(:entries)
405 411 assert_equal 4, assigns(:entries).size
406 412 # project and subproject
407 413 assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
408 414 assert_not_nil assigns(:total_hours)
409 415 assert_equal "162.90", "%.2f" % assigns(:total_hours)
410 416 # display all time by default
411 417 assert_nil assigns(:from)
412 418 assert_nil assigns(:to)
413 419 assert_tag :form,
414 420 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
415 421 end
416 422
417 423 def test_index_at_project_level_with_date_range
418 424 get :index, :project_id => 'ecookbook', :from => '2007-03-20', :to => '2007-04-30'
419 425 assert_response :success
420 426 assert_template 'index'
421 427 assert_not_nil assigns(:entries)
422 428 assert_equal 3, assigns(:entries).size
423 429 assert_not_nil assigns(:total_hours)
424 430 assert_equal "12.90", "%.2f" % assigns(:total_hours)
425 431 assert_equal '2007-03-20'.to_date, assigns(:from)
426 432 assert_equal '2007-04-30'.to_date, assigns(:to)
427 433 assert_tag :form,
428 434 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
429 435 end
430 436
431 437 def test_index_at_project_level_with_period
432 438 get :index, :project_id => 'ecookbook', :period => '7_days'
433 439 assert_response :success
434 440 assert_template 'index'
435 441 assert_not_nil assigns(:entries)
436 442 assert_not_nil assigns(:total_hours)
437 443 assert_equal Date.today - 7, assigns(:from)
438 444 assert_equal Date.today, assigns(:to)
439 445 assert_tag :form,
440 446 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
441 447 end
442 448
443 449 def test_index_one_day
444 450 get :index, :project_id => 'ecookbook', :from => "2007-03-23", :to => "2007-03-23"
445 451 assert_response :success
446 452 assert_template 'index'
447 453 assert_not_nil assigns(:total_hours)
448 454 assert_equal "4.25", "%.2f" % assigns(:total_hours)
449 455 assert_tag :form,
450 456 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
451 457 end
452 458
453 459 def test_index_from_a_date
454 460 get :index, :project_id => 'ecookbook', :from => "2007-03-23", :to => ""
455 461 assert_equal '2007-03-23'.to_date, assigns(:from)
456 462 assert_nil assigns(:to)
457 463 end
458 464
459 465 def test_index_to_a_date
460 466 get :index, :project_id => 'ecookbook', :from => "", :to => "2007-03-23"
461 467 assert_nil assigns(:from)
462 468 assert_equal '2007-03-23'.to_date, assigns(:to)
463 469 end
464 470
465 471 def test_index_today
466 472 Date.stubs(:today).returns('2011-12-15'.to_date)
467 473 get :index, :period => 'today'
468 474 assert_equal '2011-12-15'.to_date, assigns(:from)
469 475 assert_equal '2011-12-15'.to_date, assigns(:to)
470 476 end
471 477
472 478 def test_index_yesterday
473 479 Date.stubs(:today).returns('2011-12-15'.to_date)
474 480 get :index, :period => 'yesterday'
475 481 assert_equal '2011-12-14'.to_date, assigns(:from)
476 482 assert_equal '2011-12-14'.to_date, assigns(:to)
477 483 end
478 484
479 485 def test_index_current_week
480 486 Date.stubs(:today).returns('2011-12-15'.to_date)
481 487 get :index, :period => 'current_week'
482 488 assert_equal '2011-12-12'.to_date, assigns(:from)
483 489 assert_equal '2011-12-18'.to_date, assigns(:to)
484 490 end
485 491
486 492 def test_index_last_week
487 493 Date.stubs(:today).returns('2011-12-15'.to_date)
488 494 get :index, :period => 'current_week'
489 495 assert_equal '2011-12-05'.to_date, assigns(:from)
490 496 assert_equal '2011-12-11'.to_date, assigns(:to)
491 497 end
492 498
493 499 def test_index_last_week
494 500 Date.stubs(:today).returns('2011-12-15'.to_date)
495 501 get :index, :period => 'last_week'
496 502 assert_equal '2011-12-05'.to_date, assigns(:from)
497 503 assert_equal '2011-12-11'.to_date, assigns(:to)
498 504 end
499 505
500 506 def test_index_7_days
501 507 Date.stubs(:today).returns('2011-12-15'.to_date)
502 508 get :index, :period => '7_days'
503 509 assert_equal '2011-12-08'.to_date, assigns(:from)
504 510 assert_equal '2011-12-15'.to_date, assigns(:to)
505 511 end
506 512
507 513 def test_index_current_month
508 514 Date.stubs(:today).returns('2011-12-15'.to_date)
509 515 get :index, :period => 'current_month'
510 516 assert_equal '2011-12-01'.to_date, assigns(:from)
511 517 assert_equal '2011-12-31'.to_date, assigns(:to)
512 518 end
513 519
514 520 def test_index_last_month
515 521 Date.stubs(:today).returns('2011-12-15'.to_date)
516 522 get :index, :period => 'last_month'
517 523 assert_equal '2011-11-01'.to_date, assigns(:from)
518 524 assert_equal '2011-11-30'.to_date, assigns(:to)
519 525 end
520 526
521 527 def test_index_30_days
522 528 Date.stubs(:today).returns('2011-12-15'.to_date)
523 529 get :index, :period => '30_days'
524 530 assert_equal '2011-11-15'.to_date, assigns(:from)
525 531 assert_equal '2011-12-15'.to_date, assigns(:to)
526 532 end
527 533
528 534 def test_index_current_year
529 535 Date.stubs(:today).returns('2011-12-15'.to_date)
530 536 get :index, :period => 'current_year'
531 537 assert_equal '2011-01-01'.to_date, assigns(:from)
532 538 assert_equal '2011-12-31'.to_date, assigns(:to)
533 539 end
534 540
535 541 def test_index_at_issue_level
536 542 get :index, :issue_id => 1
537 543 assert_response :success
538 544 assert_template 'index'
539 545 assert_not_nil assigns(:entries)
540 546 assert_equal 2, assigns(:entries).size
541 547 assert_not_nil assigns(:total_hours)
542 548 assert_equal 154.25, assigns(:total_hours)
543 549 # display all time
544 550 assert_nil assigns(:from)
545 551 assert_nil assigns(:to)
546 552 # TODO: remove /projects/:project_id/issues/:issue_id/time_entries routes
547 553 # to use /issues/:issue_id/time_entries
548 554 assert_tag :form,
549 555 :attributes => {:action => "/projects/ecookbook/issues/1/time_entries", :id => 'query_form'}
550 556 end
551 557
552 558 def test_index_atom_feed
553 559 get :index, :project_id => 1, :format => 'atom'
554 560 assert_response :success
555 561 assert_equal 'application/atom+xml', @response.content_type
556 562 assert_not_nil assigns(:items)
557 563 assert assigns(:items).first.is_a?(TimeEntry)
558 564 end
559 565
560 566 def test_index_all_projects_csv_export
561 567 Setting.date_format = '%m/%d/%Y'
562 568 get :index, :format => 'csv'
563 569 assert_response :success
564 570 assert_equal 'text/csv; header=present', @response.content_type
565 571 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment,Overtime\n")
566 572 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\",\"\"\n")
567 573 end
568 574
569 575 def test_index_csv_export
570 576 Setting.date_format = '%m/%d/%Y'
571 577 get :index, :project_id => 1, :format => 'csv'
572 578 assert_response :success
573 579 assert_equal 'text/csv; header=present', @response.content_type
574 580 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment,Overtime\n")
575 581 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\",\"\"\n")
576 582 end
577 583
578 584 def test_index_csv_export_with_multi_custom_field
579 585 field = TimeEntryCustomField.create!(:name => 'Test', :field_format => 'list',
580 586 :multiple => true, :possible_values => ['value1', 'value2'])
581 587 entry = TimeEntry.find(1)
582 588 entry.custom_field_values = {field.id => ['value1', 'value2']}
583 589 entry.save!
584 590
585 591 get :index, :project_id => 1, :format => 'csv'
586 592 assert_response :success
587 593 assert_include '"value1, value2"', @response.body
588 594 end
589 595
590 596 def test_csv_big_5
591 597 user = User.find_by_id(3)
592 598 user.language = "zh-TW"
593 599 assert user.save
594 600 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88"
595 601 str_big5 = "\xa4@\xa4\xeb"
596 602 if str_utf8.respond_to?(:force_encoding)
597 603 str_utf8.force_encoding('UTF-8')
598 604 str_big5.force_encoding('Big5')
599 605 end
600 606 @request.session[:user_id] = 3
601 607 post :create, :project_id => 1,
602 608 :time_entry => {:comments => str_utf8,
603 609 # Not the default activity
604 610 :activity_id => '11',
605 611 :issue_id => '',
606 612 :spent_on => '2011-11-10',
607 613 :hours => '7.3'}
608 614 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
609 615
610 616 t = TimeEntry.find_by_comments(str_utf8)
611 617 assert_not_nil t
612 618 assert_equal 11, t.activity_id
613 619 assert_equal 7.3, t.hours
614 620 assert_equal 3, t.user_id
615 621
616 622 get :index, :project_id => 1, :format => 'csv',
617 623 :from => '2011-11-10', :to => '2011-11-10'
618 624 assert_response :success
619 625 assert_equal 'text/csv; header=present', @response.content_type
620 626 ar = @response.body.chomp.split("\n")
621 627 s1 = "\xa4\xe9\xb4\xc1"
622 628 if str_utf8.respond_to?(:force_encoding)
623 629 s1.force_encoding('Big5')
624 630 end
625 631 assert ar[0].include?(s1)
626 632 assert ar[1].include?(str_big5)
627 633 end
628 634
629 635 def test_csv_cannot_convert_should_be_replaced_big_5
630 636 user = User.find_by_id(3)
631 637 user.language = "zh-TW"
632 638 assert user.save
633 639 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85"
634 640 if str_utf8.respond_to?(:force_encoding)
635 641 str_utf8.force_encoding('UTF-8')
636 642 end
637 643 @request.session[:user_id] = 3
638 644 post :create, :project_id => 1,
639 645 :time_entry => {:comments => str_utf8,
640 646 # Not the default activity
641 647 :activity_id => '11',
642 648 :issue_id => '',
643 649 :spent_on => '2011-11-10',
644 650 :hours => '7.3'}
645 651 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
646 652
647 653 t = TimeEntry.find_by_comments(str_utf8)
648 654 assert_not_nil t
649 655 assert_equal 11, t.activity_id
650 656 assert_equal 7.3, t.hours
651 657 assert_equal 3, t.user_id
652 658
653 659 get :index, :project_id => 1, :format => 'csv',
654 660 :from => '2011-11-10', :to => '2011-11-10'
655 661 assert_response :success
656 662 assert_equal 'text/csv; header=present', @response.content_type
657 663 ar = @response.body.chomp.split("\n")
658 664 s1 = "\xa4\xe9\xb4\xc1"
659 665 if str_utf8.respond_to?(:force_encoding)
660 666 s1.force_encoding('Big5')
661 667 end
662 668 assert ar[0].include?(s1)
663 669 s2 = ar[1].split(",")[8]
664 670 if s2.respond_to?(:force_encoding)
665 671 s3 = "\xa5H?"
666 672 s3.force_encoding('Big5')
667 673 assert_equal s3, s2
668 674 elsif RUBY_PLATFORM == 'java'
669 675 assert_equal "??", s2
670 676 else
671 677 assert_equal "\xa5H???", s2
672 678 end
673 679 end
674 680
675 681 def test_csv_tw
676 682 with_settings :default_language => "zh-TW" do
677 683 str1 = "test_csv_tw"
678 684 user = User.find_by_id(3)
679 685 te1 = TimeEntry.create(:spent_on => '2011-11-10',
680 686 :hours => 999.9,
681 687 :project => Project.find(1),
682 688 :user => user,
683 689 :activity => TimeEntryActivity.find_by_name('Design'),
684 690 :comments => str1)
685 691 te2 = TimeEntry.find_by_comments(str1)
686 692 assert_not_nil te2
687 693 assert_equal 999.9, te2.hours
688 694 assert_equal 3, te2.user_id
689 695
690 696 get :index, :project_id => 1, :format => 'csv',
691 697 :from => '2011-11-10', :to => '2011-11-10'
692 698 assert_response :success
693 699 assert_equal 'text/csv; header=present', @response.content_type
694 700
695 701 ar = @response.body.chomp.split("\n")
696 702 s2 = ar[1].split(",")[7]
697 703 assert_equal '999.9', s2
698 704
699 705 str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
700 706 if str_tw.respond_to?(:force_encoding)
701 707 str_tw.force_encoding('UTF-8')
702 708 end
703 709 assert_equal str_tw, l(:general_lang_name)
704 710 assert_equal ',', l(:general_csv_separator)
705 711 assert_equal '.', l(:general_csv_decimal_separator)
706 712 end
707 713 end
708 714
709 715 def test_csv_fr
710 716 with_settings :default_language => "fr" do
711 717 str1 = "test_csv_fr"
712 718 user = User.find_by_id(3)
713 719 te1 = TimeEntry.create(:spent_on => '2011-11-10',
714 720 :hours => 999.9,
715 721 :project => Project.find(1),
716 722 :user => user,
717 723 :activity => TimeEntryActivity.find_by_name('Design'),
718 724 :comments => str1)
719 725 te2 = TimeEntry.find_by_comments(str1)
720 726 assert_not_nil te2
721 727 assert_equal 999.9, te2.hours
722 728 assert_equal 3, te2.user_id
723 729
724 730 get :index, :project_id => 1, :format => 'csv',
725 731 :from => '2011-11-10', :to => '2011-11-10'
726 732 assert_response :success
727 733 assert_equal 'text/csv; header=present', @response.content_type
728 734
729 735 ar = @response.body.chomp.split("\n")
730 736 s2 = ar[1].split(";")[7]
731 737 assert_equal '999,9', s2
732 738
733 739 str_fr = "Fran\xc3\xa7ais"
734 740 if str_fr.respond_to?(:force_encoding)
735 741 str_fr.force_encoding('UTF-8')
736 742 end
737 743 assert_equal str_fr, l(:general_lang_name)
738 744 assert_equal ';', l(:general_csv_separator)
739 745 assert_equal ',', l(:general_csv_decimal_separator)
740 746 end
741 747 end
742 748 end
General Comments 0
You need to be logged in to leave comments. Login now