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