To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / .svn / pristine / 1f / 1fe3164d40b2f175bf0aa2fdbd0804dbea4969a1.svn-base @ 1297:0a574315af3e

History | View | Annotate | Download (19.6 KB)

1 1296:038ba2d95de8 Chris
# Redmine - project management software
2
# Copyright (C) 2006-2012  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17
18
require File.expand_path('../../test_helper', __FILE__)
19
require 'projects_controller'
20
21
# Re-raise errors caught by the controller.
22
class ProjectsController; def rescue_action(e) raise e end; end
23
24
class ProjectsControllerTest < ActionController::TestCase
25
  fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
26
           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
27
           :attachments, :custom_fields, :custom_values, :time_entries
28
29
  def setup
30
    @controller = ProjectsController.new
31
    @request    = ActionController::TestRequest.new
32
    @response   = ActionController::TestResponse.new
33
    @request.session[:user_id] = nil
34
    Setting.default_language = 'en'
35
  end
36
37
  def test_index
38
    get :index
39
    assert_response :success
40
    assert_template 'index'
41
    assert_not_nil assigns(:projects)
42
43
    assert_tag :ul, :child => {:tag => 'li',
44
                               :descendant => {:tag => 'a', :content => 'eCookbook'},
45
                               :child => { :tag => 'ul',
46
                                           :descendant => { :tag => 'a',
47
                                                            :content => 'Child of private child'
48
                                                           }
49
                                          }
50
                               }
51
52
    assert_no_tag :a, :content => /Private child of eCookbook/
53
  end
54
55
  def test_index_atom
56
    get :index, :format => 'atom'
57
    assert_response :success
58
    assert_template 'common/feed'
59
    assert_select 'feed>title', :text => 'Redmine: Latest projects'
60
    assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_condition(User.current))
61
  end
62
63
  context "#index" do
64
    context "by non-admin user with view_time_entries permission" do
65
      setup do
66
        @request.session[:user_id] = 3
67
      end
68
      should "show overall spent time link" do
69
        get :index
70
        assert_template 'index'
71
        assert_tag :a, :attributes => {:href => '/time_entries'}
72
      end
73
    end
74
75
    context "by non-admin user without view_time_entries permission" do
76
      setup do
77
        Role.find(2).remove_permission! :view_time_entries
78
        Role.non_member.remove_permission! :view_time_entries
79
        Role.anonymous.remove_permission! :view_time_entries
80
        @request.session[:user_id] = 3
81
      end
82
      should "not show overall spent time link" do
83
        get :index
84
        assert_template 'index'
85
        assert_no_tag :a, :attributes => {:href => '/time_entries'}
86
      end
87
    end
88
  end
89
90
  context "#new" do
91
    context "by admin user" do
92
      setup do
93
        @request.session[:user_id] = 1
94
      end
95
96
      should "accept get" do
97
        get :new
98
        assert_response :success
99
        assert_template 'new'
100
      end
101
102
    end
103
104
    context "by non-admin user with add_project permission" do
105
      setup do
106
        Role.non_member.add_permission! :add_project
107
        @request.session[:user_id] = 9
108
      end
109
110
      should "accept get" do
111
        get :new
112
        assert_response :success
113
        assert_template 'new'
114
        assert_no_tag :select, :attributes => {:name => 'project[parent_id]'}
115
      end
116
    end
117
118
    context "by non-admin user with add_subprojects permission" do
119
      setup do
120
        Role.find(1).remove_permission! :add_project
121
        Role.find(1).add_permission! :add_subprojects
122
        @request.session[:user_id] = 2
123
      end
124
125
      should "accept get" do
126
        get :new, :parent_id => 'ecookbook'
127
        assert_response :success
128
        assert_template 'new'
129
        # parent project selected
130
        assert_tag :select, :attributes => {:name => 'project[parent_id]'},
131
                            :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}}
132
        # no empty value
