##// END OF EJS Templates
Show shared versions when editing issues from different projects with the context menu (#11345)....
Jean-Philippe Lang -
r9778:23a1ef543fcf
parent child
Show More
@@ -1,84 +1,85
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 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 class ContextMenusController < ApplicationController
18 class ContextMenusController < ApplicationController
19 helper :watchers
19 helper :watchers
20 helper :issues
20 helper :issues
21
21
22 def issues
22 def issues
23 @issues = Issue.visible.all(:conditions => {:id => params[:ids]}, :include => :project)
23 @issues = Issue.visible.all(:conditions => {:id => params[:ids]}, :include => :project)
24 if (@issues.size == 1)
24 if (@issues.size == 1)
25 @issue = @issues.first
25 @issue = @issues.first
26 end
26 end
27
27
28 @allowed_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&)
28 @allowed_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&)
29 @projects = @issues.collect(&:project).compact.uniq
29 @projects = @issues.collect(&:project).compact.uniq
30 @project = @projects.first if @projects.size == 1
30 @project = @projects.first if @projects.size == 1
31
31
32 @can = {:edit => User.current.allowed_to?(:edit_issues, @projects),
32 @can = {:edit => User.current.allowed_to?(:edit_issues, @projects),
33 :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
33 :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
34 :update => (User.current.allowed_to?(:edit_issues, @projects) || (User.current.allowed_to?(:change_status, @projects) && !@allowed_statuses.blank?)),
34 :update => (User.current.allowed_to?(:edit_issues, @projects) || (User.current.allowed_to?(:change_status, @projects) && !@allowed_statuses.blank?)),
35 :move => (@project && User.current.allowed_to?(:move_issues, @project)),
35 :move => (@project && User.current.allowed_to?(:move_issues, @project)),
36 :copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
36 :copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
37 :delete => User.current.allowed_to?(:delete_issues, @projects)
37 :delete => User.current.allowed_to?(:delete_issues, @projects)
38 }
38 }
39 if @project
39 if @project
40 if @issue
40 if @issue
41 @assignables = @issue.assignable_users
41 @assignables = @issue.assignable_users
42 else
42 else
43 @assignables = @project.assignable_users
43 @assignables = @project.assignable_users
44 end
44 end
45 @trackers = @project.trackers
45 @trackers = @project.trackers
46 else
46 else
47 #when multiple projects, we only keep the intersection of each set
47 #when multiple projects, we only keep the intersection of each set
48 @assignables = @projects.map(&:assignable_users).reduce(:&)
48 @assignables = @projects.map(&:assignable_users).reduce(:&)
49 @trackers = @projects.map(&:trackers).reduce(:&)
49 @trackers = @projects.map(&:trackers).reduce(:&)
50 end
50 end
51 @versions = @projects.map {|p| p.shared_versions.open}.reduce(:&)
51
52
52 @priorities = IssuePriority.active.reverse
53 @priorities = IssuePriority.active.reverse
53 @back = back_url
54 @back = back_url
54
55
55 @options_by_custom_field = {}
56 @options_by_custom_field = {}
56 if @can[:edit]
57 if @can[:edit]
57 custom_fields = @issues.map(&:available_custom_fields).reduce(:&).select do |f|
58 custom_fields = @issues.map(&:available_custom_fields).reduce(:&).select do |f|
58 %w(bool list user version).include?(f.field_format) && !f.multiple?
59 %w(bool list user version).include?(f.field_format) && !f.multiple?
59 end
60 end
60 custom_fields.each do |field|
61 custom_fields.each do |field|
61 values = field.possible_values_options(@projects)
62 values = field.possible_values_options(@projects)
62 if values.any?
63 if values.any?
63 @options_by_custom_field[field] = values
64 @options_by_custom_field[field] = values
64 end
65 end
65 end
66 end
66 end
67 end
67
68
68 @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&)
69 @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&)
69 render :layout => false
70 render :layout => false
70 end
71 end
71
72
72 def time_entries
73 def time_entries
73 @time_entries = TimeEntry.all(
74 @time_entries = TimeEntry.all(
74 :conditions => {:id => params[:ids]}, :include => :project)
75 :conditions => {:id => params[:ids]}, :include => :project)
75 @projects = @time_entries.collect(&:project).compact.uniq
76 @projects = @time_entries.collect(&:project).compact.uniq
76 @project = @projects.first if @projects.size == 1
77 @project = @projects.first if @projects.size == 1
77 @activities = TimeEntryActivity.shared.active
78 @activities = TimeEntryActivity.shared.active
78 @can = {:edit => User.current.allowed_to?(:edit_time_entries, @projects),
79 @can = {:edit => User.current.allowed_to?(:edit_time_entries, @projects),
79 :delete => User.current.allowed_to?(:edit_time_entries, @projects)
80 :delete => User.current.allowed_to?(:edit_time_entries, @projects)
80 }
81 }
81 @back = back_url
82 @back = back_url
82 render :layout => false
83 render :layout => false
83 end
84 end
84 end
85 end
@@ -1,142 +1,141
1 <ul>
1 <ul>
2 <%= call_hook(:view_issues_context_menu_start, {:issues => @issues, :can => @can, :back => @back }) %>
2 <%= call_hook(:view_issues_context_menu_start, {:issues => @issues, :can => @can, :back => @back }) %>
3
3
4 <% if !@issue.nil? -%>
4 <% if !@issue.nil? -%>
5 <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue},
5 <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue},
6 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
6 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
7 <% else %>
7 <% else %>
8 <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id)},
8 <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id)},
9 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
9 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
10 <% end %>
10 <% end %>
11
11
12 <% if @allowed_statuses.present? %>
12 <% if @allowed_statuses.present? %>
13 <li class="folder">
13 <li class="folder">
14 <a href="#" class="submenu"><%= l(:field_status) %></a>
14 <a href="#" class="submenu"><%= l(:field_status) %></a>
15 <ul>
15 <ul>
16 <% @allowed_statuses.each do |s| -%>
16 <% @allowed_statuses.each do |s| -%>
17 <li><%= context_menu_link h(s.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {:status_id => s}, :back_url => @back}, :method => :post,
17 <li><%= context_menu_link h(s.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {:status_id => s}, :back_url => @back}, :method => :post,
18 :selected => (@issue && s == @issue.status), :disabled => !@can[:update] %></li>
18 :selected => (@issue && s == @issue.status), :disabled => !@can[:update] %></li>
19 <% end -%>
19 <% end -%>
20 </ul>
20 </ul>
21 </li>
21 </li>
22 <% end %>
22 <% end %>
23
23
24 <% unless @trackers.nil? %>
24 <% unless @trackers.nil? %>
25 <li class="folder">
25 <li class="folder">
26 <a href="#" class="submenu"><%= l(:field_tracker) %></a>
26 <a href="#" class="submenu"><%= l(:field_tracker) %></a>
27 <ul>
27 <ul>
28 <% @trackers.each do |t| -%>
28 <% @trackers.each do |t| -%>
29 <li><%= context_menu_link h(t.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'tracker_id' => t}, :back_url => @back}, :method => :post,
29 <li><%= context_menu_link h(t.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'tracker_id' => t}, :back_url => @back}, :method => :post,
30 :selected => (@issue && t == @issue.tracker), :disabled => !@can[:edit] %></li>
30 :selected => (@issue && t == @issue.tracker), :disabled => !@can[:edit] %></li>
31 <% end -%>
31 <% end -%>
32 </ul>
32 </ul>
33 </li>
33 </li>
34 <% end %>
34 <% end %>
35
35
36 <% if @safe_attributes.include?('priority_id') -%>
36 <% if @safe_attributes.include?('priority_id') -%>
37 <li class="folder">
37 <li class="folder">
38 <a href="#" class="submenu"><%= l(:field_priority) %></a>
38 <a href="#" class="submenu"><%= l(:field_priority) %></a>
39 <ul>
39 <ul>
40 <% @priorities.each do |p| -%>
40 <% @priorities.each do |p| -%>
41 <li><%= context_menu_link h(p.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'priority_id' => p}, :back_url => @back}, :method => :post,
41 <li><%= context_menu_link h(p.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'priority_id' => p}, :back_url => @back}, :method => :post,
42 :selected => (@issue && p == @issue.priority), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
42 :selected => (@issue && p == @issue.priority), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
43 <% end -%>
43 <% end -%>
44 </ul>
44 </ul>
45 </li>
45 </li>
46 <% end %>
46 <% end %>
47
47
48 <% #TODO: allow editing versions when multiple projects %>
48 <% if @safe_attributes.include?('fixed_version_id') && @versions.any? -%>
49 <% if @safe_attributes.include?('fixed_version_id') && @project && @project.shared_versions.open.any? -%>
50 <li class="folder">
49 <li class="folder">
51 <a href="#" class="submenu"><%= l(:field_fixed_version) %></a>
50 <a href="#" class="submenu"><%= l(:field_fixed_version) %></a>
52 <ul>
51 <ul>
53 <% @project.shared_versions.open.sort.each do |v| -%>
52 <% @versions.sort.each do |v| -%>
54 <li><%= context_menu_link format_version_name(v), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'fixed_version_id' => v}, :back_url => @back}, :method => :post,
53 <li><%= context_menu_link format_version_name(v), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'fixed_version_id' => v}, :back_url => @back}, :method => :post,
55 :selected => (@issue && v == @issue.fixed_version), :disabled => !@can[:update] %></li>
54 :selected => (@issue && v == @issue.fixed_version), :disabled => !@can[:update] %></li>
56 <% end -%>
55 <% end -%>
57 <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'fixed_version_id' => 'none'}, :back_url => @back}, :method => :post,
56 <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'fixed_version_id' => 'none'}, :back_url => @back}, :method => :post,
58 :selected => (@issue && @issue.fixed_version.nil?), :disabled => !@can[:update] %></li>
57 :selected => (@issue && @issue.fixed_version.nil?), :disabled => !@can[:update] %></li>
59 </ul>
58 </ul>
60 </li>
59 </li>
61 <% end %>
60 <% end %>
62
61
63 <% if @safe_attributes.include?('assigned_to_id') && @assignables.present? -%>
62 <% if @safe_attributes.include?('assigned_to_id') && @assignables.present? -%>
64 <li class="folder">
63 <li class="folder">
65 <a href="#" class="submenu"><%= l(:field_assigned_to) %></a>
64 <a href="#" class="submenu"><%= l(:field_assigned_to) %></a>
66 <ul>
65 <ul>
67 <% if @assignables.include?(User.current) %>
66 <% if @assignables.include?(User.current) %>
68 <li><%= context_menu_link "<< #{l(:label_me)} >>", {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => User.current}, :back_url => @back}, :method => :post,
67 <li><%= context_menu_link "<< #{l(:label_me)} >>", {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => User.current}, :back_url => @back}, :method => :post,
69 :disabled => !@can[:update] %></li>
68 :disabled => !@can[:update] %></li>
70 <% end %>
69 <% end %>
71 <% @assignables.each do |u| -%>
70 <% @assignables.each do |u| -%>
72 <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => u}, :back_url => @back}, :method => :post,
71 <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => u}, :back_url => @back}, :method => :post,
73 :selected => (@issue && u == @issue.assigned_to), :disabled => !@can[:update] %></li>
72 :selected => (@issue && u == @issue.assigned_to), :disabled => !@can[:update] %></li>
74 <% end -%>
73 <% end -%>
75 <li><%= context_menu_link l(:label_nobody), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => 'none'}, :back_url => @back}, :method => :post,
74 <li><%= context_menu_link l(:label_nobody), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => 'none'}, :back_url => @back}, :method => :post,
76 :selected => (@issue && @issue.assigned_to.nil?), :disabled => !@can[:update] %></li>
75 :selected => (@issue && @issue.assigned_to.nil?), :disabled => !@can[:update] %></li>
77 </ul>
76 </ul>
78 </li>
77 </li>
79 <% end %>
78 <% end %>
80
79
81 <% if @safe_attributes.include?('category_id') && @project && @project.issue_categories.any? -%>
80 <% if @safe_attributes.include?('category_id') && @project && @project.issue_categories.any? -%>
82 <li class="folder">
81 <li class="folder">
83 <a href="#" class="submenu"><%= l(:field_category) %></a>
82 <a href="#" class="submenu"><%= l(:field_category) %></a>
84 <ul>
83 <ul>
85 <% @project.issue_categories.each do |u| -%>
84 <% @project.issue_categories.each do |u| -%>
86 <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'category_id' => u}, :back_url => @back}, :method => :post,
85 <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'category_id' => u}, :back_url => @back}, :method => :post,
87 :selected => (@issue && u == @issue.category), :disabled => !@can[:update] %></li>
86 :selected => (@issue && u == @issue.category), :disabled => !@can[:update] %></li>
88 <% end -%>
87 <% end -%>
89 <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'category_id' => 'none'}, :back_url => @back}, :method => :post,
88 <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'category_id' => 'none'}, :back_url => @back}, :method => :post,
90 :selected => (@issue && @issue.category.nil?), :disabled => !@can[:update] %></li>
89 :selected => (@issue && @issue.category.nil?), :disabled => !@can[:update] %></li>
91 </ul>
90 </ul>
92 </li>
91 </li>
93 <% end -%>
92 <% end -%>
94
93
95 <% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %>
94 <% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %>
96 <li class="folder">
95 <li class="folder">
97 <a href="#" class="submenu"><%= l(:field_done_ratio) %></a>
96 <a href="#" class="submenu"><%= l(:field_done_ratio) %></a>
98 <ul>
97 <ul>
99 <% (0..10).map{|x|x*10}.each do |p| -%>
98 <% (0..10).map{|x|x*10}.each do |p| -%>
100 <li><%= context_menu_link "#{p}%", {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'done_ratio' => p}, :back_url => @back}, :method => :post,
99 <li><%= context_menu_link "#{p}%", {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'done_ratio' => p}, :back_url => @back}, :method => :post,
101 :selected => (@issue && p == @issue.done_ratio), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
100 :selected => (@issue && p == @issue.done_ratio), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
102 <% end -%>
101 <% end -%>
103 </ul>
102 </ul>
104 </li>
103 </li>
105 <% end %>
104 <% end %>
106
105
107 <% @options_by_custom_field.each do |field, options| %>
106 <% @options_by_custom_field.each do |field, options| %>
108 <li class="folder">
107 <li class="folder">
109 <a href="#" class="submenu"><%= h(field.name) %></a>
108 <a href="#" class="submenu"><%= h(field.name) %></a>
110 <ul>
109 <ul>
111 <% options.each do |text, value| %>
110 <% options.each do |text, value| %>
112 <li><%= bulk_update_custom_field_context_menu_link(field, text, value || text) %></li>
111 <li><%= bulk_update_custom_field_context_menu_link(field, text, value || text) %></li>
113 <% end %>
112 <% end %>
114 <% unless field.is_required? %>
113 <% unless field.is_required? %>
115 <li><%= bulk_update_custom_field_context_menu_link(field, l(:label_none), '') %></li>
114 <li><%= bulk_update_custom_field_context_menu_link(field, l(:label_none), '') %></li>
116 <% end %>
115 <% end %>
117 </ul>
116 </ul>
118 </li>
117 </li>
119 <% end %>
118 <% end %>
120
119
121 <% if !@issue.nil? %>
120 <% if !@issue.nil? %>
122 <% if @can[:log_time] -%>
121 <% if @can[:log_time] -%>
123 <li><%= context_menu_link l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue},
122 <li><%= context_menu_link l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue},
124 :class => 'icon-time-add' %></li>
123 :class => 'icon-time-add' %></li>
125 <% end %>
124 <% end %>
126 <% if User.current.logged? %>
125 <% if User.current.logged? %>
127 <li><%= watcher_link(@issue, User.current) %></li>
126 <li><%= watcher_link(@issue, User.current) %></li>
128 <% end %>
127 <% end %>
129 <% end %>
128 <% end %>
130
129
131 <% if @issue.present? %>
130 <% if @issue.present? %>
132 <li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue},
131 <li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue},
133 :class => 'icon-copy', :disabled => !@can[:copy] %></li>
132 :class => 'icon-copy', :disabled => !@can[:copy] %></li>
134 <% else %>
133 <% else %>
135 <li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :copy => '1'},
134 <li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :copy => '1'},
136 :class => 'icon-copy', :disabled => !@can[:move] %></li>
135 :class => 'icon-copy', :disabled => !@can[:move] %></li>
137 <% end %>
136 <% end %>
138 <li><%= context_menu_link l(:button_delete), issues_path(:ids => @issues.collect(&:id), :back_url => @back),
137 <li><%= context_menu_link l(:button_delete), issues_path(:ids => @issues.collect(&:id), :back_url => @back),
139 :method => :delete, :data => {:confirm => issues_destroy_confirmation_message(@issues)}, :class => 'icon-del', :disabled => !@can[:delete] %></li>
138 :method => :delete, :data => {:confirm => issues_destroy_confirmation_message(@issues)}, :class => 'icon-del', :disabled => !@can[:delete] %></li>
140
139
141 <%= call_hook(:view_issues_context_menu_end, {:issues => @issues, :can => @can, :back => @back }) %>
140 <%= call_hook(:view_issues_context_menu_end, {:issues => @issues, :can => @can, :back => @back }) %>
142 </ul>
141 </ul>
@@ -1,251 +1,263
1 require File.expand_path('../../test_helper', __FILE__)
1 require File.expand_path('../../test_helper', __FILE__)
2
2
3 class ContextMenusControllerTest < ActionController::TestCase
3 class ContextMenusControllerTest < ActionController::TestCase
4 fixtures :projects,
4 fixtures :projects,
5 :trackers,
5 :trackers,
6 :projects_trackers,
6 :projects_trackers,
7 :roles,
7 :roles,
8 :member_roles,
8 :member_roles,
9 :members,
9 :members,
10 :enabled_modules,
10 :enabled_modules,
11 :workflows,
11 :workflows,
12 :journals, :journal_details,
12 :journals, :journal_details,
13 :versions,
13 :versions,
14 :issues, :issue_statuses, :issue_categories,
14 :issues, :issue_statuses, :issue_categories,
15 :users,
15 :users,
16 :enumerations,
16 :enumerations,
17 :time_entries
17 :time_entries
18
18
19 def test_context_menu_one_issue
19 def test_context_menu_one_issue
20 @request.session[:user_id] = 2
20 @request.session[:user_id] = 2
21 get :issues, :ids => [1]
21 get :issues, :ids => [1]
22 assert_response :success
22 assert_response :success
23 assert_template 'context_menu'
23 assert_template 'context_menu'
24 assert_tag :tag => 'a', :content => 'Edit',
24 assert_tag :tag => 'a', :content => 'Edit',
25 :attributes => { :href => '/issues/1/edit',
25 :attributes => { :href => '/issues/1/edit',
26 :class => 'icon-edit' }
26 :class => 'icon-edit' }
27 assert_tag :tag => 'a', :content => 'Closed',
27 assert_tag :tag => 'a', :content => 'Closed',
28 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bstatus_id%5D=5',
28 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bstatus_id%5D=5',
29 :class => '' }
29 :class => '' }
30 assert_tag :tag => 'a', :content => 'Immediate',
30 assert_tag :tag => 'a', :content => 'Immediate',
31 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8',
31 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8',
32 :class => '' }
32 :class => '' }
33 assert_no_tag :tag => 'a', :content => 'Inactive Priority'
33 assert_no_tag :tag => 'a', :content => 'Inactive Priority'
34 # Versions
34 # Versions
35 assert_tag :tag => 'a', :content => '2.0',
35 assert_tag :tag => 'a', :content => '2.0',
36 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3',
36 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3',
37 :class => '' }
37 :class => '' }
38 assert_tag :tag => 'a', :content => 'eCookbook Subproject 1 - 2.0',
38 assert_tag :tag => 'a', :content => 'eCookbook Subproject 1 - 2.0',
39 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4',
39 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4',
40 :class => '' }
40 :class => '' }
41
41
42 assert_tag :tag => 'a', :content => 'Dave Lopper',
42 assert_tag :tag => 'a', :content => 'Dave Lopper',
43 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3',
43 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3',
44 :class => '' }
44 :class => '' }
45 assert_tag :tag => 'a', :content => 'Copy',
45 assert_tag :tag => 'a', :content => 'Copy',
46 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
46 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
47 :class => 'icon-copy' }
47 :class => 'icon-copy' }
48 assert_no_tag :tag => 'a', :content => 'Move'
48 assert_no_tag :tag => 'a', :content => 'Move'
49 assert_tag :tag => 'a', :content => 'Delete',
49 assert_tag :tag => 'a', :content => 'Delete',
50 :attributes => { :href => '/issues?ids%5B%5D=1',
50 :attributes => { :href => '/issues?ids%5B%5D=1',
51 :class => 'icon-del' }
51 :class => 'icon-del' }
52 end
52 end
53
53
54 def test_context_menu_one_issue_by_anonymous
54 def test_context_menu_one_issue_by_anonymous
55 get :issues, :ids => [1]
55 get :issues, :ids => [1]
56 assert_response :success
56 assert_response :success
57 assert_template 'context_menu'
57 assert_template 'context_menu'
58 assert_tag :tag => 'a', :content => 'Delete',
58 assert_tag :tag => 'a', :content => 'Delete',
59 :attributes => { :href => '#',
59 :attributes => { :href => '#',
60 :class => 'icon-del disabled' }
60 :class => 'icon-del disabled' }
61 end
61 end
62
62
63 def test_context_menu_multiple_issues_of_same_project
63 def test_context_menu_multiple_issues_of_same_project
64 @request.session[:user_id] = 2
64 @request.session[:user_id] = 2
65 get :issues, :ids => [1, 2]
65 get :issues, :ids => [1, 2]
66 assert_response :success
66 assert_response :success
67 assert_template 'context_menu'
67 assert_template 'context_menu'
68 assert_not_nil assigns(:issues)
68 assert_not_nil assigns(:issues)
69 assert_equal [1, 2], assigns(:issues).map(&:id).sort
69 assert_equal [1, 2], assigns(:issues).map(&:id).sort
70
70
71 ids = assigns(:issues).map(&:id).map {|i| "ids%5B%5D=#{i}"}.join('&amp;')
71 ids = assigns(:issues).map(&:id).map {|i| "ids%5B%5D=#{i}"}.join('&amp;')
72 assert_tag :tag => 'a', :content => 'Edit',
72 assert_tag :tag => 'a', :content => 'Edit',
73 :attributes => { :href => "/issues/bulk_edit?#{ids}",
73 :attributes => { :href => "/issues/bulk_edit?#{ids}",
74 :class => 'icon-edit' }
74 :class => 'icon-edit' }
75 assert_tag :tag => 'a', :content => 'Closed',
75 assert_tag :tag => 'a', :content => 'Closed',
76 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bstatus_id%5D=5",
76 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bstatus_id%5D=5",
77 :class => '' }
77 :class => '' }
78 assert_tag :tag => 'a', :content => 'Immediate',
78 assert_tag :tag => 'a', :content => 'Immediate',
79 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bpriority_id%5D=8",
79 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bpriority_id%5D=8",
80 :class => '' }
80 :class => '' }
81 assert_tag :tag => 'a', :content => 'Dave Lopper',
81 assert_tag :tag => 'a', :content => 'Dave Lopper',
82 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bassigned_to_id%5D=3",
82 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bassigned_to_id%5D=3",
83 :class => '' }
83 :class => '' }
84 assert_tag :tag => 'a', :content => 'Copy',
84 assert_tag :tag => 'a', :content => 'Copy',
85 :attributes => { :href => "/issues/bulk_edit?copy=1&amp;#{ids}",
85 :attributes => { :href => "/issues/bulk_edit?copy=1&amp;#{ids}",
86 :class => 'icon-copy' }
86 :class => 'icon-copy' }
87 assert_no_tag :tag => 'a', :content => 'Move'
87 assert_no_tag :tag => 'a', :content => 'Move'
88 assert_tag :tag => 'a', :content => 'Delete',
88 assert_tag :tag => 'a', :content => 'Delete',
89 :attributes => { :href => "/issues?#{ids}",
89 :attributes => { :href => "/issues?#{ids}",
90 :class => 'icon-del' }
90 :class => 'icon-del' }
91 end
91 end
92
92
93 def test_context_menu_multiple_issues_of_different_projects
93 def test_context_menu_multiple_issues_of_different_projects
94 @request.session[:user_id] = 2
94 @request.session[:user_id] = 2
95 get :issues, :ids => [1, 2, 6]
95 get :issues, :ids => [1, 2, 6]
96 assert_response :success
96 assert_response :success
97 assert_template 'context_menu'
97 assert_template 'context_menu'
98 assert_not_nil assigns(:issues)
98 assert_not_nil assigns(:issues)
99 assert_equal [1, 2, 6], assigns(:issues).map(&:id).sort
99 assert_equal [1, 2, 6], assigns(:issues).map(&:id).sort
100
100
101 ids = assigns(:issues).map(&:id).map {|i| "ids%5B%5D=#{i}"}.join('&amp;')
101 ids = assigns(:issues).map(&:id).map {|i| "ids%5B%5D=#{i}"}.join('&amp;')
102 assert_tag :tag => 'a', :content => 'Edit',
102 assert_tag :tag => 'a', :content => 'Edit',
103 :attributes => { :href => "/issues/bulk_edit?#{ids}",
103 :attributes => { :href => "/issues/bulk_edit?#{ids}",
104 :class => 'icon-edit' }
104 :class => 'icon-edit' }
105 assert_tag :tag => 'a', :content => 'Closed',
105 assert_tag :tag => 'a', :content => 'Closed',
106 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bstatus_id%5D=5",
106 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bstatus_id%5D=5",
107 :class => '' }
107 :class => '' }
108 assert_tag :tag => 'a', :content => 'Immediate',
108 assert_tag :tag => 'a', :content => 'Immediate',
109 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bpriority_id%5D=8",
109 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bpriority_id%5D=8",
110 :class => '' }
110 :class => '' }
111 assert_tag :tag => 'a', :content => 'John Smith',
111 assert_tag :tag => 'a', :content => 'John Smith',
112 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bassigned_to_id%5D=2",
112 :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bassigned_to_id%5D=2",
113 :class => '' }
113 :class => '' }
114 assert_tag :tag => 'a', :content => 'Delete',
114 assert_tag :tag => 'a', :content => 'Delete',
115 :attributes => { :href => "/issues?#{ids}",
115 :attributes => { :href => "/issues?#{ids}",
116 :class => 'icon-del' }
116 :class => 'icon-del' }
117 end
117 end
118
118
119 def test_context_menu_should_include_list_custom_fields
119 def test_context_menu_should_include_list_custom_fields
120 field = IssueCustomField.create!(:name => 'List', :field_format => 'list',
120 field = IssueCustomField.create!(:name => 'List', :field_format => 'list',
121 :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
121 :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
122 @request.session[:user_id] = 2
122 @request.session[:user_id] = 2
123 get :issues, :ids => [1]
123 get :issues, :ids => [1]
124
124
125 assert_tag 'a',
125 assert_tag 'a',
126 :content => 'List',
126 :content => 'List',
127 :attributes => {:href => '#'},
127 :attributes => {:href => '#'},
128 :sibling => {:tag => 'ul', :children => {:count => 3}}
128 :sibling => {:tag => 'ul', :children => {:count => 3}}
129
129
130 assert_tag 'a',
130 assert_tag 'a',
131 :content => 'Foo',
131 :content => 'Foo',
132 :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=Foo"}
132 :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=Foo"}
133 assert_tag 'a',
133 assert_tag 'a',
134 :content => 'none',
134 :content => 'none',
135 :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D="}
135 :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D="}
136 end
136 end
137
137
138 def test_context_menu_should_not_include_null_value_for_required_custom_fields
138 def test_context_menu_should_not_include_null_value_for_required_custom_fields
139 field = IssueCustomField.create!(:name => 'List', :is_required => true, :field_format => 'list',
139 field = IssueCustomField.create!(:name => 'List', :is_required => true, :field_format => 'list',
140 :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
140 :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
141 @request.session[:user_id] = 2
141 @request.session[:user_id] = 2
142 get :issues, :ids => [1, 2]
142 get :issues, :ids => [1, 2]
143
143
144 assert_tag 'a',
144 assert_tag 'a',
145 :content => 'List',
145 :content => 'List',
146 :attributes => {:href => '#'},
146 :attributes => {:href => '#'},
147 :sibling => {:tag => 'ul', :children => {:count => 2}}
147 :sibling => {:tag => 'ul', :children => {:count => 2}}
148 end
148 end
149
149
150 def test_context_menu_on_single_issue_should_select_current_custom_field_value
150 def test_context_menu_on_single_issue_should_select_current_custom_field_value
151 field = IssueCustomField.create!(:name => 'List', :field_format => 'list',
151 field = IssueCustomField.create!(:name => 'List', :field_format => 'list',
152 :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
152 :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
153 issue = Issue.find(1)
153 issue = Issue.find(1)
154 issue.custom_field_values = {field.id => 'Bar'}
154 issue.custom_field_values = {field.id => 'Bar'}
155 issue.save!
155 issue.save!
156 @request.session[:user_id] = 2
156 @request.session[:user_id] = 2
157 get :issues, :ids => [1]
157 get :issues, :ids => [1]
158
158
159 assert_tag 'a',
159 assert_tag 'a',
160 :content => 'List',
160 :content => 'List',
161 :attributes => {:href => '#'},
161 :attributes => {:href => '#'},
162 :sibling => {:tag => 'ul', :children => {:count => 3}}
162 :sibling => {:tag => 'ul', :children => {:count => 3}}
163 assert_tag 'a',
163 assert_tag 'a',
164 :content => 'Bar',
164 :content => 'Bar',
165 :attributes => {:class => /icon-checked/}
165 :attributes => {:class => /icon-checked/}
166 end
166 end
167
167
168 def test_context_menu_should_include_bool_custom_fields
168 def test_context_menu_should_include_bool_custom_fields
169 field = IssueCustomField.create!(:name => 'Bool', :field_format => 'bool',
169 field = IssueCustomField.create!(:name => 'Bool', :field_format => 'bool',
170 :is_for_all => true, :tracker_ids => [1, 2, 3])
170 :is_for_all => true, :tracker_ids => [1, 2, 3])
171 @request.session[:user_id] = 2
171 @request.session[:user_id] = 2
172 get :issues, :ids => [1]
172 get :issues, :ids => [1]
173
173
174 assert_tag 'a',
174 assert_tag 'a',
175 :content => 'Bool',
175 :content => 'Bool',
176 :attributes => {:href => '#'},
176 :attributes => {:href => '#'},
177 :sibling => {:tag => 'ul', :children => {:count => 3}}
177 :sibling => {:tag => 'ul', :children => {:count => 3}}
178
178
179 assert_tag 'a',
179 assert_tag 'a',
180 :content => 'Yes',
180 :content => 'Yes',
181 :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=1"}
181 :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=1"}
182 end
182 end
183
183
184 def test_context_menu_should_include_user_custom_fields
184 def test_context_menu_should_include_user_custom_fields
185 field = IssueCustomField.create!(:name => 'User', :field_format => 'user',
185 field = IssueCustomField.create!(:name => 'User', :field_format => 'user',
186 :is_for_all => true, :tracker_ids => [1, 2, 3])
186 :is_for_all => true, :tracker_ids => [1, 2, 3])
187 @request.session[:user_id] = 2
187 @request.session[:user_id] = 2
188 get :issues, :ids => [1]
188 get :issues, :ids => [1]
189
189
190 assert_tag 'a',
190 assert_tag 'a',
191 :content => 'User',
191 :content => 'User',
192 :attributes => {:href => '#'},
192 :attributes => {:href => '#'},
193 :sibling => {:tag => 'ul', :children => {:count => Project.find(1).members.count + 1}}
193 :sibling => {:tag => 'ul', :children => {:count => Project.find(1).members.count + 1}}
194
194
195 assert_tag 'a',
195 assert_tag 'a',
196 :content => 'John Smith',
196 :content => 'John Smith',
197 :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=2"}
197 :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=2"}
198 end
198 end
199
199
200 def test_context_menu_should_include_version_custom_fields
200 def test_context_menu_should_include_version_custom_fields
201 field = IssueCustomField.create!(:name => 'Version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1, 2, 3])
201 field = IssueCustomField.create!(:name => 'Version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1, 2, 3])
202 @request.session[:user_id] = 2
202 @request.session[:user_id] = 2
203 get :issues, :ids => [1]
203 get :issues, :ids => [1]
204
204
205 assert_tag 'a',
205 assert_tag 'a',
206 :content => 'Version',
206 :content => 'Version',
207 :attributes => {:href => '#'},
207 :attributes => {:href => '#'},
208 :sibling => {:tag => 'ul', :children => {:count => Project.find(1).shared_versions.count + 1}}
208 :sibling => {:tag => 'ul', :children => {:count => Project.find(1).shared_versions.count + 1}}
209
209
210 assert_tag 'a',
210 assert_tag 'a',
211 :content => '2.0',
211 :content => '2.0',
212 :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=3"}
212 :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=3"}
213 end
213 end
214
214
215 def test_context_menu_by_assignable_user_should_include_assigned_to_me_link
215 def test_context_menu_by_assignable_user_should_include_assigned_to_me_link
216 @request.session[:user_id] = 2
216 @request.session[:user_id] = 2
217 get :issues, :ids => [1]
217 get :issues, :ids => [1]
218 assert_response :success
218 assert_response :success
219 assert_template 'context_menu'
219 assert_template 'context_menu'
220
220
221 assert_tag :tag => 'a', :content => / me /,
221 assert_tag :tag => 'a', :content => / me /,
222 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=2',
222 :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=2',
223 :class => '' }
223 :class => '' }
224 end
224 end
225
225
226 def test_context_menu_should_propose_shared_versions_for_issues_from_different_projects
227 @request.session[:user_id] = 2
228 version = Version.create!(:name => 'Shared', :sharing => 'system', :project_id => 1)
229
230 get :issues, :ids => [1, 4]
231 assert_response :success
232 assert_template 'context_menu'
233
234 assert_include version, assigns(:versions)
235 assert_tag :tag => 'a', :content => 'eCookbook - Shared'
236 end
237
226 def test_context_menu_issue_visibility
238 def test_context_menu_issue_visibility
227 get :issues, :ids => [1, 4]
239 get :issues, :ids => [1, 4]
228 assert_response :success
240 assert_response :success
229 assert_template 'context_menu'
241 assert_template 'context_menu'
230 assert_equal [1], assigns(:issues).collect(&:id)
242 assert_equal [1], assigns(:issues).collect(&:id)
231 end
243 end
232
244
233 def test_time_entries_context_menu
245 def test_time_entries_context_menu
234 @request.session[:user_id] = 2
246 @request.session[:user_id] = 2
235 get :time_entries, :ids => [1, 2]
247 get :time_entries, :ids => [1, 2]
236 assert_response :success
248 assert_response :success
237 assert_template 'time_entries'
249 assert_template 'time_entries'
238 assert_tag 'a', :content => 'Edit'
250 assert_tag 'a', :content => 'Edit'
239 assert_no_tag 'a', :content => 'Edit', :attributes => {:class => /disabled/}
251 assert_no_tag 'a', :content => 'Edit', :attributes => {:class => /disabled/}
240 end
252 end
241
253
242 def test_time_entries_context_menu_without_edit_permission
254 def test_time_entries_context_menu_without_edit_permission
243 @request.session[:user_id] = 2
255 @request.session[:user_id] = 2
244 Role.find_by_name('Manager').remove_permission! :edit_time_entries
256 Role.find_by_name('Manager').remove_permission! :edit_time_entries
245
257
246 get :time_entries, :ids => [1, 2]
258 get :time_entries, :ids => [1, 2]
247 assert_response :success
259 assert_response :success
248 assert_template 'time_entries'
260 assert_template 'time_entries'
249 assert_tag 'a', :content => 'Edit', :attributes => {:class => /disabled/}
261 assert_tag 'a', :content => 'Edit', :attributes => {:class => /disabled/}
250 end
262 end
251 end
263 end
General Comments 0
You need to be logged in to leave comments. Login now