-# Redmine - project management software
-# Copyright (C) 2006-2008 Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-require File.dirname(__FILE__) + '/../test_helper'
-require 'projects_controller'
-
-# Re-raise errors caught by the controller.
-class ProjectsController; def rescue_action(e) raise e end; end
-
-class ProjectsControllerTest < ActionController::TestCase
- fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
- :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
- :attachments
-
- def setup
- @controller = ProjectsController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- @request.session[:user_id] = nil
- Setting.default_language = 'en'
- end
-
- def test_index_routing
- assert_routing(
- {:method => :get, :path => '/projects'},
- :controller => 'projects', :action => 'index'
- )
- end
-
- def test_index
- get :index
- assert_response :success
- assert_template 'index'
- assert_not_nil assigns(:projects)
-
- assert_tag :ul, :child => {:tag => 'li',
- :descendant => {:tag => 'a', :content => 'eCookbook'},
- :child => { :tag => 'ul',
- :descendant => { :tag => 'a',
- :content => 'Child of private child'
- }
- }
- }
-
- assert_no_tag :a, :content => /Private child of eCookbook/
- end
-
- def test_index_atom_routing
- assert_routing(
- {:method => :get, :path => '/projects.atom'},
- :controller => 'projects', :action => 'index', :format => 'atom'
- )
- end
-
- def test_index_atom
- get :index, :format => 'atom'
- assert_response :success
- assert_template 'common/feed.atom.rxml'
- assert_select 'feed>title', :text => 'Redmine: Latest projects'
- assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_by(User.current))
- end
-
- def test_add_routing
- assert_routing(
- {:method => :get, :path => '/projects/new'},
- :controller => 'projects', :action => 'add'
- )
- assert_recognizes(
- {:controller => 'projects', :action => 'add'},
- {:method => :post, :path => '/projects/new'}
- )
- assert_recognizes(
- {:controller => 'projects', :action => 'add'},
- {:method => :post, :path => '/projects'}
- )
- end
-
- def test_get_add
- @request.session[:user_id] = 1
- get :add
- assert_response :success
- assert_template 'add'
- end
-
- def test_get_add_by_non_admin
- @request.session[:user_id] = 2
- get :add
- assert_response :success
- assert_template 'add'
- end
-
- def test_post_add
- @request.session[:user_id] = 1
- post :add, :project => { :name => "blog",
- :description => "weblog",
- :identifier => "blog",
- :is_public => 1,
- :custom_field_values => { '3' => 'Beta' }
- }
- assert_redirected_to '/projects/blog/settings'
-
- project = Project.find_by_name('blog')
- assert_kind_of Project, project
- assert_equal 'weblog', project.description
- assert_equal true, project.is_public?
- end
-
- def test_post_add_by_non_admin
- @request.session[:user_id] = 2
- post :add, :project => { :name => "blog",
- :description => "weblog",
- :identifier => "blog",
- :is_public => 1,
- :custom_field_values => { '3' => 'Beta' }
- }
- assert_redirected_to '/projects/blog/settings'
-
- project = Project.find_by_name('blog')
- assert_kind_of Project, project
- assert_equal 'weblog', project.description
- assert_equal true, project.is_public?
-
- # User should be added as a project member
- assert User.find(2).member_of?(project)
- assert_equal 1, project.members.size
- end
-
- def test_show_routing
- assert_routing(
- {:method => :get, :path => '/projects/test'},
- :controller => 'projects', :action => 'show', :id => 'test'
- )
- end
-
- def test_show_by_id
- get :show, :id => 1
- assert_response :success
- assert_template 'show'
- assert_not_nil assigns(:project)
- end
-
- def test_show_by_identifier
- get :show, :id => 'ecookbook'
- assert_response :success
- assert_template 'show'
- assert_not_nil assigns(:project)
- assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
- end
-
- def test_private_subprojects_hidden
- get :show, :id => 'ecookbook'
- assert_response :success
- assert_template 'show'
- assert_no_tag :tag => 'a', :content => /Private child/
- end
-
- def test_private_subprojects_visible
- @request.session[:user_id] = 2 # manager who is a member of the private subproject
- get :show, :id => 'ecookbook'
- assert_response :success
- assert_template 'show'
- assert_tag :tag => 'a', :content => /Private child/
- end
-
- def test_settings_routing
- assert_routing(
- {:method => :get, :path => '/projects/4223/settings'},
- :controller => 'projects', :action => 'settings', :id => '4223'
- )
- assert_routing(
- {:method => :get, :path => '/projects/4223/settings/members'},
- :controller => 'projects', :action => 'settings', :id => '4223', :tab => 'members'
- )
- end
-
- def test_settings
- @request.session[:user_id] = 2 # manager
- get :settings, :id => 1
- assert_response :success
- assert_template 'settings'
- end
-
- def test_edit
- @request.session[:user_id] = 2 # manager
- post :edit, :id => 1, :project => {:name => 'Test changed name',
- :issue_custom_field_ids => ['']}
- assert_redirected_to 'projects/ecookbook/settings'
- project = Project.find(1)
- assert_equal 'Test changed name', project.name
- end
-
- def test_add_version_routing
- assert_routing(
- {:method => :get, :path => 'projects/64/versions/new'},
- :controller => 'projects', :action => 'add_version', :id => '64'
- )
- assert_routing(
- #TODO: use PUT
- {:method => :post, :path => 'projects/64/versions/new'},
- :controller => 'projects', :action => 'add_version', :id => '64'
- )
- end
-
- def test_add_issue_category_routing
- assert_routing(
- {:method => :get, :path => 'projects/test/categories/new'},
- :controller => 'projects', :action => 'add_issue_category', :id => 'test'
- )
- assert_routing(
- #TODO: use PUT and update form
- {:method => :post, :path => 'projects/64/categories/new'},
- :controller => 'projects', :action => 'add_issue_category', :id => '64'
- )
- end
-
- def test_destroy_routing
- assert_routing(
- {:method => :get, :path => '/projects/567/destroy'},
- :controller => 'projects', :action => 'destroy', :id => '567'
- )
- assert_routing(
- #TODO: use DELETE and update form
- {:method => :post, :path => 'projects/64/destroy'},
- :controller => 'projects', :action => 'destroy', :id => '64'
- )
- end
-
- def test_get_destroy
- @request.session[:user_id] = 1 # admin
- get :destroy, :id => 1
- assert_response :success
- assert_template 'destroy'
- assert_not_nil Project.find_by_id(1)
- end
-
- def test_post_destroy
- @request.session[:user_id] = 1 # admin
- post :destroy, :id => 1, :confirm => 1
- assert_redirected_to 'admin/projects'
- assert_nil Project.find_by_id(1)
- end
-
- def test_add_file
- set_tmp_attachments_directory
- @request.session[:user_id] = 2
- Setting.notified_events = ['file_added']
- ActionMailer::Base.deliveries.clear
-
- assert_difference 'Attachment.count' do
- post :add_file, :id => 1, :version_id => '',
- :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
- end
- assert_redirected_to 'projects/ecookbook/files'
- a = Attachment.find(:first, :order => 'created_on DESC')
- assert_equal 'testfile.txt', a.filename
- assert_equal Project.find(1), a.container
-
- mail = ActionMailer::Base.deliveries.last
- assert_kind_of TMail::Mail, mail
- assert_equal "[eCookbook] New file", mail.subject
- assert mail.body.include?('testfile.txt')
- end
-
- def test_add_file_routing
- assert_routing(
- {:method => :get, :path => '/projects/33/files/new'},
- :controller => 'projects', :action => 'add_file', :id => '33'
- )
- assert_routing(
- {:method => :post, :path => '/projects/33/files/new'},
- :controller => 'projects', :action => 'add_file', :id => '33'
- )
- end
-
- def test_add_version_file
- set_tmp_attachments_directory
- @request.session[:user_id] = 2
- Setting.notified_events = ['file_added']
-
- assert_difference 'Attachment.count' do
- post :add_file, :id => 1, :version_id => '2',
- :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
- end
- assert_redirected_to 'projects/ecookbook/files'
- a = Attachment.find(:first, :order => 'created_on DESC')
- assert_equal 'testfile.txt', a.filename
- assert_equal Version.find(2), a.container
- end
-
- def test_list_files
- get :list_files, :id => 1
- assert_response :success
- assert_template 'list_files'
- assert_not_nil assigns(:containers)
-
- # file attached to the project
- assert_tag :a, :content => 'project_file.zip',
- :attributes => { :href => '/attachments/download/8/project_file.zip' }
-
- # file attached to a project's version
- assert_tag :a, :content => 'version_file.zip',
- :attributes => { :href => '/attachments/download/9/version_file.zip' }
- end
-
- def test_list_files_routing
- assert_routing(
- {:method => :get, :path => '/projects/33/files'},
- :controller => 'projects', :action => 'list_files', :id => '33'
- )
- end
-
- def test_changelog_routing
- assert_routing(
- {:method => :get, :path => '/projects/44/changelog'},
- :controller => 'projects', :action => 'changelog', :id => '44'
- )
- end
-
- def test_changelog
- get :changelog, :id => 1
- assert_response :success
- assert_template 'changelog'
- assert_not_nil assigns(:versions)
- end
-
- def test_roadmap_routing
- assert_routing(
- {:method => :get, :path => 'projects/33/roadmap'},
- :controller => 'projects', :action => 'roadmap', :id => '33'
- )
- end
-
- def test_roadmap
- get :roadmap, :id => 1
- assert_response :success
- assert_template 'roadmap'
- assert_not_nil assigns(:versions)
- # Version with no date set appears
- assert assigns(:versions).include?(Version.find(3))
- # Completed version doesn't appear
- assert !assigns(:versions).include?(Version.find(1))
- end
-
- def test_roadmap_with_completed_versions
- get :roadmap, :id => 1, :completed => 1
- assert_response :success
- assert_template 'roadmap'
- assert_not_nil assigns(:versions)
- # Version with no date set appears
- assert assigns(:versions).include?(Version.find(3))
- # Completed version appears
- assert assigns(:versions).include?(Version.find(1))
- end
-
- def test_project_activity_routing
- assert_routing(
- {:method => :get, :path => '/projects/1/activity'},
- :controller => 'projects', :action => 'activity', :id => '1'
- )
- end
-
- def test_project_activity_atom_routing
- assert_routing(
- {:method => :get, :path => '/projects/1/activity.atom'},
- :controller => 'projects', :action => 'activity', :id => '1', :format => 'atom'
- )
- end
-
- def test_project_activity
- get :activity, :id => 1, :with_subprojects => 0
- assert_response :success
- assert_template 'activity'
- assert_not_nil assigns(:events_by_day)
-
- assert_tag :tag => "h3",
- :content => /#{2.days.ago.to_date.day}/,
- :sibling => { :tag => "dl",
- :child => { :tag => "dt",
- :attributes => { :class => /issue-edit/ },
- :child => { :tag => "a",
- :content => /(#{IssueStatus.find(2).name})/,
- }
- }
- }
- end
-
- def test_previous_project_activity
- get :activity, :id => 1, :from => 3.days.ago.to_date
- assert_response :success
- assert_template 'activity'
- assert_not_nil assigns(:events_by_day)
-
- assert_tag :tag => "h3",
- :content => /#{3.day.ago.to_date.day}/,
- :sibling => { :tag => "dl",
- :child => { :tag => "dt",
- :attributes => { :class => /issue/ },
- :child => { :tag => "a",
- :content => /#{Issue.find(1).subject}/,
- }
- }
- }
- end
-
- def test_global_activity_routing
- assert_routing({:method => :get, :path => '/activity'}, :controller => 'projects', :action => 'activity', :id => nil)
- end
-
- def test_global_activity
- get :activity
- assert_response :success
- assert_template 'activity'
- assert_not_nil assigns(:events_by_day)
-
- assert_tag :tag => "h3",
- :content => /#{5.day.ago.to_date.day}/,
- :sibling => { :tag => "dl",
- :child => { :tag => "dt",
- :attributes => { :class => /issue/ },
- :child => { :tag => "a",
- :content => /#{Issue.find(5).subject}/,
- }
- }
- }
- end
-
- def test_user_activity
- get :activity, :user_id => 2
- assert_response :success
- assert_template 'activity'
- assert_not_nil assigns(:events_by_day)
-
- assert_tag :tag => "h3",
- :content => /#{3.day.ago.to_date.day}/,
- :sibling => { :tag => "dl",
- :child => { :tag => "dt",
- :attributes => { :class => /issue/ },
- :child => { :tag => "a",
- :content => /#{Issue.find(1).subject}/,
- }
- }
- }
- end
-
- def test_global_activity_atom_routing
- assert_routing({:method => :get, :path => '/activity.atom'}, :controller => 'projects', :action => 'activity', :id => nil, :format => 'atom')
- end
-
- def test_activity_atom_feed
- get :activity, :format => 'atom'
- assert_response :success
- assert_template 'common/feed.atom.rxml'
- end
-
- def test_archive_routing
- assert_routing(
- #TODO: use PUT to project path and modify form
- {:method => :post, :path => 'projects/64/archive'},
- :controller => 'projects', :action => 'archive', :id => '64'
- )
- end
-
- def test_archive
- @request.session[:user_id] = 1 # admin
- post :archive, :id => 1
- assert_redirected_to 'admin/projects'
- assert !Project.find(1).active?
- end
-
- def test_unarchive_routing
- assert_routing(
- #TODO: use PUT to project path and modify form
- {:method => :post, :path => '/projects/567/unarchive'},
- :controller => 'projects', :action => 'unarchive', :id => '567'
- )
- end
-
- def test_unarchive
- @request.session[:user_id] = 1 # admin
- Project.find(1).archive
- post :unarchive, :id => 1
- assert_redirected_to 'admin/projects'
- assert Project.find(1).active?
- end
-
- def test_project_breadcrumbs_should_be_limited_to_3_ancestors
- CustomField.delete_all
- parent = nil
- 6.times do |i|
- p = Project.create!(:name => "Breadcrumbs #{i}", :identifier => "breadcrumbs-#{i}")
- p.set_parent!(parent)
- get :show, :id => p
- assert_tag :h1, :parent => { :attributes => {:id => 'header'}},
- :children => { :count => [i, 3].min,
- :only => { :tag => 'a' } }
-
- parent = p
- end
- end
-
- def test_copy_with_project
- @request.session[:user_id] = 1 # admin
- get :copy, :id => 1
- assert_response :success
- assert_template 'copy'
- assert assigns(:project)
- assert_equal Project.find(1).description, assigns(:project).description
- assert_nil assigns(:project).id
- end
-
- def test_copy_without_project
- @request.session[:user_id] = 1 # admin
- get :copy
- assert_response :redirect
- assert_redirected_to :controller => 'admin', :action => 'projects'
- end
-
- def test_jump_should_redirect_to_active_tab
- get :show, :id => 1, :jump => 'issues'
- assert_redirected_to 'projects/ecookbook/issues'
- end
-
- def test_jump_should_not_redirect_to_inactive_tab
- get :show, :id => 3, :jump => 'documents'
- assert_response :success
- assert_template 'show'
- end
-
- def test_jump_should_not_redirect_to_unknown_tab
- get :show, :id => 3, :jump => 'foobar'
- assert_response :success
- assert_template 'show'
- end
-
- # A hook that is manually registered later
- class ProjectBasedTemplate < Redmine::Hook::ViewListener
- def view_layouts_base_html_head(context)
- # Adds a project stylesheet
- stylesheet_link_tag(context[:project].identifier) if context[:project]
- end
- end
- # Don't use this hook now
- Redmine::Hook.clear_listeners
-
- def test_hook_response
- Redmine::Hook.add_listener(ProjectBasedTemplate)
- get :show, :id => 1
- assert_tag :tag => 'link', :attributes => {:href => '/stylesheets/ecookbook.css'},
- :parent => {:tag => 'head'}
-
- Redmine::Hook.clear_listeners
- end
-end
+# Redmine - project management software\r
+# Copyright (C) 2006-2008 Jean-Philippe Lang\r
+#\r
+# This program is free software; you can redistribute it and/or\r
+# modify it under the terms of the GNU General Public License\r
+# as published by the Free Software Foundation; either version 2\r
+# of the License, or (at your option) any later version.\r
+# \r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+# GNU General Public License for more details.\r
+# \r
+# You should have received a copy of the GNU General Public License\r
+# along with this program; if not, write to the Free Software\r
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+\r
+require File.dirname(__FILE__) + '/../test_helper'\r
+require 'projects_controller'\r
+\r
+# Re-raise errors caught by the controller.\r
+class ProjectsController; def rescue_action(e) raise e end; end\r
+\r
+class ProjectsControllerTest < ActionController::TestCase\r
+ fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,\r
+ :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,\r
+ :attachments\r
+\r
+ def setup\r
+ @controller = ProjectsController.new\r
+ @request = ActionController::TestRequest.new\r
+ @response = ActionController::TestResponse.new\r
+ @request.session[:user_id] = nil\r
+ Setting.default_language = 'en'\r
+ end\r
+ \r
+ def test_index_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects'},\r
+ :controller => 'projects', :action => 'index'\r
+ )\r
+ end\r
+ \r
+ def test_index\r
+ get :index\r
+ assert_response :success\r
+ assert_template 'index'\r
+ assert_not_nil assigns(:projects)\r
+ \r
+ assert_tag :ul, :child => {:tag => 'li',\r
+ :descendant => {:tag => 'a', :content => 'eCookbook'},\r
+ :child => { :tag => 'ul',\r
+ :descendant => { :tag => 'a',\r
+ :content => 'Child of private child'\r
+ }\r
+ }\r
+ }\r
+ \r
+ assert_no_tag :a, :content => /Private child of eCookbook/\r
+ end\r
+ \r
+ def test_index_atom_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects.atom'},\r
+ :controller => 'projects', :action => 'index', :format => 'atom'\r
+ )\r
+ end\r
+ \r
+ def test_index_atom\r
+ get :index, :format => 'atom'\r
+ assert_response :success\r
+ assert_template 'common/feed.atom.rxml'\r
+ assert_select 'feed>title', :text => 'Redmine: Latest projects'\r
+ assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_by(User.current))\r
+ end\r
+ \r
+ def test_add_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects/new'},\r
+ :controller => 'projects', :action => 'add'\r
+ )\r
+ assert_recognizes(\r
+ {:controller => 'projects', :action => 'add'},\r
+ {:method => :post, :path => '/projects/new'}\r
+ )\r
+ assert_recognizes(\r
+ {:controller => 'projects', :action => 'add'},\r
+ {:method => :post, :path => '/projects'}\r
+ )\r
+ end\r
+ \r
+ def test_get_add\r
+ @request.session[:user_id] = 1\r
+ get :add\r
+ assert_response :success\r
+ assert_template 'add'\r
+ end\r
+ \r
+ def test_get_add_by_non_admin\r
+ @request.session[:user_id] = 2\r
+ get :add\r
+ assert_response :success\r
+ assert_template 'add'\r
+ end\r
+ \r
+ def test_post_add\r
+ @request.session[:user_id] = 1\r
+ post :add, :project => { :name => "blog", \r
+ :description => "weblog",\r
+ :identifier => "blog",\r
+ :is_public => 1,\r
+ :custom_field_values => { '3' => 'Beta' }\r
+ }\r
+ assert_redirected_to '/projects/blog/settings'\r
+ \r
+ project = Project.find_by_name('blog')\r
+ assert_kind_of Project, project\r
+ assert_equal 'weblog', project.description \r
+ assert_equal true, project.is_public?\r
+ end\r
+ \r
+ def test_post_add_by_non_admin\r
+ @request.session[:user_id] = 2\r
+ post :add, :project => { :name => "blog", \r
+ :description => "weblog",\r
+ :identifier => "blog",\r
+ :is_public => 1,\r
+ :custom_field_values => { '3' => 'Beta' }\r
+ }\r
+ assert_redirected_to '/projects/blog/settings'\r
+ \r
+ project = Project.find_by_name('blog')\r
+ assert_kind_of Project, project\r
+ assert_equal 'weblog', project.description \r
+ assert_equal true, project.is_public?\r
+ \r
+ # User should be added as a project member\r
+ assert User.find(2).member_of?(project)\r
+ assert_equal 1, project.members.size\r
+ end\r
+ \r
+ def test_show_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects/test'},\r
+ :controller => 'projects', :action => 'show', :id => 'test'\r
+ )\r
+ end\r
+ \r
+ def test_show_by_id\r
+ get :show, :id => 1\r
+ assert_response :success\r
+ assert_template 'show'\r
+ assert_not_nil assigns(:project)\r
+ end\r
+\r
+ def test_show_by_identifier\r
+ get :show, :id => 'ecookbook'\r
+ assert_response :success\r
+ assert_template 'show'\r
+ assert_not_nil assigns(:project)\r
+ assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)\r
+ end\r
+ \r
+ def test_show_should_not_fail_when_custom_values_are_nil\r
+ project = Project.find_by_identifier('ecookbook')\r
+ project.custom_values.first.update_attribute(:value, nil)\r
+ get :show, :id => 'ecookbook'\r
+ assert_response :success\r
+ assert_template 'show'\r
+ assert_not_nil assigns(:project)\r
+ assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)\r
+ end\r
+ \r
+ def test_private_subprojects_hidden\r
+ get :show, :id => 'ecookbook'\r
+ assert_response :success\r
+ assert_template 'show'\r
+ assert_no_tag :tag => 'a', :content => /Private child/\r
+ end\r
+\r
+ def test_private_subprojects_visible\r
+ @request.session[:user_id] = 2 # manager who is a member of the private subproject\r
+ get :show, :id => 'ecookbook'\r
+ assert_response :success\r
+ assert_template 'show'\r
+ assert_tag :tag => 'a', :content => /Private child/\r
+ end\r
+ \r
+ def test_settings_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects/4223/settings'},\r
+ :controller => 'projects', :action => 'settings', :id => '4223'\r
+ )\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects/4223/settings/members'},\r
+ :controller => 'projects', :action => 'settings', :id => '4223', :tab => 'members'\r
+ )\r
+ end\r
+ \r
+ def test_settings\r
+ @request.session[:user_id] = 2 # manager\r
+ get :settings, :id => 1\r
+ assert_response :success\r
+ assert_template 'settings'\r
+ end\r
+ \r
+ def test_edit\r
+ @request.session[:user_id] = 2 # manager\r
+ post :edit, :id => 1, :project => {:name => 'Test changed name',\r
+ :issue_custom_field_ids => ['']}\r
+ assert_redirected_to 'projects/ecookbook/settings'\r
+ project = Project.find(1)\r
+ assert_equal 'Test changed name', project.name\r
+ end\r
+ \r
+ def test_add_version_routing\r
+ assert_routing(\r
+ {:method => :get, :path => 'projects/64/versions/new'},\r
+ :controller => 'projects', :action => 'add_version', :id => '64'\r
+ )\r
+ assert_routing(\r
+ #TODO: use PUT\r
+ {:method => :post, :path => 'projects/64/versions/new'},\r
+ :controller => 'projects', :action => 'add_version', :id => '64'\r
+ )\r
+ end\r
+ \r
+ def test_add_issue_category_routing\r
+ assert_routing(\r
+ {:method => :get, :path => 'projects/test/categories/new'},\r
+ :controller => 'projects', :action => 'add_issue_category', :id => 'test'\r
+ )\r
+ assert_routing(\r
+ #TODO: use PUT and update form\r
+ {:method => :post, :path => 'projects/64/categories/new'},\r
+ :controller => 'projects', :action => 'add_issue_category', :id => '64'\r
+ )\r
+ end\r
+ \r
+ def test_destroy_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects/567/destroy'},\r
+ :controller => 'projects', :action => 'destroy', :id => '567'\r
+ )\r
+ assert_routing(\r
+ #TODO: use DELETE and update form\r
+ {:method => :post, :path => 'projects/64/destroy'},\r
+ :controller => 'projects', :action => 'destroy', :id => '64'\r
+ )\r
+ end\r
+ \r
+ def test_get_destroy\r
+ @request.session[:user_id] = 1 # admin\r
+ get :destroy, :id => 1\r
+ assert_response :success\r
+ assert_template 'destroy'\r
+ assert_not_nil Project.find_by_id(1)\r
+ end\r
+\r
+ def test_post_destroy\r
+ @request.session[:user_id] = 1 # admin\r
+ post :destroy, :id => 1, :confirm => 1\r
+ assert_redirected_to 'admin/projects'\r
+ assert_nil Project.find_by_id(1)\r
+ end\r
+ \r
+ def test_add_file\r
+ set_tmp_attachments_directory\r
+ @request.session[:user_id] = 2\r
+ Setting.notified_events = ['file_added']\r
+ ActionMailer::Base.deliveries.clear\r
+ \r
+ assert_difference 'Attachment.count' do\r
+ post :add_file, :id => 1, :version_id => '',\r
+ :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}\r
+ end\r
+ assert_redirected_to 'projects/ecookbook/files'\r
+ a = Attachment.find(:first, :order => 'created_on DESC')\r
+ assert_equal 'testfile.txt', a.filename\r
+ assert_equal Project.find(1), a.container\r
+\r
+ mail = ActionMailer::Base.deliveries.last\r
+ assert_kind_of TMail::Mail, mail\r
+ assert_equal "[eCookbook] New file", mail.subject\r
+ assert mail.body.include?('testfile.txt')\r
+ end\r
+ \r
+ def test_add_file_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects/33/files/new'},\r
+ :controller => 'projects', :action => 'add_file', :id => '33'\r
+ )\r
+ assert_routing(\r
+ {:method => :post, :path => '/projects/33/files/new'},\r
+ :controller => 'projects', :action => 'add_file', :id => '33'\r
+ )\r
+ end\r
+ \r
+ def test_add_version_file\r
+ set_tmp_attachments_directory\r
+ @request.session[:user_id] = 2\r
+ Setting.notified_events = ['file_added']\r
+ \r
+ assert_difference 'Attachment.count' do\r
+ post :add_file, :id => 1, :version_id => '2',\r
+ :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}\r
+ end\r
+ assert_redirected_to 'projects/ecookbook/files'\r
+ a = Attachment.find(:first, :order => 'created_on DESC')\r
+ assert_equal 'testfile.txt', a.filename\r
+ assert_equal Version.find(2), a.container\r
+ end\r
+ \r
+ def test_list_files\r
+ get :list_files, :id => 1\r
+ assert_response :success\r
+ assert_template 'list_files'\r
+ assert_not_nil assigns(:containers)\r
+ \r
+ # file attached to the project\r
+ assert_tag :a, :content => 'project_file.zip',\r
+ :attributes => { :href => '/attachments/download/8/project_file.zip' }\r
+ \r
+ # file attached to a project's version\r
+ assert_tag :a, :content => 'version_file.zip',\r
+ :attributes => { :href => '/attachments/download/9/version_file.zip' }\r
+ end\r
+\r
+ def test_list_files_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects/33/files'},\r
+ :controller => 'projects', :action => 'list_files', :id => '33'\r
+ )\r
+ end\r
+ \r
+ def test_changelog_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects/44/changelog'},\r
+ :controller => 'projects', :action => 'changelog', :id => '44'\r
+ )\r
+ end\r
+ \r
+ def test_changelog\r
+ get :changelog, :id => 1\r
+ assert_response :success\r
+ assert_template 'changelog'\r
+ assert_not_nil assigns(:versions)\r
+ end\r
+ \r
+ def test_roadmap_routing\r
+ assert_routing(\r
+ {:method => :get, :path => 'projects/33/roadmap'},\r
+ :controller => 'projects', :action => 'roadmap', :id => '33'\r
+ )\r
+ end\r
+ \r
+ def test_roadmap\r
+ get :roadmap, :id => 1\r
+ assert_response :success\r
+ assert_template 'roadmap'\r
+ assert_not_nil assigns(:versions)\r
+ # Version with no date set appears\r
+ assert assigns(:versions).include?(Version.find(3))\r
+ # Completed version doesn't appear\r
+ assert !assigns(:versions).include?(Version.find(1))\r
+ end\r
+ \r
+ def test_roadmap_with_completed_versions\r
+ get :roadmap, :id => 1, :completed => 1\r
+ assert_response :success\r
+ assert_template 'roadmap'\r
+ assert_not_nil assigns(:versions)\r
+ # Version with no date set appears\r
+ assert assigns(:versions).include?(Version.find(3))\r
+ # Completed version appears\r
+ assert assigns(:versions).include?(Version.find(1))\r
+ end\r
+ \r
+ def test_project_activity_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects/1/activity'},\r
+ :controller => 'projects', :action => 'activity', :id => '1'\r
+ )\r
+ end\r
+ \r
+ def test_project_activity_atom_routing\r
+ assert_routing(\r
+ {:method => :get, :path => '/projects/1/activity.atom'},\r
+ :controller => 'projects', :action => 'activity', :id => '1', :format => 'atom'\r
+ ) \r
+ end\r
+ \r
+ def test_project_activity\r
+ get :activity, :id => 1, :with_subprojects => 0\r
+ assert_response :success\r
+ assert_template 'activity'\r
+ assert_not_nil assigns(:events_by_day)\r
+ \r
+ assert_tag :tag => "h3", \r
+ :content => /#{2.days.ago.to_date.day}/,\r
+ :sibling => { :tag => "dl",\r
+ :child => { :tag => "dt",\r
+ :attributes => { :class => /issue-edit/ },\r
+ :child => { :tag => "a",\r
+ :content => /(#{IssueStatus.find(2).name})/,\r
+ }\r
+ }\r
+ }\r
+ end\r
+ \r
+ def test_previous_project_activity\r
+ get :activity, :id => 1, :from => 3.days.ago.to_date\r
+ assert_response :success\r
+ assert_template 'activity'\r
+ assert_not_nil assigns(:events_by_day)\r
+ \r
+ assert_tag :tag => "h3", \r
+ :content => /#{3.day.ago.to_date.day}/,\r
+ :sibling => { :tag => "dl",\r
+ :child => { :tag => "dt",\r
+ :attributes => { :class => /issue/ },\r
+ :child => { :tag => "a",\r
+ :content => /#{Issue.find(1).subject}/,\r
+ }\r
+ }\r
+ }\r
+ end\r
+ \r
+ def test_global_activity_routing\r
+ assert_routing({:method => :get, :path => '/activity'}, :controller => 'projects', :action => 'activity', :id => nil)\r
+ end\r
+ \r
+ def test_global_activity\r
+ get :activity\r
+ assert_response :success\r
+ assert_template 'activity'\r
+ assert_not_nil assigns(:events_by_day)\r
+ \r
+ assert_tag :tag => "h3", \r
+ :content => /#{5.day.ago.to_date.day}/,\r
+ :sibling => { :tag => "dl",\r
+ :child => { :tag => "dt",\r
+ :attributes => { :class => /issue/ },\r
+ :child => { :tag => "a",\r
+ :content => /#{Issue.find(5).subject}/,\r
+ }\r
+ }\r
+ }\r
+ end\r
+ \r
+ def test_user_activity\r
+ get :activity, :user_id => 2\r
+ assert_response :success\r
+ assert_template 'activity'\r
+ assert_not_nil assigns(:events_by_day)\r
+ \r
+ assert_tag :tag => "h3", \r
+ :content => /#{3.day.ago.to_date.day}/,\r
+ :sibling => { :tag => "dl",\r
+ :child => { :tag => "dt",\r
+ :attributes => { :class => /issue/ },\r
+ :child => { :tag => "a",\r
+ :content => /#{Issue.find(1).subject}/,\r
+ }\r
+ }\r
+ }\r
+ end\r
+ \r
+ def test_global_activity_atom_routing\r
+ assert_routing({:method => :get, :path => '/activity.atom'}, :controller => 'projects', :action => 'activity', :id => nil, :format => 'atom')\r
+ end\r
+ \r
+ def test_activity_atom_feed\r
+ get :activity, :format => 'atom'\r
+ assert_response :success\r
+ assert_template 'common/feed.atom.rxml'\r
+ end\r
+ \r
+ def test_archive_routing\r
+ assert_routing(\r
+ #TODO: use PUT to project path and modify form\r
+ {:method => :post, :path => 'projects/64/archive'},\r
+ :controller => 'projects', :action => 'archive', :id => '64'\r
+ )\r
+ end\r
+ \r
+ def test_archive\r
+ @request.session[:user_id] = 1 # admin\r
+ post :archive, :id => 1\r
+ assert_redirected_to 'admin/projects'\r
+ assert !Project.find(1).active?\r
+ end\r
+ \r
+ def test_unarchive_routing\r
+ assert_routing(\r
+ #TODO: use PUT to project path and modify form\r
+ {:method => :post, :path => '/projects/567/unarchive'},\r
+ :controller => 'projects', :action => 'unarchive', :id => '567'\r
+ )\r
+ end\r
+ \r
+ def test_unarchive\r
+ @request.session[:user_id] = 1 # admin\r
+ Project.find(1).archive\r
+ post :unarchive, :id => 1\r
+ assert_redirected_to 'admin/projects'\r
+ assert Project.find(1).active?\r
+ end\r
+ \r
+ def test_project_breadcrumbs_should_be_limited_to_3_ancestors\r
+ CustomField.delete_all\r
+ parent = nil\r
+ 6.times do |i|\r
+ p = Project.create!(:name => "Breadcrumbs #{i}", :identifier => "breadcrumbs-#{i}")\r
+ p.set_parent!(parent)\r
+ get :show, :id => p\r
+ assert_tag :h1, :parent => { :attributes => {:id => 'header'}},\r
+ :children => { :count => [i, 3].min,\r
+ :only => { :tag => 'a' } }\r
+ \r
+ parent = p\r
+ end\r
+ end\r
+\r
+ def test_copy_with_project\r
+ @request.session[:user_id] = 1 # admin\r
+ get :copy, :id => 1\r
+ assert_response :success\r
+ assert_template 'copy'\r
+ assert assigns(:project)\r
+ assert_equal Project.find(1).description, assigns(:project).description\r
+ assert_nil assigns(:project).id\r
+ end\r
+\r
+ def test_copy_without_project\r
+ @request.session[:user_id] = 1 # admin\r
+ get :copy\r
+ assert_response :redirect\r
+ assert_redirected_to :controller => 'admin', :action => 'projects'\r
+ end\r
+\r
+ def test_jump_should_redirect_to_active_tab\r
+ get :show, :id => 1, :jump => 'issues'\r
+ assert_redirected_to 'projects/ecookbook/issues'\r
+ end\r
+ \r
+ def test_jump_should_not_redirect_to_inactive_tab\r
+ get :show, :id => 3, :jump => 'documents'\r
+ assert_response :success\r
+ assert_template 'show'\r
+ end\r
+ \r
+ def test_jump_should_not_redirect_to_unknown_tab\r
+ get :show, :id => 3, :jump => 'foobar'\r
+ assert_response :success\r
+ assert_template 'show'\r
+ end\r
+ \r
+ # A hook that is manually registered later\r
+ class ProjectBasedTemplate < Redmine::Hook::ViewListener\r
+ def view_layouts_base_html_head(context)\r
+ # Adds a project stylesheet\r
+ stylesheet_link_tag(context[:project].identifier) if context[:project]\r
+ end\r
+ end\r
+ # Don't use this hook now\r
+ Redmine::Hook.clear_listeners\r
+ \r
+ def test_hook_response\r
+ Redmine::Hook.add_listener(ProjectBasedTemplate)\r
+ get :show, :id => 1\r
+ assert_tag :tag => 'link', :attributes => {:href => '/stylesheets/ecookbook.css'},\r
+ :parent => {:tag => 'head'}\r
+ \r
+ Redmine::Hook.clear_listeners\r
+ end\r
+end\r