133
        assert_no_tag :select, :attributes => {:name => 'project[parent_id]'},
134
                               :child => {:tag => 'option', :attributes => {:value => ''}}
135
      end
136
    end
137
138
  end
139
140
  context "POST :create" do
141
    context "by admin user" do
142
      setup do
143
        @request.session[:user_id] = 1
144
      end
145
146
      should "create a new project" do
147
        post :create,
148
          :project => {
149
            :name => "blog",
150
            :description => "weblog",
151
            :homepage => 'http://weblog',
152
            :identifier => "blog",
153
            :is_public => 1,
154
            :custom_field_values => { '3' => 'Beta' },
155
            :tracker_ids => ['1', '3'],
156
            # an issue custom field that is not for all project
157
            :issue_custom_field_ids => ['9'],
158
            :enabled_module_names => ['issue_tracking', 'news', 'repository']
159
          }
160
        assert_redirected_to '/projects/blog/settings'
161
162
        project = Project.find_by_name('blog')
163
        assert_kind_of Project, project
164
        assert project.active?
165
        assert_equal 'weblog', project.description
166
        assert_equal 'http://weblog', project.homepage
167
        assert_equal true, project.is_public?
168
        assert_nil project.parent
169
        assert_equal 'Beta', project.custom_value_for(3).value
170
        assert_equal [1, 3], project.trackers.map(&:id).sort
171
        assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
172
        assert project.issue_custom_fields.include?(IssueCustomField.find(9))
173
      end
174
175
      should "create a new subproject" do
176
        post :create, :project => { :name => "blog",
177
                                 :description => "weblog",
178
                                 :identifier => "blog",
179
                                 :is_public => 1,
180
                                 :custom_field_values => { '3' => 'Beta' },
181
                                 :parent_id => 1
182
                                }
183
        assert_redirected_to '/projects/blog/settings'
184
185
        project = Project.find_by_name('blog')
186
        assert_kind_of Project, project
187
        assert_equal Project.find(1), project.parent
188
      end
189
190
      should "continue" do
191
        assert_difference 'Project.count' do
192
          post :create, :project => {:name => "blog", :identifier => "blog"}, :continue => 'Create and continue'
193
        end
194
        assert_redirected_to '/projects/new?'
195
      end
196
    end
197
198
    context "by non-admin user with add_project permission" do
199
      setup do
200
        Role.non_member.add_permission! :add_project
201
        @request.session[:user_id] = 9
202
      end
203
204
      should "accept create a Project" do
205
        post :create, :project => { :name => "blog",
206
                                 :description => "weblog",
207
                                 :identifier => "blog",
208
                                 :is_public => 1,
209
                                 :custom_field_values => { '3' => 'Beta' },
210
                                 :tracker_ids => ['1', '3'],
211
                                 :enabled_module_names => ['issue_tracking', 'news', 'repository']
212
                                }
213
214
        assert_redirected_to '/projects/blog/settings'
215
216
        project = Project.find_by_name('blog')
217
        assert_kind_of Project, project
218
        assert_equal 'weblog', project.description
219
        assert_equal true, project.is_public?
220
        assert_equal [1, 3], project.trackers.map(&:id).sort
221
        assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
222
223
        # User should be added as a project member
224
        assert User.find(9).member_of?(project)
225
        assert_equal 1, project.members.size
226
      end
227
228
      should "fail with parent_id" do
229
        assert_no_difference 'Project.count' do
230
          post :create, :project => { :name => "blog",
231
                                   :description => "weblog",
232
                                   :identifier => "blog",
233
                                   :is_public => 1,
234
                                   :custom_field_values => { '3' => 'Beta' },
235
                                   :parent_id => 1
236
                                  }
237
        end
238
        assert_response :success
239
        project = assigns(:project)
240
        assert_kind_of Project, project
241
        assert_not_nil project.errors[:parent_id]
242
      end
243
    end
244
245
    context "by non-admin user with add_subprojects permission" do
