##// END OF EJS Templates
Merged r2894 from trunk....
Jean-Philippe Lang -
r2882:4be1c1ad5861
parent child
Show More
@@ -1,71 +1,71
1 1 <div class="contextual">
2 2 <%= link_to(l(:button_edit), {:controller => 'users', :action => 'edit', :id => @user}, :class => 'icon icon-edit') if User.current.admin? %>
3 3 </div>
4 4
5 5 <h2><%= avatar @user %> <%=h @user.name %></h2>
6 6
7 7 <div class="splitcontentleft">
8 8 <ul>
9 9 <% unless @user.pref.hide_mail %>
10 10 <li><%=l(:field_mail)%>: <%= mail_to(h(@user.mail), nil, :encode => 'javascript') %></li>
11 11 <% end %>
12 12 <% for custom_value in @custom_values %>
13 <% if !custom_value.value.empty? %>
13 <% if !custom_value.value.blank? %>
14 14 <li><%= custom_value.custom_field.name%>: <%=h show_value(custom_value) %></li>
15 15 <% end %>
16 16 <% end %>
17 17 <li><%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %></li>
18 18 <% unless @user.last_login_on.nil? %>
19 19 <li><%=l(:field_last_login_on)%>: <%= format_date(@user.last_login_on) %></li>
20 20 <% end %>
21 21 </ul>
22 22
23 23 <% unless @memberships.empty? %>
24 24 <h3><%=l(:label_project_plural)%></h3>
25 25 <ul>
26 26 <% for membership in @memberships %>
27 27 <li><%= link_to(h(membership.project.name), :controller => 'projects', :action => 'show', :id => membership.project) %>
28 28 (<%=h membership.role.name %>, <%= format_date(membership.created_on) %>)</li>
29 29 <% end %>
30 30 </ul>
31 31 <% end %>
32 32 <%= call_hook :view_account_left_bottom, :user => @user %>
33 33 </div>
34 34
35 35 <div class="splitcontentright">
36 36
37 37 <% unless @events_by_day.empty? %>
38 38 <h3><%= link_to l(:label_activity), :controller => 'projects', :action => 'activity', :user_id => @user, :from => @events_by_day.keys.first %></h3>
39 39
40 40 <p>
41 41 <%=l(:label_reported_issues)%>: <%= Issue.count(:conditions => ["author_id=?", @user.id]) %>
42 42 </p>
43 43
44 44 <div id="activity">
45 45 <% @events_by_day.keys.sort.reverse.each do |day| %>
46 46 <h4><%= format_activity_day(day) %></h4>
47 47 <dl>
48 48 <% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%>
49 49 <dt class="<%= e.event_type %>">
50 50 <span class="time"><%= format_time(e.event_datetime, false) %></span>
51 51 <%= content_tag('span', h(e.project), :class => 'project') %>
52 52 <%= link_to format_activity_title(e.event_title), e.event_url %></dt>
53 53 <dd><span class="description"><%= format_activity_description(e.event_description) %></span></dd>
54 54 <% end -%>
55 55 </dl>
56 56 <% end -%>
57 57 </div>
58 58
59 59 <p class="other-formats">
60 60 <%= l(:label_export_to) %>
61 61 <%= link_to 'Atom', {:controller => 'projects', :action => 'activity', :user_id => @user, :format => :atom, :key => User.current.rss_key}, :class => 'feed' %>
62 62 </p>
63 63
64 64 <% content_for :header_tags do %>
65 65 <%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :user_id => @user, :format => :atom, :key => User.current.rss_key) %>
66 66 <% end %>
67 67 <% end %>
68 68 <%= call_hook :view_account_right_bottom, :user => @user %>
69 69 </div>
70 70
71 71 <% html_title @user.name %>
@@ -1,82 +1,82
1 1 <h2><%=l(:label_overview)%></h2>
2 2
3 3 <div class="splitcontentleft">
4 4 <%= textilizable @project.description %>
5 5 <ul>
6 6 <% unless @project.homepage.blank? %><li><%=l(:field_homepage)%>: <%= link_to(h(@project.homepage), @project.homepage) %></li><% end %>
7 7 <% if @subprojects.any? %>
8 8 <li><%=l(:label_subproject_plural)%>: <%= @subprojects.collect{|p| link_to(h(p.name), :action => 'show', :id => p)}.join(", ") %></li>
9 9 <% end %>
10 10 <% if @project.parent %>
11 11 <li><%=l(:field_parent)%>: <%= link_to h(@project.parent.name), :controller => 'projects', :action => 'show', :id => @project.parent %></li>
12 12 <% end %>
13 13 <% @project.custom_values.each do |custom_value| %>
14 <% if !custom_value.value.empty? %>
14 <% if !custom_value.value.blank? %>
15 15 <li><%= custom_value.custom_field.name%>: <%=h show_value(custom_value) %></li>
16 16 <% end %>
17 17 <% end %>
18 18 </ul>
19 19
20 20 <% if User.current.allowed_to?(:view_issues, @project) %>
21 21 <div class="box">
22 22 <h3 class="icon22 icon22-tracker"><%=l(:label_issue_tracking)%></h3>
23 23 <ul>
24 24 <% for tracker in @trackers %>
25 25 <li><%= link_to tracker.name, :controller => 'issues', :action => 'index', :project_id => @project,
26 26 :set_filter => 1,
27 27 "tracker_id" => tracker.id %>:
28 28 <%= @open_issues_by_tracker[tracker] || 0 %> <%= lwr(:label_open_issues, @open_issues_by_tracker[tracker] || 0) %>
29 29 <%= l(:label_on) %> <%= @total_issues_by_tracker[tracker] || 0 %></li>
30 30 <% end %>
31 31 </ul>
32 32 <p><%= link_to l(:label_issue_view_all), :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1 %></p>
33 33 </div>
34 34 <% end %>
35 35 <%= call_hook(:view_projects_show_left, :project => @project) %>
36 36 </div>
37 37
38 38 <div class="splitcontentright">
39 39 <% if @members_by_role.any? %>
40 40 <div class="box">
41 41 <h3 class="icon22 icon22-users"><%=l(:label_member_plural)%></h3>
42 42 <p><% @members_by_role.keys.sort.each do |role| %>
43 43 <%= role.name %>:
44 44 <%= @members_by_role[role].collect(&:user).sort.collect{|u| link_to_user u}.join(", ") %>
45 45 <br />
46 46 <% end %></p>
47 47 </div>
48 48 <% end %>
49 49
50 50 <% if @news.any? && authorize_for('news', 'index') %>
51 51 <div class="box">
52 52 <h3><%=l(:label_news_latest)%></h3>
53 53 <%= render :partial => 'news/news', :collection => @news %>
54 54 <p><%= link_to l(:label_news_view_all), :controller => 'news', :action => 'index', :project_id => @project %></p>
55 55 </div>
56 56 <% end %>
57 57 <%= call_hook(:view_projects_show_right, :project => @project) %>
58 58 </div>
59 59
60 60 <% content_for :sidebar do %>
61 61 <% planning_links = []
62 62 planning_links << link_to_if_authorized(l(:label_calendar), :controller => 'issues', :action => 'calendar', :project_id => @project)
63 63 planning_links << link_to_if_authorized(l(:label_gantt), :controller => 'issues', :action => 'gantt', :project_id => @project)
64 64 planning_links.compact!
65 65 unless planning_links.empty? %>
66 66 <h3><%= l(:label_planning) %></h3>
67 67 <p><%= planning_links.join(' | ') %></p>
68 68 <% end %>
69 69
70 70 <% if @total_hours && User.current.allowed_to?(:view_time_entries, @project) %>
71 71 <h3><%= l(:label_spent_time) %></h3>
72 72 <p><span class="icon icon-time"><%= lwr(:label_f_hour, @total_hours) %></span></p>
73 73 <p><%= link_to(l(:label_details), {:controller => 'timelog', :action => 'details', :project_id => @project}) %> |
74 74 <%= link_to(l(:label_report), {:controller => 'timelog', :action => 'report', :project_id => @project}) %></p>
75 75 <% end %>
76 76 <% end %>
77 77
78 78 <% content_for :header_tags do %>
79 79 <%= auto_discovery_link_tag(:atom, {:action => 'activity', :id => @project, :format => 'atom', :key => User.current.rss_key}) %>
80 80 <% end %>
81 81
82 82 <% html_title(l(:label_overview)) -%>
@@ -1,89 +1,101
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 'account_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class AccountController; def rescue_action(e) raise e end; end
23 23
24 24 class AccountControllerTest < Test::Unit::TestCase
25 25 fixtures :users
26 26
27 27 def setup
28 28 @controller = AccountController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_show
35 35 get :show, :id => 2
36 36 assert_response :success
37 37 assert_template 'show'
38 38 assert_not_nil assigns(:user)
39 39 end
40
41 def test_show_should_not_fail_when_custom_values_are_nil
42 user = User.find(2)
43
44 # Create a custom field to illustrate the issue
45 custom_field = CustomField.create!(:name => 'Testing', :field_format => 'text')
46 custom_value = user.custom_values.build(:custom_field => custom_field).save!
47
48 get :show, :id => 2
49 assert_response :success
50 end
40 51
52
41 53 def test_show_inactive
42 54 get :show, :id => 5
43 55 assert_response 404
44 56 assert_nil assigns(:user)
45 57 end
46 58
47 59 def test_show_should_not_reveal_users_with_no_visible_activity_or_project
48 60 get :show, :id => 9
49 61 assert_response 404
50 62 end
51 63
52 64 def test_login_should_redirect_to_back_url_param
53 65 # request.uri is "test.host" in test environment
54 66 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http%3A%2F%2Ftest.host%2Fissues%2Fshow%2F1'
55 67 assert_redirected_to '/issues/show/1'
56 68 end
57 69
58 70 def test_login_should_not_redirect_to_another_host
59 71 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http%3A%2F%2Ftest.foo%2Ffake'
60 72 assert_redirected_to '/my/page'
61 73 end
62 74
63 75 def test_login_with_wrong_password
64 76 post :login, :username => 'admin', :password => 'bad'
65 77 assert_response :success
66 78 assert_template 'login'
67 79 assert_tag 'div',
68 80 :attributes => { :class => "flash error" },
69 81 :content => /Invalid user or password/
70 82 end
71 83
72 84 def test_autologin
73 85 Setting.autologin = "7"
74 86 Token.delete_all
75 87 post :login, :username => 'admin', :password => 'admin', :autologin => 1
76 88 assert_redirected_to 'my/page'
77 89 token = Token.find :first
78 90 assert_not_nil token
79 91 assert_equal User.find_by_login('admin'), token.user
80 92 assert_equal 'autologin', token.action
81 93 end
82 94
83 95 def test_logout
84 96 @request.session[:user_id] = 2
85 97 get :logout
86 98 assert_redirected_to ''
87 99 assert_nil @request.session[:user_id]
88 100 end
89 101 end
@@ -1,357 +1,367
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2008 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 :attachments
28 28
29 29 def setup
30 30 @controller = ProjectsController.new
31 31 @request = ActionController::TestRequest.new
32 32 @response = ActionController::TestResponse.new
33 33 @request.session[:user_id] = nil
34 34 Setting.default_language = 'en'
35 35 end
36 36
37 37 def test_index
38 38 get :index
39 39 assert_response :success
40 40 assert_template 'index'
41 41 assert_not_nil assigns(:project_tree)
42 42 # Root project as hash key
43 43 assert assigns(:project_tree).keys.include?(Project.find(1))
44 44 # Subproject in corresponding value
45 45 assert assigns(:project_tree)[Project.find(1)].include?(Project.find(3))
46 46 end
47 47
48 48 def test_index_atom
49 49 get :index, :format => 'atom'
50 50 assert_response :success
51 51 assert_template 'common/feed.atom.rxml'
52 52 assert_select 'feed>title', :text => 'Redmine: Latest projects'
53 53 assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_by(User.current))
54 54 end
55 55
56 56 def test_show_by_id
57 57 get :show, :id => 1
58 58 assert_response :success
59 59 assert_template 'show'
60 60 assert_not_nil assigns(:project)
61 61 end
62 62
63 63 def test_show_by_identifier
64 64 get :show, :id => 'ecookbook'
65 65 assert_response :success
66 66 assert_template 'show'
67 67 assert_not_nil assigns(:project)
68 68 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
69 69 end
70 70
71 def test_show_should_not_fail_when_custom_values_are_nil
72 project = Project.find_by_identifier('ecookbook')
73 project.custom_values.first.update_attribute(:value, nil)
74 get :show, :id => 'ecookbook'
75 assert_response :success
76 assert_template 'show'
77 assert_not_nil assigns(:project)
78 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
79 end
80
71 81 def test_private_subprojects_hidden
72 82 get :show, :id => 'ecookbook'
73 83 assert_response :success
74 84 assert_template 'show'
75 85 assert_no_tag :tag => 'a', :content => /Private child/
76 86 end
77 87
78 88 def test_private_subprojects_visible
79 89 @request.session[:user_id] = 2 # manager who is a member of the private subproject
80 90 get :show, :id => 'ecookbook'
81 91 assert_response :success
82 92 assert_template 'show'
83 93 assert_tag :tag => 'a', :content => /Private child/
84 94 end
85 95
86 96 def test_settings
87 97 @request.session[:user_id] = 2 # manager
88 98 get :settings, :id => 1
89 99 assert_response :success
90 100 assert_template 'settings'
91 101 end
92 102
93 103 def test_edit
94 104 @request.session[:user_id] = 2 # manager
95 105 post :edit, :id => 1, :project => {:name => 'Test changed name',
96 106 :issue_custom_field_ids => ['']}
97 107 assert_redirected_to 'projects/settings/ecookbook'
98 108 project = Project.find(1)
99 109 assert_equal 'Test changed name', project.name
100 110 end
101 111
102 112 def test_get_destroy
103 113 @request.session[:user_id] = 1 # admin
104 114 get :destroy, :id => 1
105 115 assert_response :success
106 116 assert_template 'destroy'
107 117 assert_not_nil Project.find_by_id(1)
108 118 end
109 119
110 120 def test_post_destroy
111 121 @request.session[:user_id] = 1 # admin
112 122 post :destroy, :id => 1, :confirm => 1
113 123 assert_redirected_to 'admin/projects'
114 124 assert_nil Project.find_by_id(1)
115 125 end
116 126
117 127 def test_add_file
118 128 set_tmp_attachments_directory
119 129 @request.session[:user_id] = 2
120 130 Setting.notified_events = ['file_added']
121 131 ActionMailer::Base.deliveries.clear
122 132
123 133 assert_difference 'Attachment.count' do
124 134 post :add_file, :id => 1, :version_id => '',
125 135 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
126 136 end
127 137 assert_redirected_to 'projects/list_files/ecookbook'
128 138 a = Attachment.find(:first, :order => 'created_on DESC')
129 139 assert_equal 'testfile.txt', a.filename
130 140 assert_equal Project.find(1), a.container
131 141
132 142 mail = ActionMailer::Base.deliveries.last
133 143 assert_kind_of TMail::Mail, mail
134 144 assert_equal "[eCookbook] New file", mail.subject
135 145 assert mail.body.include?('testfile.txt')
136 146 end
137 147
138 148 def test_add_version_file
139 149 set_tmp_attachments_directory
140 150 @request.session[:user_id] = 2
141 151 Setting.notified_events = ['file_added']
142 152
143 153 assert_difference 'Attachment.count' do
144 154 post :add_file, :id => 1, :version_id => '2',
145 155 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
146 156 end
147 157 assert_redirected_to 'projects/list_files/ecookbook'
148 158 a = Attachment.find(:first, :order => 'created_on DESC')
149 159 assert_equal 'testfile.txt', a.filename
150 160 assert_equal Version.find(2), a.container
151 161 end
152 162
153 163 def test_list_files
154 164 get :list_files, :id => 1
155 165 assert_response :success
156 166 assert_template 'list_files'
157 167 assert_not_nil assigns(:containers)
158 168
159 169 # file attached to the project
160 170 assert_tag :a, :content => 'project_file.zip',
161 171 :attributes => { :href => '/attachments/download/8/project_file.zip' }
162 172
163 173 # file attached to a project's version
164 174 assert_tag :a, :content => 'version_file.zip',
165 175 :attributes => { :href => '/attachments/download/9/version_file.zip' }
166 176 end
167 177
168 178 def test_changelog
169 179 get :changelog, :id => 1
170 180 assert_response :success
171 181 assert_template 'changelog'
172 182 assert_not_nil assigns(:versions)
173 183 end
174 184
175 185 def test_roadmap
176 186 get :roadmap, :id => 1
177 187 assert_response :success
178 188 assert_template 'roadmap'
179 189 assert_not_nil assigns(:versions)
180 190 # Version with no date set appears
181 191 assert assigns(:versions).include?(Version.find(3))
182 192 # Completed version doesn't appear
183 193 assert !assigns(:versions).include?(Version.find(1))
184 194 end
185 195
186 196 def test_roadmap_with_completed_versions
187 197 get :roadmap, :id => 1, :completed => 1
188 198 assert_response :success
189 199 assert_template 'roadmap'
190 200 assert_not_nil assigns(:versions)
191 201 # Version with no date set appears
192 202 assert assigns(:versions).include?(Version.find(3))
193 203 # Completed version appears
194 204 assert assigns(:versions).include?(Version.find(1))
195 205 end
196 206
197 207 def test_project_activity
198 208 get :activity, :id => 1, :with_subprojects => 0
199 209 assert_response :success
200 210 assert_template 'activity'
201 211 assert_not_nil assigns(:events_by_day)
202 212
203 213 assert_tag :tag => "h3",
204 214 :content => /#{2.days.ago.to_date.day}/,
205 215 :sibling => { :tag => "dl",
206 216 :child => { :tag => "dt",
207 217 :attributes => { :class => /issue-edit/ },
208 218 :child => { :tag => "a",
209 219 :content => /(#{IssueStatus.find(2).name})/,
210 220 }
211 221 }
212 222 }
213 223 end
214 224
215 225 def test_previous_project_activity
216 226 get :activity, :id => 1, :from => 3.days.ago.to_date
217 227 assert_response :success
218 228 assert_template 'activity'
219 229 assert_not_nil assigns(:events_by_day)
220 230
221 231 assert_tag :tag => "h3",
222 232 :content => /#{3.day.ago.to_date.day}/,
223 233 :sibling => { :tag => "dl",
224 234 :child => { :tag => "dt",
225 235 :attributes => { :class => /issue/ },
226 236 :child => { :tag => "a",
227 237 :content => /#{Issue.find(1).subject}/,
228 238 }
229 239 }
230 240 }
231 241 end
232 242
233 243 def test_global_activity
234 244 get :activity
235 245 assert_response :success
236 246 assert_template 'activity'
237 247 assert_not_nil assigns(:events_by_day)
238 248
239 249 assert_tag :tag => "h3",
240 250 :content => /#{5.day.ago.to_date.day}/,
241 251 :sibling => { :tag => "dl",
242 252 :child => { :tag => "dt",
243 253 :attributes => { :class => /issue/ },
244 254 :child => { :tag => "a",
245 255 :content => /#{Issue.find(5).subject}/,
246 256 }
247 257 }
248 258 }
249 259 end
250 260
251 261 def test_user_activity
252 262 get :activity, :user_id => 2
253 263 assert_response :success
254 264 assert_template 'activity'
255 265 assert_not_nil assigns(:events_by_day)
256 266
257 267 assert_tag :tag => "h3",
258 268 :content => /#{3.day.ago.to_date.day}/,
259 269 :sibling => { :tag => "dl",
260 270 :child => { :tag => "dt",
261 271 :attributes => { :class => /issue/ },
262 272 :child => { :tag => "a",
263 273 :content => /#{Issue.find(1).subject}/,
264 274 }
265 275 }
266 276 }
267 277 end
268 278
269 279 def test_activity_atom_feed
270 280 get :activity, :format => 'atom'
271 281 assert_response :success
272 282 assert_template 'common/feed.atom.rxml'
273 283 end
274 284
275 285 def test_archive
276 286 @request.session[:user_id] = 1 # admin
277 287 post :archive, :id => 1
278 288 assert_redirected_to 'admin/projects'
279 289 assert !Project.find(1).active?
280 290 end
281 291
282 292 def test_unarchive
283 293 @request.session[:user_id] = 1 # admin
284 294 Project.find(1).archive
285 295 post :unarchive, :id => 1
286 296 assert_redirected_to 'admin/projects'
287 297 assert Project.find(1).active?
288 298 end
289 299
290 300 def test_jump_should_redirect_to_active_tab
291 301 get :show, :id => 1, :jump => 'issues'
292 302 assert_redirected_to 'projects/ecookbook/issues'
293 303 end
294 304
295 305 def test_jump_should_not_redirect_to_inactive_tab
296 306 get :show, :id => 3, :jump => 'documents'
297 307 assert_response :success
298 308 assert_template 'show'
299 309 end
300 310
301 311 def test_jump_should_not_redirect_to_unknown_tab
302 312 get :show, :id => 3, :jump => 'foobar'
303 313 assert_response :success
304 314 assert_template 'show'
305 315 end
306 316
307 317 def test_project_menu
308 318 assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do
309 319 Redmine::MenuManager.map :project_menu do |menu|
310 320 menu.push :foo, { :controller => 'projects', :action => 'show' }, :cation => 'Foo'
311 321 menu.push :bar, { :controller => 'projects', :action => 'show' }, :before => :activity
312 322 menu.push :hello, { :controller => 'projects', :action => 'show' }, :caption => Proc.new {|p| p.name.upcase }, :after => :bar
313 323 end
314 324
315 325 get :show, :id => 1
316 326 assert_tag :div, :attributes => { :id => 'main-menu' },
317 327 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Foo',
318 328 :attributes => { :class => 'foo' } } }
319 329
320 330 assert_tag :div, :attributes => { :id => 'main-menu' },
321 331 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Bar',
322 332 :attributes => { :class => 'bar' } },
323 333 :before => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK' } } }
324 334
325 335 assert_tag :div, :attributes => { :id => 'main-menu' },
326 336 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK',
327 337 :attributes => { :class => 'hello' } },
328 338 :before => { :tag => 'li', :child => { :tag => 'a', :content => 'Activity' } } }
329 339
330 340 # Remove the menu items
331 341 Redmine::MenuManager.map :project_menu do |menu|
332 342 menu.delete :foo
333 343 menu.delete :bar
334 344 menu.delete :hello
335 345 end
336 346 end
337 347 end
338 348
339 349 # A hook that is manually registered later
340 350 class ProjectBasedTemplate < Redmine::Hook::ViewListener
341 351 def view_layouts_base_html_head(context)
342 352 # Adds a project stylesheet
343 353 stylesheet_link_tag(context[:project].identifier) if context[:project]
344 354 end
345 355 end
346 356 # Don't use this hook now
347 357 Redmine::Hook.clear_listeners
348 358
349 359 def test_hook_response
350 360 Redmine::Hook.add_listener(ProjectBasedTemplate)
351 361 get :show, :id => 1
352 362 assert_tag :tag => 'link', :attributes => {:href => '/stylesheets/ecookbook.css'},
353 363 :parent => {:tag => 'head'}
354 364
355 365 Redmine::Hook.clear_listeners
356 366 end
357 367 end
General Comments 0
You need to be logged in to leave comments. Login now