##// END OF EJS Templates
Fixed: Custom values with a nil value cause error on (project|account)/show (#3705)....
Jean-Philippe Lang -
r2780:52a6b0a21e5e
parent child
Show More
@@ -1,70 +1,70
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><%=h 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.roles.sort.collect(&:to_s).join(', ') %>, <%= 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', :id => nil, :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 <% other_formats_links do |f| %>
60 60 <%= f.link_to 'Atom', :url => {:controller => 'projects', :action => 'activity', :id => nil, :user_id => @user, :key => User.current.rss_key} %>
61 61 <% end %>
62 62
63 63 <% content_for :header_tags do %>
64 64 <%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :user_id => @user, :format => :atom, :key => User.current.rss_key) %>
65 65 <% end %>
66 66 <% end %>
67 67 <%= call_hook :view_account_right_bottom, :user => @user %>
68 68 </div>
69 69
70 70 <% html_title @user.name %>
@@ -1,80 +1,80
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)%>:
9 9 <%= @subprojects.collect{|p| link_to(h(p), :action => 'show', :id => p)}.join(", ") %></li>
10 10 <% end %>
11 11 <% @project.custom_values.each do |custom_value| %>
12 <% if !custom_value.value.empty? %>
12 <% if !custom_value.value.blank? %>
13 13 <li><%= custom_value.custom_field.name%>: <%=h show_value(custom_value) %></li>
14 14 <% end %>
15 15 <% end %>
16 16 </ul>
17 17
18 18 <% if User.current.allowed_to?(:view_issues, @project) %>
19 19 <div class="box">
20 20 <h3 class="icon22 icon22-tracker"><%=l(:label_issue_tracking)%></h3>
21 21 <ul>
22 22 <% for tracker in @trackers %>
23 23 <li><%= link_to tracker.name, :controller => 'issues', :action => 'index', :project_id => @project,
24 24 :set_filter => 1,
25 25 "tracker_id" => tracker.id %>:
26 26 <%= l(:label_x_open_issues_abbr_on_total, :count => @open_issues_by_tracker[tracker].to_i,
27 27 :total => @total_issues_by_tracker[tracker].to_i) %>
28 28 </li>
29 29 <% end %>
30 30 </ul>
31 31 <p><%= link_to l(:label_issue_view_all), :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1 %></p>
32 32 </div>
33 33 <% end %>
34 34 <%= call_hook(:view_projects_show_left, :project => @project) %>
35 35 </div>
36 36
37 37 <div class="splitcontentright">
38 38 <% if @users_by_role.any? %>
39 39 <div class="box">
40 40 <h3 class="icon22 icon22-users"><%=l(:label_member_plural)%></h3>
41 41 <p><% @users_by_role.keys.sort.each do |role| %>
42 42 <%=h role %>: <%= @users_by_role[role].sort.collect{|u| link_to_user u}.join(", ") %><br />
43 43 <% end %></p>
44 44 </div>
45 45 <% end %>
46 46
47 47 <% if @news.any? && authorize_for('news', 'index') %>
48 48 <div class="box">
49 49 <h3><%=l(:label_news_latest)%></h3>
50 50 <%= render :partial => 'news/news', :collection => @news %>
51 51 <p><%= link_to l(:label_news_view_all), :controller => 'news', :action => 'index', :project_id => @project %></p>
52 52 </div>
53 53 <% end %>
54 54 <%= call_hook(:view_projects_show_right, :project => @project) %>
55 55 </div>
56 56
57 57 <% content_for :sidebar do %>
58 58 <% planning_links = []
59 59 planning_links << link_to_if_authorized(l(:label_calendar), :controller => 'issues', :action => 'calendar', :project_id => @project)
60 60 planning_links << link_to_if_authorized(l(:label_gantt), :controller => 'issues', :action => 'gantt', :project_id => @project)
61 61 planning_links.compact!
62 62 unless planning_links.empty? %>
63 63 <h3><%= l(:label_planning) %></h3>
64 64 <p><%= planning_links.join(' | ') %></p>
65 65 <% end %>
66 66
67 67 <% if @total_hours && User.current.allowed_to?(:view_time_entries, @project) %>
68 68 <h3><%= l(:label_spent_time) %></h3>
69 69 <p><span class="icon icon-time"><%= l_hours(@total_hours) %></span></p>
70 70 <p><%= link_to(l(:label_details), {:controller => 'timelog', :action => 'details', :project_id => @project}) %> |
71 71 <%= link_to(l(:label_report), {:controller => 'timelog', :action => 'report', :project_id => @project}) %></p>
72 72 <% end %>
73 73 <%= call_hook(:view_projects_show_sidebar_bottom, :project => @project) %>
74 74 <% end %>
75 75
76 76 <% content_for :header_tags do %>
77 77 <%= auto_discovery_link_tag(:atom, {:action => 'activity', :id => @project, :format => 'atom', :key => User.current.rss_key}) %>
78 78 <% end %>
79 79
80 80 <% html_title(l(:label_overview)) -%>
@@ -1,169 +1,181
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 < ActionController::TestCase
25 25 fixtures :users, :roles
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_login_should_redirect_to_back_url_param
48 60 # request.uri is "test.host" in test environment
49 61 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http%3A%2F%2Ftest.host%2Fissues%2Fshow%2F1'
50 62 assert_redirected_to '/issues/show/1'
51 63 end
52 64
53 65 def test_login_should_not_redirect_to_another_host
54 66 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http%3A%2F%2Ftest.foo%2Ffake'
55 67 assert_redirected_to '/my/page'
56 68 end
57 69
58 70 def test_login_with_wrong_password
59 71 post :login, :username => 'admin', :password => 'bad'
60 72 assert_response :success
61 73 assert_template 'login'
62 74 assert_tag 'div',
63 75 :attributes => { :class => "flash error" },
64 76 :content => /Invalid user or password/
65 77 end
66 78
67 79 if Object.const_defined?(:OpenID)
68 80
69 81 def test_login_with_openid_for_existing_user
70 82 Setting.self_registration = '3'
71 83 Setting.openid = '1'
72 84 existing_user = User.new(:firstname => 'Cool',
73 85 :lastname => 'User',
74 86 :mail => 'user@somedomain.com',
75 87 :identity_url => 'http://openid.example.com/good_user')
76 88 existing_user.login = 'cool_user'
77 89 assert existing_user.save!
78 90
79 91 post :login, :openid_url => existing_user.identity_url
80 92 assert_redirected_to 'my/page'
81 93 end
82 94
83 95 def test_login_with_openid_for_existing_non_active_user
84 96 Setting.self_registration = '2'
85 97 Setting.openid = '1'
86 98 existing_user = User.new(:firstname => 'Cool',
87 99 :lastname => 'User',
88 100 :mail => 'user@somedomain.com',
89 101 :identity_url => 'http://openid.example.com/good_user',
90 102 :status => User::STATUS_REGISTERED)
91 103 existing_user.login = 'cool_user'
92 104 assert existing_user.save!
93 105
94 106 post :login, :openid_url => existing_user.identity_url
95 107 assert_redirected_to 'login'
96 108 end
97 109
98 110 def test_login_with_openid_with_new_user_created
99 111 Setting.self_registration = '3'
100 112 Setting.openid = '1'
101 113 post :login, :openid_url => 'http://openid.example.com/good_user'
102 114 assert_redirected_to 'my/account'
103 115 user = User.find_by_login('cool_user')
104 116 assert user
105 117 assert_equal 'Cool', user.firstname
106 118 assert_equal 'User', user.lastname
107 119 end
108 120
109 121 def test_login_with_openid_with_new_user_and_self_registration_off
110 122 Setting.self_registration = '0'
111 123 Setting.openid = '1'
112 124 post :login, :openid_url => 'http://openid.example.com/good_user'
113 125 assert_redirected_to home_url
114 126 user = User.find_by_login('cool_user')
115 127 assert ! user
116 128 end
117 129
118 130 def test_login_with_openid_with_new_user_created_with_email_activation_should_have_a_token
119 131 Setting.self_registration = '1'
120 132 Setting.openid = '1'
121 133 post :login, :openid_url => 'http://openid.example.com/good_user'
122 134 assert_redirected_to 'login'
123 135 user = User.find_by_login('cool_user')
124 136 assert user
125 137
126 138 token = Token.find_by_user_id_and_action(user.id, 'register')
127 139 assert token
128 140 end
129 141
130 142 def test_login_with_openid_with_new_user_created_with_manual_activation
131 143 Setting.self_registration = '2'
132 144 Setting.openid = '1'
133 145 post :login, :openid_url => 'http://openid.example.com/good_user'
134 146 assert_redirected_to 'login'
135 147 user = User.find_by_login('cool_user')
136 148 assert user
137 149 assert_equal User::STATUS_REGISTERED, user.status
138 150 end
139 151
140 152 def test_login_with_openid_with_new_user_with_conflict_should_register
141 153 Setting.self_registration = '3'
142 154 Setting.openid = '1'
143 155 existing_user = User.new(:firstname => 'Cool', :lastname => 'User', :mail => 'user@somedomain.com')
144 156 existing_user.login = 'cool_user'
145 157 assert existing_user.save!
146 158
147 159 post :login, :openid_url => 'http://openid.example.com/good_user'
148 160 assert_response :success
149 161 assert_template 'register'
150 162 assert assigns(:user)
151 163 assert_equal 'http://openid.example.com/good_user', assigns(:user)[:identity_url]
152 164 end
153 165
154 166 def test_setting_openid_should_return_true_when_set_to_true
155 167 Setting.openid = '1'
156 168 assert_equal true, Setting.openid?
157 169 end
158 170
159 171 else
160 172 puts "Skipping openid tests."
161 173 end
162 174
163 175 def test_logout
164 176 @request.session[:user_id] = 2
165 177 get :logout
166 178 assert_redirected_to ''
167 179 assert_nil @request.session[:user_id]
168 180 end
169 181 end
This diff has been collapsed as it changes many lines, (1144 lines changed) Show them Hide them
@@ -1,567 +1,577
1 # Redmine - project management software
2 # Copyright (C) 2006-2008 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.dirname(__FILE__) + '/../test_helper'
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
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_routing
38 assert_routing(
39 {:method => :get, :path => '/projects'},
40 :controller => 'projects', :action => 'index'
41 )
42 end
43
44 def test_index
45 get :index
46 assert_response :success
47 assert_template 'index'
48 assert_not_nil assigns(:projects)
49
50 assert_tag :ul, :child => {:tag => 'li',
51 :descendant => {:tag => 'a', :content => 'eCookbook'},
52 :child => { :tag => 'ul',
53 :descendant => { :tag => 'a',
54 :content => 'Child of private child'
55 }
56 }
57 }
58
59 assert_no_tag :a, :content => /Private child of eCookbook/
60 end
61
62 def test_index_atom_routing
63 assert_routing(
64 {:method => :get, :path => '/projects.atom'},
65 :controller => 'projects', :action => 'index', :format => 'atom'
66 )
67 end
68
69 def test_index_atom
70 get :index, :format => 'atom'
71 assert_response :success
72 assert_template 'common/feed.atom.rxml'
73 assert_select 'feed>title', :text => 'Redmine: Latest projects'
74 assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_by(User.current))
75 end
76
77 def test_add_routing
78 assert_routing(
79 {:method => :get, :path => '/projects/new'},
80 :controller => 'projects', :action => 'add'
81 )
82 assert_recognizes(
83 {:controller => 'projects', :action => 'add'},
84 {:method => :post, :path => '/projects/new'}
85 )
86 assert_recognizes(
87 {:controller => 'projects', :action => 'add'},
88 {:method => :post, :path => '/projects'}
89 )
90 end
91
92 def test_get_add
93 @request.session[:user_id] = 1
94 get :add
95 assert_response :success
96 assert_template 'add'
97 end
98
99 def test_get_add_by_non_admin
100 @request.session[:user_id] = 2
101 get :add
102 assert_response :success
103 assert_template 'add'
104 end
105
106 def test_post_add
107 @request.session[:user_id] = 1
108 post :add, :project => { :name => "blog",
109 :description => "weblog",
110 :identifier => "blog",
111 :is_public => 1,
112 :custom_field_values => { '3' => 'Beta' }
113 }
114 assert_redirected_to '/projects/blog/settings'
115
116 project = Project.find_by_name('blog')
117 assert_kind_of Project, project
118 assert_equal 'weblog', project.description
119 assert_equal true, project.is_public?
120 end
121
122 def test_post_add_by_non_admin
123 @request.session[:user_id] = 2
124 post :add, :project => { :name => "blog",
125 :description => "weblog",
126 :identifier => "blog",
127 :is_public => 1,
128 :custom_field_values => { '3' => 'Beta' }
129 }
130 assert_redirected_to '/projects/blog/settings'
131
132 project = Project.find_by_name('blog')
133 assert_kind_of Project, project
134 assert_equal 'weblog', project.description
135 assert_equal true, project.is_public?
136
137 # User should be added as a project member
138 assert User.find(2).member_of?(project)
139 assert_equal 1, project.members.size
140 end
141
142 def test_show_routing
143 assert_routing(
144 {:method => :get, :path => '/projects/test'},
145 :controller => 'projects', :action => 'show', :id => 'test'
146 )
147 end
148
149 def test_show_by_id
150 get :show, :id => 1
151 assert_response :success
152 assert_template 'show'
153 assert_not_nil assigns(:project)
154 end
155
156 def test_show_by_identifier
157 get :show, :id => 'ecookbook'
158 assert_response :success
159 assert_template 'show'
160 assert_not_nil assigns(:project)
161 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
162 end
163
164 def test_private_subprojects_hidden
165 get :show, :id => 'ecookbook'
166 assert_response :success
167 assert_template 'show'
168 assert_no_tag :tag => 'a', :content => /Private child/
169 end
170
171 def test_private_subprojects_visible
172 @request.session[:user_id] = 2 # manager who is a member of the private subproject
173 get :show, :id => 'ecookbook'
174 assert_response :success
175 assert_template 'show'
176 assert_tag :tag => 'a', :content => /Private child/
177 end
178
179 def test_settings_routing
180 assert_routing(
181 {:method => :get, :path => '/projects/4223/settings'},
182 :controller => 'projects', :action => 'settings', :id => '4223'
183 )
184 assert_routing(
185 {:method => :get, :path => '/projects/4223/settings/members'},
186 :controller => 'projects', :action => 'settings', :id => '4223', :tab => 'members'
187 )
188 end
189
190 def test_settings
191 @request.session[:user_id] = 2 # manager
192 get :settings, :id => 1
193 assert_response :success
194 assert_template 'settings'
195 end
196
197 def test_edit
198 @request.session[:user_id] = 2 # manager
199 post :edit, :id => 1, :project => {:name => 'Test changed name',
200 :issue_custom_field_ids => ['']}
201 assert_redirected_to 'projects/ecookbook/settings'
202 project = Project.find(1)
203 assert_equal 'Test changed name', project.name
204 end
205
206 def test_add_version_routing
207 assert_routing(
208 {:method => :get, :path => 'projects/64/versions/new'},
209 :controller => 'projects', :action => 'add_version', :id => '64'
210 )
211 assert_routing(
212 #TODO: use PUT
213 {:method => :post, :path => 'projects/64/versions/new'},
214 :controller => 'projects', :action => 'add_version', :id => '64'
215 )
216 end
217
218 def test_add_issue_category_routing
219 assert_routing(
220 {:method => :get, :path => 'projects/test/categories/new'},
221 :controller => 'projects', :action => 'add_issue_category', :id => 'test'
222 )
223 assert_routing(
224 #TODO: use PUT and update form
225 {:method => :post, :path => 'projects/64/categories/new'},
226 :controller => 'projects', :action => 'add_issue_category', :id => '64'
227 )
228 end
229
230 def test_destroy_routing
231 assert_routing(
232 {:method => :get, :path => '/projects/567/destroy'},
233 :controller => 'projects', :action => 'destroy', :id => '567'
234 )
235 assert_routing(
236 #TODO: use DELETE and update form
237 {:method => :post, :path => 'projects/64/destroy'},
238 :controller => 'projects', :action => 'destroy', :id => '64'
239 )
240 end
241
242 def test_get_destroy
243 @request.session[:user_id] = 1 # admin
244 get :destroy, :id => 1
245 assert_response :success
246 assert_template 'destroy'
247 assert_not_nil Project.find_by_id(1)
248 end
249
250 def test_post_destroy
251 @request.session[:user_id] = 1 # admin
252 post :destroy, :id => 1, :confirm => 1
253 assert_redirected_to 'admin/projects'
254 assert_nil Project.find_by_id(1)
255 end
256
257 def test_add_file
258 set_tmp_attachments_directory
259 @request.session[:user_id] = 2
260 Setting.notified_events = ['file_added']
261 ActionMailer::Base.deliveries.clear
262
263 assert_difference 'Attachment.count' do
264 post :add_file, :id => 1, :version_id => '',
265 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
266 end
267 assert_redirected_to 'projects/ecookbook/files'
268 a = Attachment.find(:first, :order => 'created_on DESC')
269 assert_equal 'testfile.txt', a.filename
270 assert_equal Project.find(1), a.container
271
272 mail = ActionMailer::Base.deliveries.last
273 assert_kind_of TMail::Mail, mail
274 assert_equal "[eCookbook] New file", mail.subject
275 assert mail.body.include?('testfile.txt')
276 end
277
278 def test_add_file_routing
279 assert_routing(
280 {:method => :get, :path => '/projects/33/files/new'},
281 :controller => 'projects', :action => 'add_file', :id => '33'
282 )
283 assert_routing(
284 {:method => :post, :path => '/projects/33/files/new'},
285 :controller => 'projects', :action => 'add_file', :id => '33'
286 )
287 end
288
289 def test_add_version_file
290 set_tmp_attachments_directory
291 @request.session[:user_id] = 2
292 Setting.notified_events = ['file_added']
293
294 assert_difference 'Attachment.count' do
295 post :add_file, :id => 1, :version_id => '2',
296 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
297 end
298 assert_redirected_to 'projects/ecookbook/files'
299 a = Attachment.find(:first, :order => 'created_on DESC')
300 assert_equal 'testfile.txt', a.filename
301 assert_equal Version.find(2), a.container
302 end
303
304 def test_list_files
305 get :list_files, :id => 1
306 assert_response :success
307 assert_template 'list_files'
308 assert_not_nil assigns(:containers)
309
310 # file attached to the project
311 assert_tag :a, :content => 'project_file.zip',
312 :attributes => { :href => '/attachments/download/8/project_file.zip' }
313
314 # file attached to a project's version
315 assert_tag :a, :content => 'version_file.zip',
316 :attributes => { :href => '/attachments/download/9/version_file.zip' }
317 end
318
319 def test_list_files_routing
320 assert_routing(
321 {:method => :get, :path => '/projects/33/files'},
322 :controller => 'projects', :action => 'list_files', :id => '33'
323 )
324 end
325
326 def test_changelog_routing
327 assert_routing(
328 {:method => :get, :path => '/projects/44/changelog'},
329 :controller => 'projects', :action => 'changelog', :id => '44'
330 )
331 end
332
333 def test_changelog
334 get :changelog, :id => 1
335 assert_response :success
336 assert_template 'changelog'
337 assert_not_nil assigns(:versions)
338 end
339
340 def test_roadmap_routing
341 assert_routing(
342 {:method => :get, :path => 'projects/33/roadmap'},
343 :controller => 'projects', :action => 'roadmap', :id => '33'
344 )
345 end
346
347 def test_roadmap
348 get :roadmap, :id => 1
349 assert_response :success
350 assert_template 'roadmap'
351 assert_not_nil assigns(:versions)
352 # Version with no date set appears
353 assert assigns(:versions).include?(Version.find(3))
354 # Completed version doesn't appear
355 assert !assigns(:versions).include?(Version.find(1))
356 end
357
358 def test_roadmap_with_completed_versions
359 get :roadmap, :id => 1, :completed => 1
360 assert_response :success
361 assert_template 'roadmap'
362 assert_not_nil assigns(:versions)
363 # Version with no date set appears
364 assert assigns(:versions).include?(Version.find(3))
365 # Completed version appears
366 assert assigns(:versions).include?(Version.find(1))
367 end
368
369 def test_project_activity_routing
370 assert_routing(
371 {:method => :get, :path => '/projects/1/activity'},
372 :controller => 'projects', :action => 'activity', :id => '1'
373 )
374 end
375
376 def test_project_activity_atom_routing
377 assert_routing(
378 {:method => :get, :path => '/projects/1/activity.atom'},
379 :controller => 'projects', :action => 'activity', :id => '1', :format => 'atom'
380 )
381 end
382
383 def test_project_activity
384 get :activity, :id => 1, :with_subprojects => 0
385 assert_response :success
386 assert_template 'activity'
387 assert_not_nil assigns(:events_by_day)
388
389 assert_tag :tag => "h3",
390 :content => /#{2.days.ago.to_date.day}/,
391 :sibling => { :tag => "dl",
392 :child => { :tag => "dt",
393 :attributes => { :class => /issue-edit/ },
394 :child => { :tag => "a",
395 :content => /(#{IssueStatus.find(2).name})/,
396 }
397 }
398 }
399 end
400
401 def test_previous_project_activity
402 get :activity, :id => 1, :from => 3.days.ago.to_date
403 assert_response :success
404 assert_template 'activity'
405 assert_not_nil assigns(:events_by_day)
406
407 assert_tag :tag => "h3",
408 :content => /#{3.day.ago.to_date.day}/,
409 :sibling => { :tag => "dl",
410 :child => { :tag => "dt",
411 :attributes => { :class => /issue/ },
412 :child => { :tag => "a",
413 :content => /#{Issue.find(1).subject}/,
414 }
415 }
416 }
417 end
418
419 def test_global_activity_routing
420 assert_routing({:method => :get, :path => '/activity'}, :controller => 'projects', :action => 'activity', :id => nil)
421 end
422
423 def test_global_activity
424 get :activity
425 assert_response :success
426 assert_template 'activity'
427 assert_not_nil assigns(:events_by_day)
428
429 assert_tag :tag => "h3",
430 :content => /#{5.day.ago.to_date.day}/,
431 :sibling => { :tag => "dl",
432 :child => { :tag => "dt",
433 :attributes => { :class => /issue/ },
434 :child => { :tag => "a",
435 :content => /#{Issue.find(5).subject}/,
436 }
437 }
438 }
439 end
440
441 def test_user_activity
442 get :activity, :user_id => 2
443 assert_response :success
444 assert_template 'activity'
445 assert_not_nil assigns(:events_by_day)
446
447 assert_tag :tag => "h3",
448 :content => /#{3.day.ago.to_date.day}/,
449 :sibling => { :tag => "dl",
450 :child => { :tag => "dt",
451 :attributes => { :class => /issue/ },
452 :child => { :tag => "a",
453 :content => /#{Issue.find(1).subject}/,
454 }
455 }
456 }
457 end
458
459 def test_global_activity_atom_routing
460 assert_routing({:method => :get, :path => '/activity.atom'}, :controller => 'projects', :action => 'activity', :id => nil, :format => 'atom')
461 end
462
463 def test_activity_atom_feed
464 get :activity, :format => 'atom'
465 assert_response :success
466 assert_template 'common/feed.atom.rxml'
467 end
468
469 def test_archive_routing
470 assert_routing(
471 #TODO: use PUT to project path and modify form
472 {:method => :post, :path => 'projects/64/archive'},
473 :controller => 'projects', :action => 'archive', :id => '64'
474 )
475 end
476
477 def test_archive
478 @request.session[:user_id] = 1 # admin
479 post :archive, :id => 1
480 assert_redirected_to 'admin/projects'
481 assert !Project.find(1).active?
482 end
483
484 def test_unarchive_routing
485 assert_routing(
486 #TODO: use PUT to project path and modify form
487 {:method => :post, :path => '/projects/567/unarchive'},
488 :controller => 'projects', :action => 'unarchive', :id => '567'
489 )
490 end
491
492 def test_unarchive
493 @request.session[:user_id] = 1 # admin
494 Project.find(1).archive
495 post :unarchive, :id => 1
496 assert_redirected_to 'admin/projects'
497 assert Project.find(1).active?
498 end
499
500 def test_project_breadcrumbs_should_be_limited_to_3_ancestors
501 CustomField.delete_all
502 parent = nil
503 6.times do |i|
504 p = Project.create!(:name => "Breadcrumbs #{i}", :identifier => "breadcrumbs-#{i}")
505 p.set_parent!(parent)
506 get :show, :id => p
507 assert_tag :h1, :parent => { :attributes => {:id => 'header'}},
508 :children => { :count => [i, 3].min,
509 :only => { :tag => 'a' } }
510
511 parent = p
512 end
513 end
514
515 def test_copy_with_project
516 @request.session[:user_id] = 1 # admin
517 get :copy, :id => 1
518 assert_response :success
519 assert_template 'copy'
520 assert assigns(:project)
521 assert_equal Project.find(1).description, assigns(:project).description
522 assert_nil assigns(:project).id
523 end
524
525 def test_copy_without_project
526 @request.session[:user_id] = 1 # admin
527 get :copy
528 assert_response :redirect
529 assert_redirected_to :controller => 'admin', :action => 'projects'
530 end
531
532 def test_jump_should_redirect_to_active_tab
533 get :show, :id => 1, :jump => 'issues'
534 assert_redirected_to 'projects/ecookbook/issues'
535 end
536
537 def test_jump_should_not_redirect_to_inactive_tab
538 get :show, :id => 3, :jump => 'documents'
539 assert_response :success
540 assert_template 'show'
541 end
542
543 def test_jump_should_not_redirect_to_unknown_tab
544 get :show, :id => 3, :jump => 'foobar'
545 assert_response :success
546 assert_template 'show'
547 end
548
549 # A hook that is manually registered later
550 class ProjectBasedTemplate < Redmine::Hook::ViewListener
551 def view_layouts_base_html_head(context)
552 # Adds a project stylesheet
553 stylesheet_link_tag(context[:project].identifier) if context[:project]
554 end
555 end
556 # Don't use this hook now
557 Redmine::Hook.clear_listeners
558
559 def test_hook_response
560 Redmine::Hook.add_listener(ProjectBasedTemplate)
561 get :show, :id => 1
562 assert_tag :tag => 'link', :attributes => {:href => '/stylesheets/ecookbook.css'},
563 :parent => {:tag => 'head'}
564
565 Redmine::Hook.clear_listeners
566 end
567 end
1 # Redmine - project management software
2 # Copyright (C) 2006-2008 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.dirname(__FILE__) + '/../test_helper'
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
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_routing
38 assert_routing(
39 {:method => :get, :path => '/projects'},
40 :controller => 'projects', :action => 'index'
41 )
42 end
43
44 def test_index
45 get :index
46 assert_response :success
47 assert_template 'index'
48 assert_not_nil assigns(:projects)
49
50 assert_tag :ul, :child => {:tag => 'li',
51 :descendant => {:tag => 'a', :content => 'eCookbook'},
52 :child => { :tag => 'ul',
53 :descendant => { :tag => 'a',
54 :content => 'Child of private child'
55 }
56 }
57 }
58
59 assert_no_tag :a, :content => /Private child of eCookbook/
60 end
61
62 def test_index_atom_routing
63 assert_routing(
64 {:method => :get, :path => '/projects.atom'},
65 :controller => 'projects', :action => 'index', :format => 'atom'
66 )
67 end
68
69 def test_index_atom
70 get :index, :format => 'atom'
71 assert_response :success
72 assert_template 'common/feed.atom.rxml'
73 assert_select 'feed>title', :text => 'Redmine: Latest projects'
74 assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_by(User.current))
75 end
76
77 def test_add_routing
78 assert_routing(
79 {:method => :get, :path => '/projects/new'},
80 :controller => 'projects', :action => 'add'
81 )
82 assert_recognizes(
83 {:controller => 'projects', :action => 'add'},
84 {:method => :post, :path => '/projects/new'}
85 )
86 assert_recognizes(
87 {:controller => 'projects', :action => 'add'},
88 {:method => :post, :path => '/projects'}
89 )
90 end
91
92 def test_get_add
93 @request.session[:user_id] = 1
94 get :add
95 assert_response :success
96 assert_template 'add'
97 end
98
99 def test_get_add_by_non_admin
100 @request.session[:user_id] = 2
101 get :add
102 assert_response :success
103 assert_template 'add'
104 end
105
106 def test_post_add
107 @request.session[:user_id] = 1
108 post :add, :project => { :name => "blog",
109 :description => "weblog",
110 :identifier => "blog",
111 :is_public => 1,
112 :custom_field_values => { '3' => 'Beta' }
113 }
114 assert_redirected_to '/projects/blog/settings'
115
116 project = Project.find_by_name('blog')
117 assert_kind_of Project, project
118 assert_equal 'weblog', project.description
119 assert_equal true, project.is_public?
120 end
121
122 def test_post_add_by_non_admin
123 @request.session[:user_id] = 2
124 post :add, :project => { :name => "blog",
125 :description => "weblog",
126 :identifier => "blog",
127 :is_public => 1,
128 :custom_field_values => { '3' => 'Beta' }
129 }
130 assert_redirected_to '/projects/blog/settings'
131
132 project = Project.find_by_name('blog')
133 assert_kind_of Project, project
134 assert_equal 'weblog', project.description
135 assert_equal true, project.is_public?
136
137 # User should be added as a project member
138 assert User.find(2).member_of?(project)
139 assert_equal 1, project.members.size
140 end
141
142 def test_show_routing
143 assert_routing(
144 {:method => :get, :path => '/projects/test'},
145 :controller => 'projects', :action => 'show', :id => 'test'
146 )
147 end
148
149 def test_show_by_id
150 get :show, :id => 1
151 assert_response :success
152 assert_template 'show'
153 assert_not_nil assigns(:project)
154 end
155
156 def test_show_by_identifier
157 get :show, :id => 'ecookbook'
158 assert_response :success
159 assert_template 'show'
160 assert_not_nil assigns(:project)
161 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
162 end
163
164 def test_show_should_not_fail_when_custom_values_are_nil
165 project = Project.find_by_identifier('ecookbook')
166 project.custom_values.first.update_attribute(:value, nil)
167 get :show, :id => 'ecookbook'
168 assert_response :success
169 assert_template 'show'
170 assert_not_nil assigns(:project)
171 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
172 end
173
174 def test_private_subprojects_hidden
175 get :show, :id => 'ecookbook'
176 assert_response :success
177 assert_template 'show'
178 assert_no_tag :tag => 'a', :content => /Private child/
179 end
180
181 def test_private_subprojects_visible
182 @request.session[:user_id] = 2 # manager who is a member of the private subproject
183 get :show, :id => 'ecookbook'
184 assert_response :success
185 assert_template 'show'
186 assert_tag :tag => 'a', :content => /Private child/
187 end
188
189 def test_settings_routing
190 assert_routing(
191 {:method => :get, :path => '/projects/4223/settings'},
192 :controller => 'projects', :action => 'settings', :id => '4223'
193 )
194 assert_routing(
195 {:method => :get, :path => '/projects/4223/settings/members'},
196 :controller => 'projects', :action => 'settings', :id => '4223', :tab => 'members'
197 )
198 end
199
200 def test_settings
201 @request.session[:user_id] = 2 # manager
202 get :settings, :id => 1
203 assert_response :success
204 assert_template 'settings'
205 end
206
207 def test_edit
208 @request.session[:user_id] = 2 # manager
209 post :edit, :id => 1, :project => {:name => 'Test changed name',
210 :issue_custom_field_ids => ['']}
211 assert_redirected_to 'projects/ecookbook/settings'
212 project = Project.find(1)
213 assert_equal 'Test changed name', project.name
214 end
215
216 def test_add_version_routing
217 assert_routing(
218 {:method => :get, :path => 'projects/64/versions/new'},
219 :controller => 'projects', :action => 'add_version', :id => '64'
220 )
221 assert_routing(
222 #TODO: use PUT
223 {:method => :post, :path => 'projects/64/versions/new'},
224 :controller => 'projects', :action => 'add_version', :id => '64'
225 )
226 end
227
228 def test_add_issue_category_routing
229 assert_routing(
230 {:method => :get, :path => 'projects/test/categories/new'},
231 :controller => 'projects', :action => 'add_issue_category', :id => 'test'
232 )
233 assert_routing(
234 #TODO: use PUT and update form
235 {:method => :post, :path => 'projects/64/categories/new'},
236 :controller => 'projects', :action => 'add_issue_category', :id => '64'
237 )
238 end
239
240 def test_destroy_routing
241 assert_routing(
242 {:method => :get, :path => '/projects/567/destroy'},
243 :controller => 'projects', :action => 'destroy', :id => '567'
244 )
245 assert_routing(
246 #TODO: use DELETE and update form
247 {:method => :post, :path => 'projects/64/destroy'},
248 :controller => 'projects', :action => 'destroy', :id => '64'
249 )
250 end
251
252 def test_get_destroy
253 @request.session[:user_id] = 1 # admin
254 get :destroy, :id => 1
255 assert_response :success
256 assert_template 'destroy'
257 assert_not_nil Project.find_by_id(1)
258 end
259
260 def test_post_destroy
261 @request.session[:user_id] = 1 # admin
262 post :destroy, :id => 1, :confirm => 1
263 assert_redirected_to 'admin/projects'
264 assert_nil Project.find_by_id(1)
265 end
266
267 def test_add_file
268 set_tmp_attachments_directory
269 @request.session[:user_id] = 2
270 Setting.notified_events = ['file_added']
271 ActionMailer::Base.deliveries.clear
272
273 assert_difference 'Attachment.count' do
274 post :add_file, :id => 1, :version_id => '',
275 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
276 end
277 assert_redirected_to 'projects/ecookbook/files'
278 a = Attachment.find(:first, :order => 'created_on DESC')
279 assert_equal 'testfile.txt', a.filename
280 assert_equal Project.find(1), a.container
281
282 mail = ActionMailer::Base.deliveries.last
283 assert_kind_of TMail::Mail, mail
284 assert_equal "[eCookbook] New file", mail.subject
285 assert mail.body.include?('testfile.txt')
286 end
287
288 def test_add_file_routing
289 assert_routing(
290 {:method => :get, :path => '/projects/33/files/new'},
291 :controller => 'projects', :action => 'add_file', :id => '33'
292 )
293 assert_routing(
294 {:method => :post, :path => '/projects/33/files/new'},
295 :controller => 'projects', :action => 'add_file', :id => '33'
296 )
297 end
298
299 def test_add_version_file
300 set_tmp_attachments_directory
301 @request.session[:user_id] = 2
302 Setting.notified_events = ['file_added']
303
304 assert_difference 'Attachment.count' do
305 post :add_file, :id => 1, :version_id => '2',
306 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
307 end
308 assert_redirected_to 'projects/ecookbook/files'
309 a = Attachment.find(:first, :order => 'created_on DESC')
310 assert_equal 'testfile.txt', a.filename
311 assert_equal Version.find(2), a.container
312 end
313
314 def test_list_files
315 get :list_files, :id => 1
316 assert_response :success
317 assert_template 'list_files'
318 assert_not_nil assigns(:containers)
319
320 # file attached to the project
321 assert_tag :a, :content => 'project_file.zip',
322 :attributes => { :href => '/attachments/download/8/project_file.zip' }
323
324 # file attached to a project's version
325 assert_tag :a, :content => 'version_file.zip',
326 :attributes => { :href => '/attachments/download/9/version_file.zip' }
327 end
328
329 def test_list_files_routing
330 assert_routing(
331 {:method => :get, :path => '/projects/33/files'},
332 :controller => 'projects', :action => 'list_files', :id => '33'
333 )
334 end
335
336 def test_changelog_routing
337 assert_routing(
338 {:method => :get, :path => '/projects/44/changelog'},
339 :controller => 'projects', :action => 'changelog', :id => '44'
340 )
341 end
342
343 def test_changelog
344 get :changelog, :id => 1
345 assert_response :success
346 assert_template 'changelog'
347 assert_not_nil assigns(:versions)
348 end
349
350 def test_roadmap_routing
351 assert_routing(
352 {:method => :get, :path => 'projects/33/roadmap'},
353 :controller => 'projects', :action => 'roadmap', :id => '33'
354 )
355 end
356
357 def test_roadmap
358 get :roadmap, :id => 1
359 assert_response :success
360 assert_template 'roadmap'
361 assert_not_nil assigns(:versions)
362 # Version with no date set appears
363 assert assigns(:versions).include?(Version.find(3))
364 # Completed version doesn't appear
365 assert !assigns(:versions).include?(Version.find(1))
366 end
367
368 def test_roadmap_with_completed_versions
369 get :roadmap, :id => 1, :completed => 1
370 assert_response :success
371 assert_template 'roadmap'
372 assert_not_nil assigns(:versions)
373 # Version with no date set appears
374 assert assigns(:versions).include?(Version.find(3))
375 # Completed version appears
376 assert assigns(:versions).include?(Version.find(1))
377 end
378
379 def test_project_activity_routing
380 assert_routing(
381 {:method => :get, :path => '/projects/1/activity'},
382 :controller => 'projects', :action => 'activity', :id => '1'
383 )
384 end
385
386 def test_project_activity_atom_routing
387 assert_routing(
388 {:method => :get, :path => '/projects/1/activity.atom'},
389 :controller => 'projects', :action => 'activity', :id => '1', :format => 'atom'
390 )
391 end
392
393 def test_project_activity
394 get :activity, :id => 1, :with_subprojects => 0
395 assert_response :success
396 assert_template 'activity'
397 assert_not_nil assigns(:events_by_day)
398
399 assert_tag :tag => "h3",
400 :content => /#{2.days.ago.to_date.day}/,
401 :sibling => { :tag => "dl",
402 :child => { :tag => "dt",
403 :attributes => { :class => /issue-edit/ },
404 :child => { :tag => "a",
405 :content => /(#{IssueStatus.find(2).name})/,
406 }
407 }
408 }
409 end
410
411 def test_previous_project_activity
412 get :activity, :id => 1, :from => 3.days.ago.to_date
413 assert_response :success
414 assert_template 'activity'
415 assert_not_nil assigns(:events_by_day)
416
417 assert_tag :tag => "h3",
418 :content => /#{3.day.ago.to_date.day}/,
419 :sibling => { :tag => "dl",
420 :child => { :tag => "dt",
421 :attributes => { :class => /issue/ },
422 :child => { :tag => "a",
423 :content => /#{Issue.find(1).subject}/,
424 }
425 }
426 }
427 end
428
429 def test_global_activity_routing
430 assert_routing({:method => :get, :path => '/activity'}, :controller => 'projects', :action => 'activity', :id => nil)
431 end
432
433 def test_global_activity
434 get :activity
435 assert_response :success
436 assert_template 'activity'
437 assert_not_nil assigns(:events_by_day)
438
439 assert_tag :tag => "h3",
440 :content => /#{5.day.ago.to_date.day}/,
441 :sibling => { :tag => "dl",
442 :child => { :tag => "dt",
443 :attributes => { :class => /issue/ },
444 :child => { :tag => "a",
445 :content => /#{Issue.find(5).subject}/,
446 }
447 }
448 }
449 end
450
451 def test_user_activity
452 get :activity, :user_id => 2
453 assert_response :success
454 assert_template 'activity'
455 assert_not_nil assigns(:events_by_day)
456
457 assert_tag :tag => "h3",
458 :content => /#{3.day.ago.to_date.day}/,
459 :sibling => { :tag => "dl",
460 :child => { :tag => "dt",
461 :attributes => { :class => /issue/ },
462 :child => { :tag => "a",
463 :content => /#{Issue.find(1).subject}/,
464 }
465 }
466 }
467 end
468
469 def test_global_activity_atom_routing
470 assert_routing({:method => :get, :path => '/activity.atom'}, :controller => 'projects', :action => 'activity', :id => nil, :format => 'atom')
471 end
472
473 def test_activity_atom_feed
474 get :activity, :format => 'atom'
475 assert_response :success
476 assert_template 'common/feed.atom.rxml'
477 end
478
479 def test_archive_routing
480 assert_routing(
481 #TODO: use PUT to project path and modify form
482 {:method => :post, :path => 'projects/64/archive'},
483 :controller => 'projects', :action => 'archive', :id => '64'
484 )
485 end
486
487 def test_archive
488 @request.session[:user_id] = 1 # admin
489 post :archive, :id => 1
490 assert_redirected_to 'admin/projects'
491 assert !Project.find(1).active?
492 end
493
494 def test_unarchive_routing
495 assert_routing(
496 #TODO: use PUT to project path and modify form
497 {:method => :post, :path => '/projects/567/unarchive'},
498 :controller => 'projects', :action => 'unarchive', :id => '567'
499 )
500 end
501
502 def test_unarchive
503 @request.session[:user_id] = 1 # admin
504 Project.find(1).archive
505 post :unarchive, :id => 1
506 assert_redirected_to 'admin/projects'
507 assert Project.find(1).active?
508 end
509
510 def test_project_breadcrumbs_should_be_limited_to_3_ancestors
511 CustomField.delete_all
512 parent = nil
513 6.times do |i|
514 p = Project.create!(:name => "Breadcrumbs #{i}", :identifier => "breadcrumbs-#{i}")
515 p.set_parent!(parent)
516 get :show, :id => p
517 assert_tag :h1, :parent => { :attributes => {:id => 'header'}},
518 :children => { :count => [i, 3].min,
519 :only => { :tag => 'a' } }
520
521 parent = p
522 end
523 end
524
525 def test_copy_with_project
526 @request.session[:user_id] = 1 # admin
527 get :copy, :id => 1
528 assert_response :success
529 assert_template 'copy'
530 assert assigns(:project)
531 assert_equal Project.find(1).description, assigns(:project).description
532 assert_nil assigns(:project).id
533 end
534
535 def test_copy_without_project
536 @request.session[:user_id] = 1 # admin
537 get :copy
538 assert_response :redirect
539 assert_redirected_to :controller => 'admin', :action => 'projects'
540 end
541
542 def test_jump_should_redirect_to_active_tab
543 get :show, :id => 1, :jump => 'issues'
544 assert_redirected_to 'projects/ecookbook/issues'
545 end
546
547 def test_jump_should_not_redirect_to_inactive_tab
548 get :show, :id => 3, :jump => 'documents'
549 assert_response :success
550 assert_template 'show'
551 end
552
553 def test_jump_should_not_redirect_to_unknown_tab
554 get :show, :id => 3, :jump => 'foobar'
555 assert_response :success
556 assert_template 'show'
557 end
558
559 # A hook that is manually registered later
560 class ProjectBasedTemplate < Redmine::Hook::ViewListener
561 def view_layouts_base_html_head(context)
562 # Adds a project stylesheet
563 stylesheet_link_tag(context[:project].identifier) if context[:project]
564 end
565 end
566 # Don't use this hook now
567 Redmine::Hook.clear_listeners
568
569 def test_hook_response
570 Redmine::Hook.add_listener(ProjectBasedTemplate)
571 get :show, :id => 1
572 assert_tag :tag => 'link', :attributes => {:href => '/stylesheets/ecookbook.css'},
573 :parent => {:tag => 'head'}
574
575 Redmine::Hook.clear_listeners
576 end
577 end
General Comments 0
You need to be logged in to leave comments. Login now