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