Feature #44581 » 0001-Make-project-members-page-available-to-all-users-wit.patch
| app/controllers/members_controller.rb | ||
|---|---|---|
| 20 | 20 |
class MembersController < ApplicationController |
| 21 | 21 |
self.model_object = Member |
| 22 | 22 | |
| 23 |
menu_item :overview |
|
| 24 | ||
| 23 | 25 |
before_action :find_model_object, :except => [:index, :new, :create, :autocomplete] |
| 24 | 26 |
before_action :find_project_from_association, :except => [:index, :new, :create, :autocomplete] |
| 25 | 27 |
before_action :find_project_by_project_id, :only => [:index, :new, :create, :autocomplete] |
| ... | ... | |
| 31 | 33 |
include MembersHelper |
| 32 | 34 | |
| 33 | 35 |
def index |
| 34 |
scope = @project.memberships |
|
| 35 |
@members = scope.includes(:principal, :roles).order(:id) |
|
| 36 | ||
| 37 | 36 |
respond_to do |format| |
| 38 |
format.html {head :not_acceptable}
|
|
| 37 |
format.html |
|
| 39 | 38 |
format.api do |
| 39 |
scope = @project.memberships |
|
| 40 |
@members = scope.includes(:principal, :roles).order(:id) |
|
| 40 | 41 |
@offset, @limit = api_offset_and_limit |
| 41 | 42 |
@member_count = scope.count |
| 42 | 43 |
@member_pages = Paginator.new @member_count, @limit, params['page'] |
| ... | ... | |
| 44 | 45 |
@members = @members.limit(@limit).offset(@offset).to_a |
| 45 | 46 |
end |
| 46 | 47 |
format.csv do |
| 47 |
send_data(members_to_csv(@members), type: 'text/csv; header=present', filename: "#{@project.identifier}-members.csv")
|
|
| 48 |
if User.current.allowed_to?(:manage_members, @project) |
|
| 49 |
scope = @project.memberships |
|
| 50 |
@members = scope.includes(:principal, :roles).order(:id) |
|
| 51 |
send_data(members_to_csv(@members), type: 'text/csv; header=present', filename: "#{@project.identifier}-members.csv")
|
|
| 52 |
else |
|
| 53 |
head :forbidden |
|
| 54 |
end |
|
| 48 | 55 |
end |
| 49 | 56 |
end |
| 50 | 57 |
end |
| app/helpers/members_helper.rb | ||
|---|---|---|
| 59 | 59 |
# Returns the scope of the members of project matching the filters |
| 60 | 60 |
# set in the request params |
| 61 | 61 |
def members_scope(project) |
| 62 |
project.memberships. |
|
| 63 |
like(params[:member_name]). |
|
| 64 |
with_role(params[:member_role_id]). |
|
| 65 |
status(params[:member_status]) |
|
| 62 |
scope = |
|
| 63 |
project.memberships. |
|
| 64 |
like(params[:member_name]). |
|
| 65 |
with_role(params[:member_role_id]) |
|
| 66 |
if User.current.allowed_to?(:manage_members, project) |
|
| 67 |
scope.status(params[:member_status]) |
|
| 68 |
else |
|
| 69 |
scope.active |
|
| 70 |
end |
|
| 66 | 71 |
end |
| 67 | 72 | |
| 68 | 73 |
# limit/offset on Member.sorted would paginate role join rows, not members |
| app/helpers/projects_helper.rb | ||
|---|---|---|
| 24 | 24 |
{:name => 'info', :action => :edit_project,
|
| 25 | 25 |
:partial => 'projects/edit', :label => :label_project}, |
| 26 | 26 |
{:name => 'members', :action => :manage_members,
|
| 27 |
:partial => 'projects/settings/members', :label => :label_member_plural,
|
|
| 27 |
:partial => 'members/members', :label => :label_member_plural,
|
|
| 28 | 28 |
:url => {:tab => 'members'}.merge(members_list_params)},
|
| 29 | 29 |
{:name => 'issues', :action => :edit_project, :module => :issue_tracking,
|
| 30 | 30 |
:partial => 'projects/settings/issues', :label => :label_issue_tracking}, |
| app/helpers/routes_helper.rb | ||
|---|---|---|
| 99 | 99 |
def board_path(board, *) |
| 100 | 100 |
project_board_path(board.project, board, *) |
| 101 | 101 |
end |
| 102 | ||
| 103 |
def _project_members_path(project, parameters = {})
|
|
| 104 |
params = parameters.is_a?(Hash) ? parameters.except('tab', :tab) : parameters
|
|
| 105 |
if controller_name == 'members' && action_name == 'index' |
|
| 106 |
project_members_path(project, params) |
|
| 107 |
else |
|
| 108 |
settings_project_path(project, 'members', params) |
|
| 109 |
end |
|
| 110 |
end |
|
| 102 | 111 |
end |
| app/views/members/_members.html.erb | ||
|---|---|---|
| 1 |
<% members, member_pages, member_count = paginate_members(members_scope(@project)) %> |
|
| 2 | ||
| 3 |
<% if User.current.admin? %> |
|
| 4 |
<div class="contextual"><%= link_to sprite_icon('settings', l(:label_administration)), users_path, :class => "icon icon-settings" %></div>
|
|
| 5 |
<% end %> |
|
| 6 | ||
| 7 |
<% if User.current.allowed_to?(:manage_members, @project) %> |
|
| 8 |
<p><%= link_to sprite_icon('add', l(:label_member_new)), new_project_membership_path(@project, members_list_params), :remote => true, :class => "icon icon-add" %></p>
|
|
| 9 |
<% end %> |
|
| 10 | ||
| 11 |
<%= form_tag(_project_members_path(@project), :method => :get, :id => 'members-filter-form') do %> |
|
| 12 |
<fieldset><legend><%= l(:label_filter_plural) %></legend> |
|
| 13 |
<label for='member_name'><%= l(:label_user) %> / <%= l(:label_group) %>:</label> |
|
| 14 |
<%= text_field_tag 'member_name', params[:member_name], :size => 20 %> |
|
| 15 |
<label for='member_role_id'><%= l(:label_role) %>:</label> |
|
| 16 |
<%= select_tag 'member_role_id', |
|
| 17 |
options_for_select([[l(:label_all), '']] + Role.givable.pluck(:name, :id), params[:member_role_id]), |
|
| 18 |
:onchange => "this.form.submit(); return false;" %> |
|
| 19 |
<% if User.current.allowed_to?(:manage_members, @project) %> |
|
| 20 |
<label for='member_status'><%= l(:field_status) %>:</label> |
|
| 21 |
<%= select_tag 'member_status', |
|
| 22 |
options_for_select(member_status_options, params[:member_status]), |
|
| 23 |
:onchange => "this.form.submit(); return false;" %> |
|
| 24 |
<% end %> |
|
| 25 |
<%= submit_tag l(:button_apply), :class => "small", :name => nil %> |
|
| 26 |
<%= link_to sprite_icon('reload', l(:button_clear)), _project_members_path(@project), :class => 'icon icon-reload' %>
|
|
| 27 |
</fieldset> |
|
| 28 |
<% end %> |
|
| 29 |
|
|
| 30 | ||
| 31 |
<% if member_count > 0 %> |
|
| 32 |
<div class="autoscroll"> |
|
| 33 |
<table class="list members"> |
|
| 34 |
<thead> |
|
| 35 |
<tr> |
|
| 36 |
<th><%= l(:label_user) %> / <%= l(:label_group) %></th> |
|
| 37 |
<th><%= l(:label_role_plural) %></th> |
|
| 38 |
<% if User.current.allowed_to?(:manage_members, @project) %> |
|
| 39 |
<th></th> |
|
| 40 |
<% end %> |
|
| 41 |
<%= call_hook(:view_projects_settings_members_table_header, :project => @project) %> |
|
| 42 |
</tr> |
|
| 43 |
</thead> |
|
| 44 |
<tbody> |
|
| 45 |
<% members.each do |member| %> |
|
| 46 |
<% next if member.new_record? %> |
|
| 47 |
<tr id="member-<%= member.id %>" class="member"> |
|
| 48 |
<td class="name"> |
|
| 49 |
<span class="icon"> |
|
| 50 |
<% if member.principal %> |
|
| 51 |
<%= link_to_principal member.principal %> |
|
| 52 |
<% end %> |
|
| 53 |
</span> |
|
| 54 |
</td> |
|
| 55 |
<td class="roles"> |
|
| 56 |
<span id="member-<%= member.id %>-roles"><%= member.roles.sort.collect(&:to_s).join(', ') %></span>
|
|
| 57 |
<div id="member-<%= member.id %>-form"></div> |
|
| 58 |
</td> |
|
| 59 |
<% if User.current.allowed_to?(:manage_members, @project) %> |
|
| 60 |
<td class="buttons"> |
|
| 61 |
<%= link_to sprite_icon('edit', l(:button_edit)),
|
|
| 62 |
edit_membership_path(member, members_list_params), |
|
| 63 |
:remote => true, |
|
| 64 |
:class => 'icon icon-edit' %> |
|
| 65 |
<%= remove_link membership_path(member, members_list_params), |
|
| 66 |
:remote => true, |
|
| 67 |
:data => (!User.current.admin? && member.include?(User.current) ? {:confirm => l(:text_own_membership_delete_confirmation)} : {}) if member.deletable? %>
|
|
| 68 |
</td> |
|
| 69 |
<% end %> |
|
| 70 |
<%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) if User.current.allowed_to?(:manage_members, @project) %>
|
|
| 71 |
</tr> |
|
| 72 |
<% end %> |
|
| 73 |
</tbody> |
|
| 74 |
</table> |
|
| 75 |
</div> |
|
| 76 |
<span class="pagination"> |
|
| 77 |
<%= pagination_links_full(member_pages, member_count) do |text, parameters, options| |
|
| 78 |
link_to text, _project_members_path(@project, request.query_parameters.merge(parameters)), options |
|
| 79 |
end %> |
|
| 80 |
</span> |
|
| 81 |
<% if User.current.allowed_to?(:manage_members, @project) %> |
|
| 82 |
<% other_formats_links do |f| %> |
|
| 83 |
<%= f.link_to_with_query_parameters "CSV", {}, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
|
|
| 84 |
<% end %> |
|
| 85 |
<div id="csv-export-options" style="display: none;"> |
|
| 86 |
<h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3> |
|
| 87 |
<%= form_tag(project_memberships_path(project_id: @project.id, format: 'csv'), :method => :get, :id => 'csv-export-form') do %> |
|
| 88 |
<%= export_csv_encoding_select_tag %> |
|
| 89 |
<p class="buttons"> |
|
| 90 |
<%= submit_tag l(:button_export), :name => nil, :onclick => 'hideModal(this);', :data => {:disable_with => false} %>
|
|
| 91 |
<%= link_to_function l(:button_cancel), 'hideModal(this);' %> |
|
| 92 |
</p> |
|
| 93 |
<% end %> |
|
| 94 |
</div> |
|
| 95 |
<% end %> |
|
| 96 |
<% else %> |
|
| 97 |
<p class="nodata"><%= l(:label_no_data) %></p> |
|
| 98 |
<% end %> |
|
| app/views/members/index.html.erb | ||
|---|---|---|
| 1 |
<h2><%= l(:label_member_plural) %></h2> |
|
| 2 | ||
| 3 |
<%= render :partial => 'members' %> |
|
| 4 | ||
| 5 |
<% html_title(l(:label_member_plural)) -%> |
|
| app/views/projects/_members_box.html.erb | ||
|---|---|---|
| 4 | 4 |
<% @principals_by_role.keys.sort.each do |role| %> |
| 5 | 5 |
<p><span class="label"><%= role %>:</span> <%= @principals_by_role[role].sort.collect{|p| link_to_principal(p, :class => p.is_a?(Group) ? 'icon icon-group' : nil)}.join(", ").html_safe %></p>
|
| 6 | 6 |
<% end %> |
| 7 |
<% if User.current.allowed_to?(:view_members, @project) %> |
|
| 8 |
<p><%= link_to l(:label_member_view_all), project_members_path(@project) %></p> |
|
| 9 |
<% end %> |
|
| 7 | 10 |
</div> |
| 8 | 11 |
<% end %> |
| app/views/projects/settings/_members.html.erb | ||
|---|---|---|
| 1 |
<% members, member_pages, member_count = paginate_members(members_scope(@project)) %> |
|
| 2 | ||
| 3 |
<% if User.current.admin? %> |
|
| 4 |
<div class="contextual"><%= link_to sprite_icon('settings', l(:label_administration)), users_path, :class => "icon icon-settings" %></div>
|
|
| 5 |
<% end %> |
|
| 6 |
<p><%= link_to sprite_icon('add', l(:label_member_new)), new_project_membership_path(@project, members_list_params), :remote => true, :class => "icon icon-add" %></p>
|
|
| 7 | ||
| 8 |
<%= form_tag(settings_project_path(@project, :tab => 'members'), :method => :get, :id => 'members-filter-form') do %> |
|
| 9 |
<fieldset><legend><%= l(:label_filter_plural) %></legend> |
|
| 10 |
<label for='member_name'><%= l(:label_user) %> / <%= l(:label_group) %>:</label> |
|
| 11 |
<%= text_field_tag 'member_name', params[:member_name], :size => 20 %> |
|
| 12 |
<label for='member_role_id'><%= l(:label_role) %>:</label> |
|
| 13 |
<%= select_tag 'member_role_id', |
|
| 14 |
options_for_select([[l(:label_all), '']] + Role.givable.pluck(:name, :id), params[:member_role_id]), |
|
| 15 |
:onchange => "this.form.submit(); return false;" %> |
|
| 16 |
<label for='member_status'><%= l(:field_status) %>:</label> |
|
| 17 |
<%= select_tag 'member_status', |
|
| 18 |
options_for_select(member_status_options, params[:member_status]), |
|
| 19 |
:onchange => "this.form.submit(); return false;" %> |
|
| 20 |
<%= submit_tag l(:button_apply), :class => "small", :name => nil %> |
|
| 21 |
<%= link_to sprite_icon('reload', l(:button_clear)), settings_project_path(@project, :tab => 'members'), :class => 'icon icon-reload' %>
|
|
| 22 |
</fieldset> |
|
| 23 |
<% end %> |
|
| 24 |
|
|
| 25 | ||
| 26 |
<% if member_count > 0 %> |
|
| 27 |
<div class="autoscroll"> |
|
| 28 |
<table class="list members"> |
|
| 29 |
<thead> |
|
| 30 |
<tr> |
|
| 31 |
<th><%= l(:label_user) %> / <%= l(:label_group) %></th> |
|
| 32 |
<th><%= l(:label_role_plural) %></th> |
|
| 33 |
<th></th> |
|
| 34 |
<%= call_hook(:view_projects_settings_members_table_header, :project => @project) %> |
|
| 35 |
</tr> |
|
| 36 |
</thead> |
|
| 37 |
<tbody> |
|
| 38 |
<% members.each do |member| %> |
|
| 39 |
<% next if member.new_record? %> |
|
| 40 |
<tr id="member-<%= member.id %>" class="member"> |
|
| 41 |
<td class="name"> |
|
| 42 |
<span class="icon"> |
|
| 43 |
<% if member.principal %> |
|
| 44 |
<%= link_to_principal member.principal %> |
|
| 45 |
<% end %> |
|
| 46 |
</span> |
|
| 47 |
</td> |
|
| 48 |
<td class="roles"> |
|
| 49 |
<span id="member-<%= member.id %>-roles"><%= member.roles.sort.collect(&:to_s).join(', ') %></span>
|
|
| 50 |
<div id="member-<%= member.id %>-form"></div> |
|
| 51 |
</td> |
|
| 52 |
<td class="buttons"> |
|
| 53 |
<%= link_to sprite_icon('edit', l(:button_edit)),
|
|
| 54 |
edit_membership_path(member, members_list_params), |
|
| 55 |
:remote => true, |
|
| 56 |
:class => 'icon icon-edit' %> |
|
| 57 |
<%= remove_link membership_path(member, members_list_params), |
|
| 58 |
:remote => true, |
|
| 59 |
:data => (!User.current.admin? && member.include?(User.current) ? {:confirm => l(:text_own_membership_delete_confirmation)} : {}) if member.deletable? %>
|
|
| 60 |
</td> |
|
| 61 |
<%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %>
|
|
| 62 |
</tr> |
|
| 63 |
<% end %> |
|
| 64 |
</tbody> |
|
| 65 |
</table> |
|
| 66 |
</div> |
|
| 67 |
<span class="pagination"> |
|
| 68 |
<%= pagination_links_full(member_pages, member_count) do |text, parameters, options| |
|
| 69 |
link_to text, settings_project_path(@project, 'members', request.query_parameters.except('tab', :tab).merge(parameters)), options
|
|
| 70 |
end %> |
|
| 71 |
</span> |
|
| 72 |
<% other_formats_links do |f| %> |
|
| 73 |
<%= f.link_to_with_query_parameters "CSV", {}, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
|
|
| 74 |
<% end %> |
|
| 75 |
<div id="csv-export-options" style="display: none;"> |
|
| 76 |
<h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3> |
|
| 77 |
<%= form_tag(project_memberships_path(project_id: @project.id, format: 'csv'), :method => :get, :id => 'csv-export-form') do %> |
|
| 78 |
<%= export_csv_encoding_select_tag %> |
|
| 79 |
<p class="buttons"> |
|
| 80 |
<%= submit_tag l(:button_export), :name => nil, :onclick => 'hideModal(this);', :data => {:disable_with => false} %>
|
|
| 81 |
<%= link_to_function l(:button_cancel), 'hideModal(this);' %> |
|
| 82 |
</p> |
|
| 83 |
<% end %> |
|
| 84 |
</div> |
|
| 85 |
<% else %> |
|
| 86 |
<p class="nodata"><%= l(:label_no_data) %></p> |
|
| 87 |
<% end %> |
|
| 1 |
<%= render :partial => 'members/members' %> |
|
| config/locales/en.yml | ||
|---|---|---|
| 674 | 674 |
label_member: Member |
| 675 | 675 |
label_member_new: New member |
| 676 | 676 |
label_member_plural: Members |
| 677 |
label_member_view_all: View all members |
|
| 677 | 678 |
label_tracker: Tracker |
| 678 | 679 |
label_tracker_plural: Trackers |
| 679 | 680 |
label_tracker_all: All trackers |
| config/routes.rb | ||
|---|---|---|
| 164 | 164 |
end |
| 165 | 165 |
end |
| 166 | 166 | |
| 167 |
get 'members', :to => 'members#index', :as => 'members' |
|
| 168 | ||
| 167 | 169 |
resource :enumerations, :controller => 'project_enumerations', :only => [:update, :destroy] |
| 168 | 170 | |
| 169 | 171 |
get 'issues/:copy_from/copy', :to => 'issues#new', :as => 'copy_issue' |
| test/functional/members_controller_test.rb | ||
|---|---|---|
| 461 | 461 |
assert_response :success |
| 462 | 462 |
assert_include 'User Misc', response.body |
| 463 | 463 |
end |
| 464 | ||
| 465 |
def test_index_html_should_render_members_page |
|
| 466 |
get(:index, :params => {:project_id => 1})
|
|
| 467 |
assert_response :success |
|
| 468 |
assert_select 'h2', :text => 'Members' |
|
| 469 |
assert_select 'div#main-menu a.overview.selected' |
|
| 470 |
assert_select 'title', :text => 'Members - eCookbook - Redmine' |
|
| 471 |
assert_select 'form#members-filter-form[action=?]', '/projects/ecookbook/members' do |
|
| 472 |
assert_select 'input[name=member_name]' |
|
| 473 |
assert_select 'select[name=member_role_id]' |
|
| 474 |
assert_select 'input[type=submit]' |
|
| 475 |
assert_select 'a[href=?]', '/projects/ecookbook/members' |
|
| 476 |
end |
|
| 477 |
assert_select 'table.list.members' |
|
| 478 |
end |
|
| 479 | ||
| 480 |
def test_index_html_filter_by_status |
|
| 481 |
@request.session[:user_id] = 2 |
|
| 482 |
get(:index, :params => {:project_id => 1, :member_status => 3})
|
|
| 483 |
assert_response :success |
|
| 484 |
assert_select 'table.list.members tbody tr.member', :count => 1 |
|
| 485 |
assert_select 'tr#member-4' |
|
| 486 |
assert_select 'tr#member-1', :count => 0 |
|
| 487 |
assert_select 'tr#member-2', :count => 0 |
|
| 488 |
end |
|
| 489 | ||
| 490 |
def test_index_html_for_user_with_manage_members_permission_should_display_actions |
|
| 491 |
@request.session[:user_id] = 2 # user 2 has manage_members |
|
| 492 |
get(:index, :params => {:project_id => 1})
|
|
| 493 |
assert_response :success |
|
| 494 |
assert_select 'p a.icon-add' |
|
| 495 |
assert_select 'td.buttons a.icon-edit' |
|
| 496 |
assert_select 'select[name=member_status]' |
|
| 497 |
end |
|
| 498 | ||
| 499 |
def test_index_html_for_user_without_manage_members_permission_should_not_display_actions |
|
| 500 |
role = Role.create!(:name => 'Viewer', :permissions => [:view_project, :view_members]) |
|
| 501 |
user = User.generate! |
|
| 502 |
User.add_to_project(user, Project.find(1), role) |
|
| 503 |
@request.session[:user_id] = user.id |
|
| 504 | ||
| 505 |
get(:index, :params => {:project_id => 1})
|
|
| 506 |
assert_response :success |
|
| 507 |
assert_select 'p a.icon-add', :count => 0 |
|
| 508 |
assert_select 'td.buttons', :count => 0 |
|
| 509 |
assert_select 'select[name=member_status]', :count => 0 |
|
| 510 |
assert_select 'tr#member-4', :count => 0 |
|
| 511 |
end |
|
| 512 | ||
| 513 |
def test_index_html_for_user_without_manage_members_permission_should_only_show_active_members |
|
| 514 |
role = Role.create!(:name => 'Viewer', :permissions => [:view_project, :view_members]) |
|
| 515 |
user = User.generate! |
|
| 516 |
User.add_to_project(user, Project.find(1), role) |
|
| 517 |
@request.session[:user_id] = user.id |
|
| 518 | ||
| 519 |
get(:index, :params => {:project_id => 1, :member_status => 3})
|
|
| 520 |
assert_response :success |
|
| 521 |
assert_select 'select[name=member_status]', :count => 0 |
|
| 522 |
assert_select 'tr#member-4', :count => 0 |
|
| 523 |
assert_select 'tr#member-1' |
|
| 524 |
assert_select 'tr#member-2' |
|
| 525 |
end |
|
| 526 | ||
| 527 |
def test_index_html_filter_by_name |
|
| 528 |
get(:index, :params => {:project_id => 1, :member_name => 'John'})
|
|
| 529 |
assert_response :success |
|
| 530 |
assert_select 'table.list.members tbody tr.member', :count => 1 |
|
| 531 |
assert_select 'tr#member-1' |
|
| 532 |
end |
|
| 533 | ||
| 534 |
def test_index_html_filter_by_role |
|
| 535 |
get(:index, :params => {:project_id => 1, :member_role_id => 2})
|
|
| 536 |
assert_response :success |
|
| 537 |
assert_select 'table.list.members tbody tr.member' |
|
| 538 |
assert_select 'tr#member-2' |
|
| 539 |
assert_select 'tr#member-1', :count => 0 |
|
| 540 |
end |
|
| 541 | ||
| 542 |
def test_index_html_with_pagination |
|
| 543 |
project = Project.find(1) |
|
| 544 |
26.times { User.add_to_project(User.generate!, project, Role.find(2)) }
|
|
| 545 |
with_settings :per_page_options => '25,50,100' do |
|
| 546 |
get(:index, :params => {:project_id => 1, :members_page => 2})
|
|
| 547 |
assert_response :success |
|
| 548 |
assert_select 'span.pagination' |
|
| 549 |
assert_select 'span.pagination a[href*=?]', '/projects/ecookbook/members?members_page=' |
|
| 550 |
assert_select 'span.pagination a[href*=?]', 'settings/members', :count => 0 |
|
| 551 |
end |
|
| 552 |
end |
|
| 553 | ||
| 554 |
def test_index_html_unauthorized_user_should_be_denied |
|
| 555 |
@request.session[:user_id] = nil |
|
| 556 |
get(:index, :params => {:project_id => 2})
|
|
| 557 |
assert_response :redirect |
|
| 558 |
end |
|
| 464 | 559 |
end |
| test/functional/projects_controller_test.rb | ||
|---|---|---|
| 784 | 784 |
get(:show, :params => {:id => 1})
|
| 785 | 785 |
assert_response :success |
| 786 | 786 |
assert_select '#header h1', :text => "eCookbook" |
| 787 |
assert_select 'div.members.box a[href=?]', '/projects/ecookbook/members', :text => 'View all members' |
|
| 787 | 788 |
end |
| 788 | 789 | |
| 789 | 790 |
def test_show_by_identifier |
| ... | ... | |
| 1037 | 1038 |
} |
| 1038 | 1039 |
) |
| 1039 | 1040 |
assert_response :success |
| 1041 |
assert_select 'div#main-menu a.settings.selected' |
|
| 1040 | 1042 |
assert_select "tr#member-#{user_member.id} td.name a[href=?]", "/users/#{user.id}", :text => user.name
|
| 1041 | 1043 |
assert_select "tr#member-#{group_member.id} td.name a[href=?]", '/groups/10', :text => 'A Team'
|
| 1042 | 1044 |
end |
| test/helpers/members_helper_test.rb | ||
|---|---|---|
| 87 | 87 |
end |
| 88 | 88 | |
| 89 | 89 |
def test_members_scope_default_should_return_all_members |
| 90 |
User.current = User.find(2) |
|
| 90 | 91 |
project = Project.find(1) |
| 91 | 92 |
stubs(:params).returns({})
|
| 92 | 93 | |
| ... | ... | |
| 94 | 95 |
end |
| 95 | 96 | |
| 96 | 97 |
def test_members_scope_with_status_active_should_filter_by_active_status |
| 98 |
User.current = User.find(2) |
|
| 97 | 99 |
project = Project.find(1) |
| 98 | 100 |
stubs(:params).returns({:member_status => '1'})
|
| 99 | 101 | |
| ... | ... | |
| 101 | 103 |
end |
| 102 | 104 | |
| 103 | 105 |
def test_members_scope_with_status_locked_should_return_locked_members |
| 106 |
User.current = User.find(2) |
|
| 104 | 107 |
project = Project.find(1) |
| 105 | 108 |
stubs(:params).returns({:member_status => '3'})
|
| 106 | 109 | |
| 107 | 110 |
assert_equal [4], members_scope(project).ids.sort |
| 108 | 111 |
end |
| 112 | ||
| 113 |
def test_members_scope_for_user_without_manage_members_permission_should_return_active_members_only |
|
| 114 |
User.current = User.find(4) |
|
| 115 |
project = Project.find(1) |
|
| 116 |
stubs(:params).returns({:member_status => '3'})
|
|
| 117 | ||
| 118 |
assert_equal [1, 2], members_scope(project).ids.sort |
|
| 119 |
end |
|
| 109 | 120 |
end |
| test/helpers/routes_helper_test.rb | ||
|---|---|---|
| 43 | 43 |
assert_equal 'http://test.host/projects/ecookbook/issues?set_filter=1', _project_issues_url(Project.find(1), set_filter: 1) |
| 44 | 44 |
assert_equal 'http://test.host/issues?set_filter=1', _project_issues_url(nil, set_filter: 1) |
| 45 | 45 |
end |
| 46 | ||
| 47 |
def test_project_members_path_in_settings_context |
|
| 48 |
project = Project.find('ecookbook')
|
|
| 49 |
stubs(:controller_name).returns('projects')
|
|
| 50 |
stubs(:action_name).returns('settings')
|
|
| 51 | ||
| 52 |
assert_equal '/projects/ecookbook/settings/members', _project_members_path(project) |
|
| 53 |
assert_equal '/projects/ecookbook/settings/members?members_page=2', _project_members_path(project, :members_page => 2) |
|
| 54 |
assert_equal '/projects/ecookbook/settings/members?members_page=2', _project_members_path(project, :tab => 'members', :members_page => 2) |
|
| 55 |
end |
|
| 56 | ||
| 57 |
def test_project_members_path_in_project_members_context |
|
| 58 |
project = Project.find('ecookbook')
|
|
| 59 |
stubs(:controller_name).returns('members')
|
|
| 60 |
stubs(:action_name).returns('index')
|
|
| 61 | ||
| 62 |
assert_equal '/projects/ecookbook/members', _project_members_path(project) |
|
| 63 |
assert_equal '/projects/ecookbook/members?members_page=2', _project_members_path(project, :members_page => 2) |
|
| 64 |
assert_equal '/projects/ecookbook/members?members_page=2', _project_members_path(project, :tab => 'members', :members_page => 2) |
|
| 65 |
end |
|
| 46 | 66 |
end |