246
      setup do
247
        Role.find(1).remove_permission! :add_project
248
        Role.find(1).add_permission! :add_subprojects
249
        @request.session[:user_id] = 2
250
      end
251
252
      should "create a project with a parent_id" do
253
        post :create, :project => { :name => "blog",
254
                                 :description => "weblog",
255
                                 :identifier => "blog",
256
                                 :is_public => 1,
257
                                 :custom_field_values => { '3' => 'Beta' },
258
                                 :parent_id => 1
259
                                }
260
        assert_redirected_to '/projects/blog/settings'
261
        project = Project.find_by_name('blog')
262
      end
263
264
      should "fail without parent_id" do
265
        assert_no_difference 'Project.count' do
266
          post :create, :project => { :name => "blog",
267
                                   :description => "weblog",
268
                                   :identifier => "blog",
269
                                   :is_public => 1,
270
                                   :custom_field_values => { '3' => 'Beta' }
271
                                  }
272
        end
273
        assert_response :success
274
        project = assigns(:project)
275
        assert_kind_of Project, project
276
        assert_not_nil project.errors[:parent_id]
277
      end
278
279
      should "fail with unauthorized parent_id" do
280
        assert !User.find(2).member_of?(Project.find(6))
281
        assert_no_difference 'Project.count' do
282
          post :create, :project => { :name => "blog",
283
                                   :description => "weblog",
284
                                   :identifier => "blog",
285
                                   :is_public => 1,
286
                                   :custom_field_values => { '3' => 'Beta' },
287
                                   :parent_id => 6
288
                                  }
289
        end
290
        assert_response :success
291
        project = assigns(:project)
292
        assert_kind_of Project, project
293
        assert_not_nil project.errors[:parent_id]
294
      end
295
    end
296
  end
297
298
  def test_create_should_preserve_modules_on_validation_failure
299
    with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
300
      @request.session[:user_id] = 1
301
      assert_no_difference 'Project.count' do
302
        post :create, :project => {
303
          :name => "blog",
304
          :identifier => "",
305
          :enabled_module_names => %w(issue_tracking news)
306
        }
307
      end
308
      assert_response :success
309
      project = assigns(:project)
310
      assert_equal %w(issue_tracking news), project.enabled_module_names.sort
311
    end
312
  end
313
314
  def test_show_by_id
315
    get :show, :id => 1
316
    assert_response :success
317
    assert_template 'show'
318
    assert_not_nil assigns(:project)
319
  end
320
321
  def test_show_by_identifier
322
    get :show, :id => 'ecookbook'
323
    assert_response :success
324
    assert_template 'show'
325
    assert_not_nil assigns(:project)
326
    assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
327
328
    assert_tag 'li', :content => /Development status/
329
  end
330
331
  def test_show_should_not_display_hidden_custom_fields
332
    ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
333
    get :show, :id => 'ecookbook'
334
    assert_response :success
335
    assert_template 'show'
336
    assert_not_nil assigns(:project)
337
338
    assert_no_tag 'li', :content => /Development status/
339
  end
340
341
  def test_show_should_not_fail_when_custom_values_are_nil
342
    project = Project.find_by_identifier('ecookbook')
343
    project.custom_values.first.update_attribute(:value, nil)
344
    get :show, :id => 'ecookbook'
345
    assert_response :success
346
    assert_template 'show'
347
    assert_not_nil assigns(:project)
348
    assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
349
  end
350
351
  def show_archived_project_should_be_denied
352
    project = Project.find_by_identifier('ecookbook')
353
    project.archive!
354
355
    get :show, :id => 'ecookbook'
356
    assert_response 403
357
    assert_nil assigns(:project)
358
    assert_tag :tag => 'p', :content => /archived/
359
  end
360
361
  def test_private_subprojects_hidden
362
    get :show, :id => 'ecookbook'
363
    assert_response :success
364
    assert_template 'show'
