##// 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 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
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
@@ -1,567 +1,577
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 < ActionController::TestCase
25 25 fixtures :projects, :versions, :users, :roles, :members, :member_roles, :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_routing
38 38 assert_routing(
39 39 {:method => :get, :path => '/projects'},
40 40 :controller => 'projects', :action => 'index'
41 41 )
42 42 end
43 43
44 44 def test_index
45 45 get :index
46 46 assert_response :success
47 47 assert_template 'index'
48 48 assert_not_nil assigns(:projects)
49 49
50 50 assert_tag :ul, :child => {:tag => 'li',
51 51 :descendant => {:tag => 'a', :content => 'eCookbook'},
52 52 :child => { :tag => 'ul',
53 53 :descendant => { :tag => 'a',
54 54 :content => 'Child of private child'
55 55 }
56 56 }
57 57 }
58 58
59 59 assert_no_tag :a, :content => /Private child of eCookbook/
60 60 end
61 61
62 62 def test_index_atom_routing
63 63 assert_routing(
64 64 {:method => :get, :path => '/projects.atom'},
65 65 :controller => 'projects', :action => 'index', :format => 'atom'
66 66 )
67 67 end
68 68
69 69 def test_index_atom
70 70 get :index, :format => 'atom'
71 71 assert_response :success
72 72 assert_template 'common/feed.atom.rxml'
73 73 assert_select 'feed>title', :text => 'Redmine: Latest projects'
74 74 assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_by(User.current))
75 75 end
76 76
77 77 def test_add_routing
78 78 assert_routing(
79 79 {:method => :get, :path => '/projects/new'},
80 80 :controller => 'projects', :action => 'add'
81 81 )
82 82 assert_recognizes(
83 83 {:controller => 'projects', :action => 'add'},
84 84 {:method => :post, :path => '/projects/new'}
85 85 )
86 86 assert_recognizes(
87 87 {:controller => 'projects', :action => 'add'},
88 88 {:method => :post, :path => '/projects'}
89 89 )
90 90 end
91 91
92 92 def test_get_add
93 93 @request.session[:user_id] = 1
94 94 get :add
95 95 assert_response :success
96 96 assert_template 'add'
97 97 end
98 98
99 99 def test_get_add_by_non_admin
100 100 @request.session[:user_id] = 2
101 101 get :add
102 102 assert_response :success
103 103 assert_template 'add'
104 104 end
105 105
106 106 def test_post_add
107 107 @request.session[:user_id] = 1
108 108 post :add, :project => { :name => "blog",
109 109 :description => "weblog",
110 110 :identifier => "blog",
111 111 :is_public => 1,
112 112 :custom_field_values => { '3' => 'Beta' }
113 113 }
114 114 assert_redirected_to '/projects/blog/settings'
115 115
116 116 project = Project.find_by_name('blog')
117 117 assert_kind_of Project, project
118 118 assert_equal 'weblog', project.description
119 119 assert_equal true, project.is_public?
120 120 end
121 121
122 122 def test_post_add_by_non_admin
123 123 @request.session[:user_id] = 2
124 124 post :add, :project => { :name => "blog",
125 125 :description => "weblog",
126 126 :identifier => "blog",
127 127 :is_public => 1,
128 128 :custom_field_values => { '3' => 'Beta' }
129 129 }
130 130 assert_redirected_to '/projects/blog/settings'
131 131
132 132 project = Project.find_by_name('blog')
133 133 assert_kind_of Project, project
134 134 assert_equal 'weblog', project.description
135 135 assert_equal true, project.is_public?
136 136
137 137 # User should be added as a project member
138 138 assert User.find(2).member_of?(project)
139 139 assert_equal 1, project.members.size
140 140 end
141 141
142 142 def test_show_routing
143 143 assert_routing(
144 144 {:method => :get, :path => '/projects/test'},
145 145 :controller => 'projects', :action => 'show', :id => 'test'
146 146 )
147 147 end
148 148
149 149 def test_show_by_id
150 150 get :show, :id => 1
151 151 assert_response :success
152 152 assert_template 'show'
153 153 assert_not_nil assigns(:project)
154 154 end
155 155
156 156 def test_show_by_identifier
157 157 get :show, :id => 'ecookbook'
158 158 assert_response :success
159 159 assert_template 'show'
160 160 assert_not_nil assigns(:project)
161 161 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
162 162 end
163 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
164 174 def test_private_subprojects_hidden
165 175 get :show, :id => 'ecookbook'
166 176 assert_response :success
167 177 assert_template 'show'
168 178 assert_no_tag :tag => 'a', :content => /Private child/
169 179 end
170 180
171 181 def test_private_subprojects_visible
172 182 @request.session[:user_id] = 2 # manager who is a member of the private subproject
173 183 get :show, :id => 'ecookbook'
174 184 assert_response :success
175 185 assert_template 'show'
176 186 assert_tag :tag => 'a', :content => /Private child/
177 187 end
178 188
179 189 def test_settings_routing
180 190 assert_routing(
181 191 {:method => :get, :path => '/projects/4223/settings'},
182 192 :controller => 'projects', :action => 'settings', :id => '4223'
183 193 )
184 194 assert_routing(
185 195 {:method => :get, :path => '/projects/4223/settings/members'},
186 196 :controller => 'projects', :action => 'settings', :id => '4223', :tab => 'members'
187 197 )
188 198 end
189 199
190 200 def test_settings
191 201 @request.session[:user_id] = 2 # manager
192 202 get :settings, :id => 1
193 203 assert_response :success
194 204 assert_template 'settings'
195 205 end
196 206
197 207 def test_edit
198 208 @request.session[:user_id] = 2 # manager
199 209 post :edit, :id => 1, :project => {:name => 'Test changed name',
200 210 :issue_custom_field_ids => ['']}
201 211 assert_redirected_to 'projects/ecookbook/settings'
202 212 project = Project.find(1)
203 213 assert_equal 'Test changed name', project.name
204 214 end
205 215
206 216 def test_add_version_routing
207 217 assert_routing(
208 218 {:method => :get, :path => 'projects/64/versions/new'},
209 219 :controller => 'projects', :action => 'add_version', :id => '64'
210 220 )
211 221 assert_routing(
212 222 #TODO: use PUT
213 223 {:method => :post, :path => 'projects/64/versions/new'},
214 224 :controller => 'projects', :action => 'add_version', :id => '64'
215 225 )
216 226 end
217 227
218 228 def test_add_issue_category_routing
219 229 assert_routing(
220 230 {:method => :get, :path => 'projects/test/categories/new'},
221 231 :controller => 'projects', :action => 'add_issue_category', :id => 'test'
222 232 )
223 233 assert_routing(
224 234 #TODO: use PUT and update form
225 235 {:method => :post, :path => 'projects/64/categories/new'},
226 236 :controller => 'projects', :action => 'add_issue_category', :id => '64'
227 237 )
228 238 end
229 239
230 240 def test_destroy_routing
231 241 assert_routing(
232 242 {:method => :get, :path => '/projects/567/destroy'},
233 243 :controller => 'projects', :action => 'destroy', :id => '567'
234 244 )
235 245 assert_routing(
236 246 #TODO: use DELETE and update form
237 247 {:method => :post, :path => 'projects/64/destroy'},
238 248 :controller => 'projects', :action => 'destroy', :id => '64'
239 249 )
240 250 end
241 251
242 252 def test_get_destroy
243 253 @request.session[:user_id] = 1 # admin
244 254 get :destroy, :id => 1
245 255 assert_response :success
246 256 assert_template 'destroy'
247 257 assert_not_nil Project.find_by_id(1)
248 258 end
249 259
250 260 def test_post_destroy
251 261 @request.session[:user_id] = 1 # admin
252 262 post :destroy, :id => 1, :confirm => 1
253 263 assert_redirected_to 'admin/projects'
254 264 assert_nil Project.find_by_id(1)
255 265 end
256 266
257 267 def test_add_file
258 268 set_tmp_attachments_directory
259 269 @request.session[:user_id] = 2
260 270 Setting.notified_events = ['file_added']
261 271 ActionMailer::Base.deliveries.clear
262 272
263 273 assert_difference 'Attachment.count' do
264 274 post :add_file, :id => 1, :version_id => '',
265 275 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
266 276 end
267 277 assert_redirected_to 'projects/ecookbook/files'
268 278 a = Attachment.find(:first, :order => 'created_on DESC')
269 279 assert_equal 'testfile.txt', a.filename
270 280 assert_equal Project.find(1), a.container
271 281
272 282 mail = ActionMailer::Base.deliveries.last
273 283 assert_kind_of TMail::Mail, mail
274 284 assert_equal "[eCookbook] New file", mail.subject
275 285 assert mail.body.include?('testfile.txt')
276 286 end
277 287
278 288 def test_add_file_routing
279 289 assert_routing(
280 290 {:method => :get, :path => '/projects/33/files/new'},
281 291 :controller => 'projects', :action => 'add_file', :id => '33'
282 292 )
283 293 assert_routing(
284 294 {:method => :post, :path => '/projects/33/files/new'},
285 295 :controller => 'projects', :action => 'add_file', :id => '33'
286 296 )
287 297 end
288 298
289 299 def test_add_version_file
290 300 set_tmp_attachments_directory
291 301 @request.session[:user_id] = 2
292 302 Setting.notified_events = ['file_added']
293 303
294 304 assert_difference 'Attachment.count' do
295 305 post :add_file, :id => 1, :version_id => '2',
296 306 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
297 307 end
298 308 assert_redirected_to 'projects/ecookbook/files'
299 309 a = Attachment.find(:first, :order => 'created_on DESC')
300 310 assert_equal 'testfile.txt', a.filename
301 311 assert_equal Version.find(2), a.container
302 312 end
303 313
304 314 def test_list_files
305 315 get :list_files, :id => 1
306 316 assert_response :success
307 317 assert_template 'list_files'
308 318 assert_not_nil assigns(:containers)
309 319
310 320 # file attached to the project
311 321 assert_tag :a, :content => 'project_file.zip',
312 322 :attributes => { :href => '/attachments/download/8/project_file.zip' }
313 323
314 324 # file attached to a project's version
315 325 assert_tag :a, :content => 'version_file.zip',
316 326 :attributes => { :href => '/attachments/download/9/version_file.zip' }
317 327 end
318 328
319 329 def test_list_files_routing
320 330 assert_routing(
321 331 {:method => :get, :path => '/projects/33/files'},
322 332 :controller => 'projects', :action => 'list_files', :id => '33'
323 333 )
324 334 end
325 335
326 336 def test_changelog_routing
327 337 assert_routing(
328 338 {:method => :get, :path => '/projects/44/changelog'},
329 339 :controller => 'projects', :action => 'changelog', :id => '44'
330 340 )
331 341 end
332 342
333 343 def test_changelog
334 344 get :changelog, :id => 1
335 345 assert_response :success
336 346 assert_template 'changelog'
337 347 assert_not_nil assigns(:versions)
338 348 end
339 349
340 350 def test_roadmap_routing
341 351 assert_routing(
342 352 {:method => :get, :path => 'projects/33/roadmap'},
343 353 :controller => 'projects', :action => 'roadmap', :id => '33'
344 354 )
345 355 end
346 356
347 357 def test_roadmap
348 358 get :roadmap, :id => 1
349 359 assert_response :success
350 360 assert_template 'roadmap'
351 361 assert_not_nil assigns(:versions)
352 362 # Version with no date set appears
353 363 assert assigns(:versions).include?(Version.find(3))
354 364 # Completed version doesn't appear
355 365 assert !assigns(:versions).include?(Version.find(1))
356 366 end
357 367
358 368 def test_roadmap_with_completed_versions
359 369 get :roadmap, :id => 1, :completed => 1
360 370 assert_response :success
361 371 assert_template 'roadmap'
362 372 assert_not_nil assigns(:versions)
363 373 # Version with no date set appears
364 374 assert assigns(:versions).include?(Version.find(3))
365 375 # Completed version appears
366 376 assert assigns(:versions).include?(Version.find(1))
367 377 end
368 378
369 379 def test_project_activity_routing
370 380 assert_routing(
371 381 {:method => :get, :path => '/projects/1/activity'},
372 382 :controller => 'projects', :action => 'activity', :id => '1'
373 383 )
374 384 end
375 385
376 386 def test_project_activity_atom_routing
377 387 assert_routing(
378 388 {:method => :get, :path => '/projects/1/activity.atom'},
379 389 :controller => 'projects', :action => 'activity', :id => '1', :format => 'atom'
380 390 )
381 391 end
382 392
383 393 def test_project_activity
384 394 get :activity, :id => 1, :with_subprojects => 0
385 395 assert_response :success
386 396 assert_template 'activity'
387 397 assert_not_nil assigns(:events_by_day)
388 398
389 399 assert_tag :tag => "h3",
390 400 :content => /#{2.days.ago.to_date.day}/,
391 401 :sibling => { :tag => "dl",
392 402 :child => { :tag => "dt",
393 403 :attributes => { :class => /issue-edit/ },
394 404 :child => { :tag => "a",
395 405 :content => /(#{IssueStatus.find(2).name})/,
396 406 }
397 407 }
398 408 }
399 409 end
400 410
401 411 def test_previous_project_activity
402 412 get :activity, :id => 1, :from => 3.days.ago.to_date
403 413 assert_response :success
404 414 assert_template 'activity'
405 415 assert_not_nil assigns(:events_by_day)
406 416
407 417 assert_tag :tag => "h3",
408 418 :content => /#{3.day.ago.to_date.day}/,
409 419 :sibling => { :tag => "dl",
410 420 :child => { :tag => "dt",
411 421 :attributes => { :class => /issue/ },
412 422 :child => { :tag => "a",
413 423 :content => /#{Issue.find(1).subject}/,
414 424 }
415 425 }
416 426 }
417 427 end
418 428
419 429 def test_global_activity_routing
420 430 assert_routing({:method => :get, :path => '/activity'}, :controller => 'projects', :action => 'activity', :id => nil)
421 431 end
422 432
423 433 def test_global_activity
424 434 get :activity
425 435 assert_response :success
426 436 assert_template 'activity'
427 437 assert_not_nil assigns(:events_by_day)
428 438
429 439 assert_tag :tag => "h3",
430 440 :content => /#{5.day.ago.to_date.day}/,
431 441 :sibling => { :tag => "dl",
432 442 :child => { :tag => "dt",
433 443 :attributes => { :class => /issue/ },
434 444 :child => { :tag => "a",
435 445 :content => /#{Issue.find(5).subject}/,
436 446 }
437 447 }
438 448 }
439 449 end
440 450
441 451 def test_user_activity
442 452 get :activity, :user_id => 2
443 453 assert_response :success
444 454 assert_template 'activity'
445 455 assert_not_nil assigns(:events_by_day)
446 456
447 457 assert_tag :tag => "h3",
448 458 :content => /#{3.day.ago.to_date.day}/,
449 459 :sibling => { :tag => "dl",
450 460 :child => { :tag => "dt",
451 461 :attributes => { :class => /issue/ },
452 462 :child => { :tag => "a",
453 463 :content => /#{Issue.find(1).subject}/,
454 464 }
455 465 }
456 466 }
457 467 end
458 468
459 469 def test_global_activity_atom_routing
460 470 assert_routing({:method => :get, :path => '/activity.atom'}, :controller => 'projects', :action => 'activity', :id => nil, :format => 'atom')
461 471 end
462 472
463 473 def test_activity_atom_feed
464 474 get :activity, :format => 'atom'
465 475 assert_response :success
466 476 assert_template 'common/feed.atom.rxml'
467 477 end
468 478
469 479 def test_archive_routing
470 480 assert_routing(
471 481 #TODO: use PUT to project path and modify form
472 482 {:method => :post, :path => 'projects/64/archive'},
473 483 :controller => 'projects', :action => 'archive', :id => '64'
474 484 )
475 485 end
476 486
477 487 def test_archive
478 488 @request.session[:user_id] = 1 # admin
479 489 post :archive, :id => 1
480 490 assert_redirected_to 'admin/projects'
481 491 assert !Project.find(1).active?
482 492 end
483 493
484 494 def test_unarchive_routing
485 495 assert_routing(
486 496 #TODO: use PUT to project path and modify form
487 497 {:method => :post, :path => '/projects/567/unarchive'},
488 498 :controller => 'projects', :action => 'unarchive', :id => '567'
489 499 )
490 500 end
491 501
492 502 def test_unarchive
493 503 @request.session[:user_id] = 1 # admin
494 504 Project.find(1).archive
495 505 post :unarchive, :id => 1
496 506 assert_redirected_to 'admin/projects'
497 507 assert Project.find(1).active?
498 508 end
499 509
500 510 def test_project_breadcrumbs_should_be_limited_to_3_ancestors
501 511 CustomField.delete_all
502 512 parent = nil
503 513 6.times do |i|
504 514 p = Project.create!(:name => "Breadcrumbs #{i}", :identifier => "breadcrumbs-#{i}")
505 515 p.set_parent!(parent)
506 516 get :show, :id => p
507 517 assert_tag :h1, :parent => { :attributes => {:id => 'header'}},
508 518 :children => { :count => [i, 3].min,
509 519 :only => { :tag => 'a' } }
510 520
511 521 parent = p
512 522 end
513 523 end
514 524
515 525 def test_copy_with_project
516 526 @request.session[:user_id] = 1 # admin
517 527 get :copy, :id => 1
518 528 assert_response :success
519 529 assert_template 'copy'
520 530 assert assigns(:project)
521 531 assert_equal Project.find(1).description, assigns(:project).description
522 532 assert_nil assigns(:project).id
523 533 end
524 534
525 535 def test_copy_without_project
526 536 @request.session[:user_id] = 1 # admin
527 537 get :copy
528 538 assert_response :redirect
529 539 assert_redirected_to :controller => 'admin', :action => 'projects'
530 540 end
531 541
532 542 def test_jump_should_redirect_to_active_tab
533 543 get :show, :id => 1, :jump => 'issues'
534 544 assert_redirected_to 'projects/ecookbook/issues'
535 545 end
536 546
537 547 def test_jump_should_not_redirect_to_inactive_tab
538 548 get :show, :id => 3, :jump => 'documents'
539 549 assert_response :success
540 550 assert_template 'show'
541 551 end
542 552
543 553 def test_jump_should_not_redirect_to_unknown_tab
544 554 get :show, :id => 3, :jump => 'foobar'
545 555 assert_response :success
546 556 assert_template 'show'
547 557 end
548 558
549 559 # A hook that is manually registered later
550 560 class ProjectBasedTemplate < Redmine::Hook::ViewListener
551 561 def view_layouts_base_html_head(context)
552 562 # Adds a project stylesheet
553 563 stylesheet_link_tag(context[:project].identifier) if context[:project]
554 564 end
555 565 end
556 566 # Don't use this hook now
557 567 Redmine::Hook.clear_listeners
558 568
559 569 def test_hook_response
560 570 Redmine::Hook.add_listener(ProjectBasedTemplate)
561 571 get :show, :id => 1
562 572 assert_tag :tag => 'link', :attributes => {:href => '/stylesheets/ecookbook.css'},
563 573 :parent => {:tag => 'head'}
564 574
565 575 Redmine::Hook.clear_listeners
566 576 end
567 577 end
General Comments 0
You need to be logged in to leave comments. Login now