##// END OF EJS Templates
Menu mapper: add support for :before, :after and :last options to #push method and add #delete method....
Jean-Philippe Lang -
r1646:7b8a4fc28bd2
parent child
Show More
@@ -1,134 +1,134
1 1 require 'redmine/access_control'
2 2 require 'redmine/menu_manager'
3 3 require 'redmine/mime_type'
4 4 require 'redmine/core_ext'
5 5 require 'redmine/themes'
6 6 require 'redmine/plugin'
7 7
8 8 begin
9 9 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
10 10 rescue LoadError
11 11 # RMagick is not available
12 12 end
13 13
14 14 REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar Git Filesystem )
15 15
16 16 # Permissions
17 17 Redmine::AccessControl.map do |map|
18 18 map.permission :view_project, {:projects => [:show, :activity]}, :public => true
19 19 map.permission :search_project, {:search => :index}, :public => true
20 20 map.permission :edit_project, {:projects => [:settings, :edit]}, :require => :member
21 21 map.permission :select_project_modules, {:projects => :modules}, :require => :member
22 22 map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy]}, :require => :member
23 23 map.permission :manage_versions, {:projects => [:settings, :add_version], :versions => [:edit, :destroy]}, :require => :member
24 24
25 25 map.project_module :issue_tracking do |map|
26 26 # Issue categories
27 27 map.permission :manage_categories, {:projects => [:settings, :add_issue_category], :issue_categories => [:edit, :destroy]}, :require => :member
28 28 # Issues
29 29 map.permission :view_issues, {:projects => [:changelog, :roadmap],
30 30 :issues => [:index, :changes, :show, :context_menu],
31 31 :versions => [:show, :status_by],
32 32 :queries => :index,
33 33 :reports => :issue_report}, :public => true
34 34 map.permission :add_issues, {:issues => :new}
35 35 map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit, :destroy_attachment]}
36 36 map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
37 37 map.permission :add_issue_notes, {:issues => [:edit, :reply]}
38 38 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
39 39 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
40 40 map.permission :move_issues, {:issues => :move}, :require => :loggedin
41 41 map.permission :delete_issues, {:issues => :destroy}, :require => :member
42 42 # Queries
43 43 map.permission :manage_public_queries, {:queries => [:new, :edit, :destroy]}, :require => :member
44 44 map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin
45 45 # Gantt & calendar
46 46 map.permission :view_gantt, :projects => :gantt
47 47 map.permission :view_calendar, :projects => :calendar
48 48 end
49 49
50 50 map.project_module :time_tracking do |map|
51 51 map.permission :log_time, {:timelog => :edit}, :require => :loggedin
52 52 map.permission :view_time_entries, :timelog => [:details, :report]
53 53 map.permission :edit_time_entries, {:timelog => [:edit, :destroy]}, :require => :member
54 54 map.permission :edit_own_time_entries, {:timelog => [:edit, :destroy]}, :require => :loggedin
55 55 end
56 56
57 57 map.project_module :news do |map|
58 58 map.permission :manage_news, {:news => [:new, :edit, :destroy, :destroy_comment]}, :require => :member
59 59 map.permission :view_news, {:news => [:index, :show]}, :public => true
60 60 map.permission :comment_news, {:news => :add_comment}
61 61 end
62 62
63 63 map.project_module :documents do |map|
64 64 map.permission :manage_documents, {:documents => [:new, :edit, :destroy, :add_attachment, :destroy_attachment]}, :require => :loggedin
65 65 map.permission :view_documents, :documents => [:index, :show, :download]
66 66 end
67 67
68 68 map.project_module :files do |map|
69 69 map.permission :manage_files, {:projects => :add_file, :versions => :destroy_file}, :require => :loggedin
70 70 map.permission :view_files, :projects => :list_files, :versions => :download
71 71 end
72 72
73 73 map.project_module :wiki do |map|
74 74 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
75 75 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
76 76 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
77 77 map.permission :view_wiki_pages, :wiki => [:index, :history, :diff, :annotate, :special]
78 78 map.permission :edit_wiki_pages, :wiki => [:edit, :preview, :add_attachment, :destroy_attachment]
79 79 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
80 80 end
81 81
82 82 map.project_module :repository do |map|
83 83 map.permission :manage_repository, {:repositories => [:edit, :destroy]}, :require => :member
84 84 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
85 85 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
86 86 end
87 87
88 88 map.project_module :boards do |map|
89 89 map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
90 90 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
91 91 map.permission :add_messages, {:messages => [:new, :reply]}
92 92 map.permission :edit_messages, {:messages => :edit}, :require => :member
93 93 map.permission :delete_messages, {:messages => :destroy}, :require => :member
94 94 end
95 95 end
96 96
97 97 Redmine::MenuManager.map :top_menu do |menu|
98 98 menu.push :home, :home_path, :html => { :class => 'home' }
99 99 menu.push :my_page, { :controller => 'my', :action => 'page' }, :html => { :class => 'mypage' }, :if => Proc.new { User.current.logged? }
100 100 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural, :html => { :class => 'projects' }
101 101 menu.push :administration, { :controller => 'admin', :action => 'index' }, :html => { :class => 'admin' }, :if => Proc.new { User.current.admin? }
102 102 menu.push :help, Redmine::Info.help_url, :html => { :class => 'help' }
103 103 end
104 104
105 105 Redmine::MenuManager.map :account_menu do |menu|
106 106 menu.push :login, :signin_path, :html => { :class => 'login' }, :if => Proc.new { !User.current.logged? }
107 107 menu.push :register, { :controller => 'account', :action => 'register' }, :html => { :class => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
108 108 menu.push :my_account, { :controller => 'my', :action => 'account' }, :html => { :class => 'myaccount' }, :if => Proc.new { User.current.logged? }
109 109 menu.push :logout, :signout_path, :html => { :class => 'logout' }, :if => Proc.new { User.current.logged? }
110 110 end
111 111
112 112 Redmine::MenuManager.map :application_menu do |menu|
113 113 # Empty
114 114 end
115 115
116 116 Redmine::MenuManager.map :project_menu do |menu|
117 117 menu.push :overview, { :controller => 'projects', :action => 'show' }
118 118 menu.push :activity, { :controller => 'projects', :action => 'activity' }
119 119 menu.push :roadmap, { :controller => 'projects', :action => 'roadmap' },
120 120 :if => Proc.new { |p| p.versions.any? }
121 121 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
122 122 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
123 123 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
124 124 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
125 125 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
126 126 menu.push :wiki, { :controller => 'wiki', :action => 'index', :page => nil },
127 127 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
128 128 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
129 129 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
130 130 menu.push :files, { :controller => 'projects', :action => 'list_files' }, :caption => :label_attachment_plural
131 131 menu.push :repository, { :controller => 'repositories', :action => 'show' },
132 132 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
133 menu.push :settings, { :controller => 'projects', :action => 'settings' }
133 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
134 134 end
@@ -1,154 +1,178
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 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 'gloc'
19 19
20 20 module Redmine
21 21 module MenuManager
22 22 module MenuController
23 23 def self.included(base)
24 24 base.extend(ClassMethods)
25 25 end
26 26
27 27 module ClassMethods
28 28 @@menu_items = Hash.new {|hash, key| hash[key] = {:default => key, :actions => {}}}
29 29 mattr_accessor :menu_items
30 30
31 31 # Set the menu item name for a controller or specific actions
32 32 # Examples:
33 33 # * menu_item :tickets # => sets the menu name to :tickets for the whole controller
34 34 # * menu_item :tickets, :only => :list # => sets the menu name to :tickets for the 'list' action only
35 35 # * menu_item :tickets, :only => [:list, :show] # => sets the menu name to :tickets for 2 actions only
36 36 #
37 37 # The default menu item name for a controller is controller_name by default
38 38 # Eg. the default menu item name for ProjectsController is :projects
39 39 def menu_item(id, options = {})
40 40 if actions = options[:only]
41 41 actions = [] << actions unless actions.is_a?(Array)
42 42 actions.each {|a| menu_items[controller_name.to_sym][:actions][a.to_sym] = id}
43 43 else
44 44 menu_items[controller_name.to_sym][:default] = id
45 45 end
46 46 end
47 47 end
48 48
49 49 def menu_items
50 50 self.class.menu_items
51 51 end
52 52
53 53 # Returns the menu item name according to the current action
54 54 def current_menu_item
55 55 menu_items[controller_name.to_sym][:actions][action_name.to_sym] ||
56 56 menu_items[controller_name.to_sym][:default]
57 57 end
58 58 end
59 59
60 60 module MenuHelper
61 61 # Returns the current menu item name
62 62 def current_menu_item
63 63 @controller.current_menu_item
64 64 end
65 65
66 66 # Renders the application main menu
67 67 def render_main_menu(project)
68 68 render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project)
69 69 end
70 70
71 71 def render_menu(menu, project=nil)
72 72 links = []
73 73 Redmine::MenuManager.allowed_items(menu, User.current, project).each do |item|
74 74 unless item.condition && !item.condition.call(project)
75 75 url = case item.url
76 76 when Hash
77 77 project.nil? ? item.url : {item.param => project}.merge(item.url)
78 78 when Symbol
79 79 send(item.url)
80 80 else
81 81 item.url
82 82 end
83 83 caption = item.caption(project)
84 84 caption = l(caption) if caption.is_a?(Symbol)
85 85 links << content_tag('li',
86 86 link_to(h(caption), url, (current_menu_item == item.name ? item.html_options.merge(:class => 'selected') : item.html_options)))
87 87 end
88 88 end
89 89 links.empty? ? nil : content_tag('ul', links.join("\n"))
90 90 end
91 91 end
92 92
93 93 class << self
94 94 def map(menu_name)
95 mapper = Mapper.new
96 yield mapper
97 95 @items ||= {}
98 @items[menu_name.to_sym] ||= []
99 @items[menu_name.to_sym] += mapper.items
96 mapper = Mapper.new(menu_name.to_sym, @items)
97 yield mapper
100 98 end
101 99
102 100 def items(menu_name)
103 101 @items[menu_name.to_sym] || []
104 102 end
105 103
106 104 def allowed_items(menu_name, user, project)
107 105 project ? items(menu_name).select {|item| user && user.allowed_to?(item.url, project)} : items(menu_name)
108 106 end
109 107 end
110 108
111 109 class Mapper
110 def initialize(menu, items)
111 items[menu] ||= []
112 @menu = menu
113 @menu_items = items[menu]
114 end
115
116 @@last_items_count = Hash.new {|h,k| h[k] = 0}
117
112 118 # Adds an item at the end of the menu. Available options:
113 119 # * param: the parameter name that is used for the project id (default is :id)
114 120 # * if: a Proc that is called before rendering the item, the item is displayed only if it returns true
115 121 # * caption that can be:
116 122 # * a localized string Symbol
117 123 # * a String
118 124 # * a Proc that can take the project as argument
125 # * before, after: specify where the menu item should be inserted (eg. :after => :activity)
126 # * last: menu item will stay at the end (eg. :last => true)
119 127 # * html_options: a hash of html options that are passed to link_to
120 128 def push(name, url, options={})
121 items << MenuItem.new(name, url, options)
129 options = options.dup
130
131 # menu item position
132 if before = options.delete(:before)
133 position = @menu_items.index {|i| i.name == before}
134 elsif after = options.delete(:after)
135 position = @menu_items.index {|i| i.name == after}
136 position += 1 unless position.nil?
137 elsif options.delete(:last)
138 position = @menu_items.size
139 @@last_items_count[@menu] += 1
140 end
141 # default position
142 position ||= @menu_items.size - @@last_items_count[@menu]
143
144 @menu_items.insert(position, MenuItem.new(name, url, options))
122 145 end
123 146
124 def items
125 @items ||= []
147 # Removes a menu item
148 def delete(name)
149 @menu_items.delete_if {|i| i.name == name}
126 150 end
127 151 end
128 152
129 153 class MenuItem
130 154 include GLoc
131 155 attr_reader :name, :url, :param, :condition, :html_options
132 156
133 157 def initialize(name, url, options)
134 158 raise "Invalid option :if for menu item '#{name}'" if options[:if] && !options[:if].respond_to?(:call)
135 159 raise "Invalid option :html for menu item '#{name}'" if options[:html] && !options[:html].is_a?(Hash)
136 160 @name = name
137 161 @url = url
138 162 @condition = options[:if]
139 163 @param = options[:param] || :id
140 164 @caption = options[:caption]
141 165 @html_options = options[:html] || {}
142 166 end
143 167
144 168 def caption(project=nil)
145 169 if @caption.is_a?(Proc)
146 170 @caption.call(project)
147 171 else
148 172 # check if localized string exists on first render (after GLoc strings are loaded)
149 173 @caption_key ||= (@caption || (l_has_string?("label_#{@name}".to_sym) ? "label_#{@name}".to_sym : @name.to_s.humanize))
150 174 end
151 175 end
152 176 end
153 177 end
154 178 end
@@ -1,315 +1,344
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 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.dirname(__FILE__) + '/../test_helper'
19 19 require 'projects_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class ProjectsController; def rescue_action(e) raise e end; end
23 23
24 24 class ProjectsControllerTest < Test::Unit::TestCase
25 25 fixtures :projects, :versions, :users, :roles, :members, :issues, :journals, :journal_details,
26 26 :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages
27 27
28 28 def setup
29 29 @controller = ProjectsController.new
30 30 @request = ActionController::TestRequest.new
31 31 @response = ActionController::TestResponse.new
32 32 @request.session[:user_id] = nil
33 33 end
34 34
35 35 def test_index
36 36 get :index
37 37 assert_response :success
38 38 assert_template 'index'
39 39 assert_not_nil assigns(:project_tree)
40 40 # Root project as hash key
41 41 assert assigns(:project_tree).keys.include?(Project.find(1))
42 42 # Subproject in corresponding value
43 43 assert assigns(:project_tree)[Project.find(1)].include?(Project.find(3))
44 44 end
45 45
46 46 def test_index_atom
47 47 get :index, :format => 'atom'
48 48 assert_response :success
49 49 assert_template 'common/feed.atom.rxml'
50 50 assert_select 'feed>title', :text => 'Redmine: Latest projects'
51 51 assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_by(User.current))
52 52 end
53 53
54 54 def test_show_by_id
55 55 get :show, :id => 1
56 56 assert_response :success
57 57 assert_template 'show'
58 58 assert_not_nil assigns(:project)
59 59 end
60 60
61 61 def test_show_by_identifier
62 62 get :show, :id => 'ecookbook'
63 63 assert_response :success
64 64 assert_template 'show'
65 65 assert_not_nil assigns(:project)
66 66 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
67 67 end
68 68
69 69 def test_private_subprojects_hidden
70 70 get :show, :id => 'ecookbook'
71 71 assert_response :success
72 72 assert_template 'show'
73 73 assert_no_tag :tag => 'a', :content => /Private child/
74 74 end
75 75
76 76 def test_private_subprojects_visible
77 77 @request.session[:user_id] = 2 # manager who is a member of the private subproject
78 78 get :show, :id => 'ecookbook'
79 79 assert_response :success
80 80 assert_template 'show'
81 81 assert_tag :tag => 'a', :content => /Private child/
82 82 end
83 83
84 84 def test_settings
85 85 @request.session[:user_id] = 2 # manager
86 86 get :settings, :id => 1
87 87 assert_response :success
88 88 assert_template 'settings'
89 89 end
90 90
91 91 def test_edit
92 92 @request.session[:user_id] = 2 # manager
93 93 post :edit, :id => 1, :project => {:name => 'Test changed name',
94 94 :issue_custom_field_ids => ['']}
95 95 assert_redirected_to 'projects/settings/ecookbook'
96 96 project = Project.find(1)
97 97 assert_equal 'Test changed name', project.name
98 98 end
99 99
100 100 def test_get_destroy
101 101 @request.session[:user_id] = 1 # admin
102 102 get :destroy, :id => 1
103 103 assert_response :success
104 104 assert_template 'destroy'
105 105 assert_not_nil Project.find_by_id(1)
106 106 end
107 107
108 108 def test_post_destroy
109 109 @request.session[:user_id] = 1 # admin
110 110 post :destroy, :id => 1, :confirm => 1
111 111 assert_redirected_to 'admin/projects'
112 112 assert_nil Project.find_by_id(1)
113 113 end
114 114
115 115 def test_list_files
116 116 get :list_files, :id => 1
117 117 assert_response :success
118 118 assert_template 'list_files'
119 119 assert_not_nil assigns(:versions)
120 120 end
121 121
122 122 def test_changelog
123 123 get :changelog, :id => 1
124 124 assert_response :success
125 125 assert_template 'changelog'
126 126 assert_not_nil assigns(:versions)
127 127 end
128 128
129 129 def test_roadmap
130 130 get :roadmap, :id => 1
131 131 assert_response :success
132 132 assert_template 'roadmap'
133 133 assert_not_nil assigns(:versions)
134 134 # Version with no date set appears
135 135 assert assigns(:versions).include?(Version.find(3))
136 136 # Completed version doesn't appear
137 137 assert !assigns(:versions).include?(Version.find(1))
138 138 end
139 139
140 140 def test_roadmap_with_completed_versions
141 141 get :roadmap, :id => 1, :completed => 1
142 142 assert_response :success
143 143 assert_template 'roadmap'
144 144 assert_not_nil assigns(:versions)
145 145 # Version with no date set appears
146 146 assert assigns(:versions).include?(Version.find(3))
147 147 # Completed version appears
148 148 assert assigns(:versions).include?(Version.find(1))
149 149 end
150 150
151 151 def test_project_activity
152 152 get :activity, :id => 1, :with_subprojects => 0
153 153 assert_response :success
154 154 assert_template 'activity'
155 155 assert_not_nil assigns(:events_by_day)
156 156 assert_not_nil assigns(:events)
157 157
158 158 # subproject issue not included by default
159 159 assert !assigns(:events).include?(Issue.find(5))
160 160
161 161 assert_tag :tag => "h3",
162 162 :content => /#{2.days.ago.to_date.day}/,
163 163 :sibling => { :tag => "dl",
164 164 :child => { :tag => "dt",
165 165 :attributes => { :class => /issue-edit/ },
166 166 :child => { :tag => "a",
167 167 :content => /(#{IssueStatus.find(2).name})/,
168 168 }
169 169 }
170 170 }
171 171
172 172 get :activity, :id => 1, :from => 3.days.ago.to_date
173 173 assert_response :success
174 174 assert_template 'activity'
175 175 assert_not_nil assigns(:events_by_day)
176 176
177 177 assert_tag :tag => "h3",
178 178 :content => /#{3.day.ago.to_date.day}/,
179 179 :sibling => { :tag => "dl",
180 180 :child => { :tag => "dt",
181 181 :attributes => { :class => /issue/ },
182 182 :child => { :tag => "a",
183 183 :content => /#{Issue.find(1).subject}/,
184 184 }
185 185 }
186 186 }
187 187 end
188 188
189 189 def test_activity_with_subprojects
190 190 get :activity, :id => 1, :with_subprojects => 1
191 191 assert_response :success
192 192 assert_template 'activity'
193 193 assert_not_nil assigns(:events)
194 194
195 195 assert assigns(:events).include?(Issue.find(1))
196 196 assert !assigns(:events).include?(Issue.find(4))
197 197 # subproject issue
198 198 assert assigns(:events).include?(Issue.find(5))
199 199 end
200 200
201 201 def test_global_activity_anonymous
202 202 get :activity
203 203 assert_response :success
204 204 assert_template 'activity'
205 205 assert_not_nil assigns(:events)
206 206
207 207 assert assigns(:events).include?(Issue.find(1))
208 208 # Issue of a private project
209 209 assert !assigns(:events).include?(Issue.find(4))
210 210 end
211 211
212 212 def test_global_activity_logged_user
213 213 @request.session[:user_id] = 2 # manager
214 214 get :activity
215 215 assert_response :success
216 216 assert_template 'activity'
217 217 assert_not_nil assigns(:events)
218 218
219 219 assert assigns(:events).include?(Issue.find(1))
220 220 # Issue of a private project the user belongs to
221 221 assert assigns(:events).include?(Issue.find(4))
222 222 end
223 223
224 224
225 225 def test_global_activity_with_all_types
226 226 get :activity, :show_issues => 1, :show_news => 1, :show_files => 1, :show_documents => 1, :show_changesets => 1, :show_wiki_pages => 1, :show_messages => 1
227 227 assert_response :success
228 228 assert_template 'activity'
229 229 assert_not_nil assigns(:events)
230 230
231 231 assert assigns(:events).include?(Issue.find(1))
232 232 assert !assigns(:events).include?(Issue.find(4))
233 233 assert assigns(:events).include?(Message.find(5))
234 234 end
235 235
236 236 def test_calendar
237 237 get :calendar, :id => 1
238 238 assert_response :success
239 239 assert_template 'calendar'
240 240 assert_not_nil assigns(:calendar)
241 241 end
242 242
243 243 def test_calendar_with_subprojects_should_not_show_private_subprojects
244 244 get :calendar, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
245 245 assert_response :success
246 246 assert_template 'calendar'
247 247 assert_not_nil assigns(:calendar)
248 248 assert_no_tag :tag => 'a', :content => /#6/
249 249 end
250 250
251 251 def test_calendar_with_subprojects_should_show_private_subprojects
252 252 @request.session[:user_id] = 2
253 253 get :calendar, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
254 254 assert_response :success
255 255 assert_template 'calendar'
256 256 assert_not_nil assigns(:calendar)
257 257 assert_tag :tag => 'a', :content => /#6/
258 258 end
259 259
260 260 def test_gantt
261 261 get :gantt, :id => 1
262 262 assert_response :success
263 263 assert_template 'gantt.rhtml'
264 264 events = assigns(:events)
265 265 assert_not_nil events
266 266 # Issue with start and due dates
267 267 i = Issue.find(1)
268 268 assert_not_nil i.due_date
269 269 assert events.include?(Issue.find(1))
270 270 # Issue with without due date but targeted to a version with date
271 271 i = Issue.find(2)
272 272 assert_nil i.due_date
273 273 assert events.include?(i)
274 274 end
275 275
276 276 def test_gantt_with_subprojects_should_not_show_private_subprojects
277 277 get :gantt, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
278 278 assert_response :success
279 279 assert_template 'gantt.rhtml'
280 280 assert_not_nil assigns(:events)
281 281 assert_no_tag :tag => 'a', :content => /#6/
282 282 end
283 283
284 284 def test_gantt_with_subprojects_should_show_private_subprojects
285 285 @request.session[:user_id] = 2
286 286 get :gantt, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
287 287 assert_response :success
288 288 assert_template 'gantt.rhtml'
289 289 assert_not_nil assigns(:events)
290 290 assert_tag :tag => 'a', :content => /#6/
291 291 end
292 292
293 293 def test_gantt_export_to_pdf
294 294 get :gantt, :id => 1, :format => 'pdf'
295 295 assert_response :success
296 296 assert_template 'gantt.rfpdf'
297 297 assert_equal 'application/pdf', @response.content_type
298 298 assert_not_nil assigns(:events)
299 299 end
300 300
301 301 def test_archive
302 302 @request.session[:user_id] = 1 # admin
303 303 post :archive, :id => 1
304 304 assert_redirected_to 'admin/projects'
305 305 assert !Project.find(1).active?
306 306 end
307 307
308 308 def test_unarchive
309 309 @request.session[:user_id] = 1 # admin
310 310 Project.find(1).archive
311 311 post :unarchive, :id => 1
312 312 assert_redirected_to 'admin/projects'
313 313 assert Project.find(1).active?
314 314 end
315
316 def test_project_menu
317 assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do
318 Redmine::MenuManager.map :project_menu do |menu|
319 menu.push :foo, { :controller => 'projects', :action => 'show' }, :cation => 'Foo'
320 menu.push :bar, { :controller => 'projects', :action => 'show' }, :before => :activity
321 menu.push :hello, { :controller => 'projects', :action => 'show' }, :caption => Proc.new {|p| p.name.upcase }, :after => :bar
322 end
323
324 get :show, :id => 1
325 assert_tag :div, :attributes => { :id => 'main-menu' },
326 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Foo' } }
327
328 assert_tag :div, :attributes => { :id => 'main-menu' },
329 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Bar' },
330 :before => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK' } } }
331
332 assert_tag :div, :attributes => { :id => 'main-menu' },
333 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK' },
334 :before => { :tag => 'li', :child => { :tag => 'a', :content => 'Activity' } } }
335
336 # Remove the menu items
337 Redmine::MenuManager.map :project_menu do |menu|
338 menu.delete :foo
339 menu.delete :bar
340 menu.delete :hello
341 end
342 end
343 end
315 344 end
General Comments 0
You need to be logged in to leave comments. Login now