365
    assert_no_tag :tag => 'a', :content => /Private child/
366
  end
367
368
  def test_private_subprojects_visible
369
    @request.session[:user_id] = 2 # manager who is a member of the private subproject
370
    get :show, :id => 'ecookbook'
371
    assert_response :success
372
    assert_template 'show'
373
    assert_tag :tag => 'a', :content => /Private child/
374
  end
375
376
  def test_settings
377
    @request.session[:user_id] = 2 # manager
378
    get :settings, :id => 1
379
    assert_response :success
380
    assert_template 'settings'
381
  end
382
383
  def test_settings_should_be_denied_for_member_on_closed_project
384
    Project.find(1).close
385
    @request.session[:user_id] = 2 # manager
386
387
    get :settings, :id => 1
388
    assert_response 403
389
  end
390
391
  def test_settings_should_be_denied_for_anonymous_on_closed_project
392
    Project.find(1).close
393
394
    get :settings, :id => 1
395
    assert_response 302
396
  end
397
398
  def test_update
399
    @request.session[:user_id] = 2 # manager
400
    post :update, :id => 1, :project => {:name => 'Test changed name',
401
                                       :issue_custom_field_ids => ['']}
402
    assert_redirected_to '/projects/ecookbook/settings'
403
    project = Project.find(1)
404
    assert_equal 'Test changed name', project.name
405
  end
406
407
  def test_update_with_failure
408
    @request.session[:user_id] = 2 # manager
409
    post :update, :id => 1, :project => {:name => ''}
410
    assert_response :success
411
    assert_template 'settings'
412
    assert_error_tag :content => /name can&#x27;t be blank/i
413
  end
414
415
  def test_update_should_be_denied_for_member_on_closed_project
416
    Project.find(1).close
417
    @request.session[:user_id] = 2 # manager
418
419
    post :update, :id => 1, :project => {:name => 'Closed'}
420
    assert_response 403
421
    assert_equal 'eCookbook', Project.find(1).name
422
  end
423
424
  def test_update_should_be_denied_for_anonymous_on_closed_project
425
    Project.find(1).close
426
427
    post :update, :id => 1, :project => {:name => 'Closed'}
428
    assert_response 302
429
    assert_equal 'eCookbook', Project.find(1).name
430
  end
431
432
  def test_modules
433
    @request.session[:user_id] = 2
434
    Project.find(1).enabled_module_names = ['issue_tracking', 'news']
435
436
    post :modules, :id => 1, :enabled_module_names => ['issue_tracking', 'repository', 'documents']
437
    assert_redirected_to '/projects/ecookbook/settings/modules'
438
    assert_equal ['documents', 'issue_tracking', 'repository'], Project.find(1).enabled_module_names.sort
439
  end
440
441
  def test_destroy_without_confirmation
442
    @request.session[:user_id] = 1 # admin
443
    delete :destroy, :id => 1
444
    assert_response :success
445
    assert_template 'destroy'
446
    assert_not_nil Project.find_by_id(1)
447
    assert_tag :tag => 'strong',
448
               :content => ['Private child of eCookbook',
449
                            'Child of private child, eCookbook Subproject 1',
450
                            'eCookbook Subproject 2'].join(', ')
451
  end
452
453
  def test_destroy
454
    @request.session[:user_id] = 1 # admin
455
    delete :destroy, :id => 1, :confirm => 1
456
    assert_redirected_to '/admin/projects'
457
    assert_nil Project.find_by_id(1)
458
  end
459
460
  def test_archive
461
    @request.session[:user_id] = 1 # admin
462
    post :archive, :id => 1
463
    assert_redirected_to '/admin/projects'
464
    assert !Project.find(1).active?
465
  end
466
467
  def test_archive_with_failure
468
    @request.session[:user_id] = 1
469
    Project.any_instance.stubs(:archive).returns(false)
470
    post :archive, :id => 1
471
    assert_redirected_to '/admin/projects'
472
    assert_match /project cannot be archived/i, flash[:error]
473
  end
474
475
  def test_unarchive
476
    @request.session[:user_id] = 1 # admin
477
    Project.find(1).archive
478
    post :unarchive, :id => 1
479
    assert_redirected_to '/admin/projects'
480
    assert Project.find(1).active?
481
  end
482
483
  def test_close
484
    @request.session[:user_id] = 2
485
    post :close, :id => 1
486
    assert_redirected_to '/projects/ecookbook'
487
    assert_equal Project::STATUS_CLOSED, Project.find(1).status
488
  end
489
490
  def test_reopen
491
    Project.find(1).close
492
    @request.session[:user_id] = 2
493
    post :reopen, :id => 1
494
    assert_redirected_to '/projects/ecookbook'
495
    assert Project.find(1).active?
496
  end
497
498
  def test_project_breadcrumbs_should_be_limited_to_3_ancestors
499
    CustomField.delete_all
500
    parent = nil
501
    6.times do |i|
502
      p = Project.create!(:name => "Breadcrumbs #{i}", :identifier => "breadcrumbs-#{i}")
503
      p.set_parent!(parent)
504
      get :show, :id => p
505
      assert_tag :h1, :parent => { :attributes => {:id => 'header'}},
506
                      :children => { :count => [i, 3].min,
507
                                     :only => { :tag => 'a' } }
508
509
      parent = p
510
    end
511
  end
512
513
  def test_get_copy
514
    @request.session[:user_id] = 1 # admin
515
    get :copy, :id => 1
516
    assert_response :success
517
    assert_template 'copy'
518
    assert assigns(:project)
519
    assert_equal Project.find(1).description, assigns(:project).description
520
    assert_nil assigns(:project).id
521
522
    assert_tag :tag => 'input',
523
      :attributes => {:name => 'project[enabled_module_names][]', :value => 'issue_tracking'}
524
  end
525
526
  def test_get_copy_with_invalid_source_should_respond_with_404
527
    @request.session[:user_id] = 1
528
    get :copy, :id => 99
529
    assert_response 404
530
  end
531
532
  def test_post_copy_should_copy_requested_items
533
    @request.session[:user_id] = 1 # admin
534
    CustomField.delete_all
535
536
    assert_difference 'Project.count' do
537
      post :copy, :id => 1,
538
        :project => {
539
          :name => 'Copy',
540
          :identifier => 'unique-copy',
541
          :tracker_ids => ['1', '2', '3', ''],
542
          :enabled_module_names => %w(issue_tracking time_tracking)
543
        },
544
        :only => %w(issues versions)
545
    end
546
    project = Project.find('unique-copy')
547
    source = Project.find(1)
548
    assert_equal %w(issue_tracking time_tracking), project.enabled_module_names.sort
549
550
    assert_equal source.versions.count, project.versions.count, "All versions were not copied"
551
    assert_equal source.issues.count, project.issues.count, "All issues were not copied"
552
    assert_equal 0, project.members.count
553
  end
554
555
  def test_post_copy_should_redirect_to_settings_when_successful
556
    @request.session[:user_id] = 1 # admin
557
    post :copy, :id => 1, :project => {:name => 'Copy', :identifier => 'unique-copy'}
558
    assert_response :redirect
559
    assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'unique-copy'
560
  end
561
562
  def test_jump_should_redirect_to_active_tab
563
    get :show, :id => 1, :jump => 'issues'
564
    assert_redirected_to '/projects/ecookbook/issues'
565
  end
566
567
  def test_jump_should_not_redirect_to_inactive_tab
568
    get :show, :id => 3, :jump => 'documents'
569
    assert_response :success
570
    assert_template 'show'
571
  end
572
573
  def test_jump_should_not_redirect_to_unknown_tab
574
    get :show, :id => 3, :jump => 'foobar'
575
    assert_response :success
576
    assert_template 'show'
577
  end
578
end