From 476a1dad4e50994163cd9bae7a4bf01be701b162 Mon Sep 17 00:00:00 2001 From: FloWalchs Date: Mon, 9 Mar 2026 19:44:29 +0000 Subject: [PATCH] tests-group-controller-remove_users --- .../context_menus_controller_test.rb | 110 +++++++++++++++++- test/functional/groups_controller_test.rb | 43 ++++++- test/integration/api_test/api_routing_test.rb | 3 +- test/integration/api_test/groups_test.rb | 36 ++++++ test/integration/routing/groups_test.rb | 3 +- 5 files changed, 188 insertions(+), 7 deletions(-) diff --git a/test/functional/context_menus_controller_test.rb b/test/functional/context_menus_controller_test.rb index b91d9dcce..3966b7e43 100644 --- a/test/functional/context_menus_controller_test.rb +++ b/test/functional/context_menus_controller_test.rb @@ -314,7 +314,7 @@ class ContextMenusControllerTest < Redmine::ControllerTest def test_context_menu_should_propose_shared_versions_for_issues_from_different_projects @request.session[:user_id] = 2 - version = Version.create!(:name => 'Shared', :sharing => 'system', :project_id => 1) + Version.create!(:name => 'Shared', :sharing => 'system', :project_id => 1) get( :issues, @@ -522,4 +522,112 @@ class ContextMenusControllerTest < Redmine::ControllerTest assert_select 'a.icon-del', :count => 0 end end + + def test_context_menu_multiple_users_should_show_add_user_to_group_links + get :users, params: { ids: [1, 2] } + assert_response :success + + assert_select 'a.submenu', text: I18n.t(:label_add_user_to_group), count: 1 + assert_select 'a.submenu', text: I18n.t(:label_remove_user_from_group), count: 0 + + assert_select 'a.icon.icon-lock span.icon-label', text: 'Lock', count: 1 + assert_select 'a.icon.icon-del span.icon-label', text: 'Delete', count: 1 + + assert_select 'li.folder' do |folders| + rem_folder = folders.find { |li| li.at_css('> a.submenu')&.text&.strip == I18n.t(:label_add_user_to_group) } + assert rem_folder, "a.submenu '#{I18n.t(:label_add_user_to_group)}' not found" + if rem_folder + assert_select rem_folder, '> ul > li', count: 2 + assert_select rem_folder, "ul > li > a[rel='nofollow'][data-method='post']", count: 2 + end + end + end + + def test_context_menu_multiple_users_should_show_remove_add_user_from_group_links + get :users, params: { ids: [1, 8] } + assert_response :success + + assert_select 'a.icon.icon-lock span.icon-label', text: 'Lock', count: 1 + assert_select 'a.icon.icon-del span.icon-label', text: 'Delete', count: 1 + + assert_select 'a.submenu', text: I18n.t(:label_add_user_to_group), count: 1 + assert_select 'a.submenu', text: I18n.t(:label_remove_user_from_group), count: 1 + + assert_select 'li.folder' do |folders| + rem_folder = folders.find { |li| li.at_css('> a.submenu')&.text&.strip == I18n.t(:label_add_user_to_group) } + assert rem_folder, "a.submenu '#{I18n.t(:label_add_user_to_group)}' not found" + if rem_folder + assert_select rem_folder, '> ul > li', count: 2 + assert_select rem_folder, "ul > li > a[rel='nofollow'][data-method='post']", count: 2 + end + + rem_folder = folders.find { |li| li.at_css('> a.submenu')&.text&.strip == I18n.t(:label_remove_user_from_group) } + assert rem_folder, "a.submenu '#{I18n.t(:label_remove_user_from_group)}' not found" + if rem_folder + assert_select rem_folder, '> ul > li', count: 2 + assert_select rem_folder, "ul > li > a[rel='nofollow'][data-method='delete']", count: 2 + end + end + end + + def test_context_menu_single_user_should_show_remove_user_from_group_links + get :users, params: { ids: [8] } + assert_response :success + + assert_select 'a.submenu', text: I18n.t(:label_remove_user_from_group), count: 1 + assert_select 'a.submenu', text: I18n.t(:label_add_user_to_group), count: 0 + + assert_select 'a.icon.icon-lock span.icon-label', text: 'Lock', count: 1 + assert_select 'a.icon.icon-edit span.icon-label', text: 'Edit', count: 1 + assert_select 'a.icon.icon-del span.icon-label', text: 'Delete', count: 1 + + assert_select 'li.folder' do |folders| + rem_folder = folders.find { |li| li.at_css('> a.submenu')&.text&.strip == I18n.t(:label_remove_user_from_group) } + assert rem_folder, "a.submenu '#{I18n.t(:label_remove_user_from_group)}' not found" + if rem_folder + assert_select rem_folder, '> ul > li', count: 2 + assert_select rem_folder, "ul > li > a[rel='nofollow'][data-method='delete']", count: 2 + assert_select rem_folder, 'a[data-confirm]' do |links| + value = links.first['data-confirm'] + assert value.start_with?('Are you sure you want to remove 1 user') + end + end + end + end + + def test_context_menu_mulitple_user_should_show_remove_add_user_from_group_links + group = Group.find(10) + user = User.find(9) + group.users << user + + get :users, params: { ids: [8, 9] } + assert_response :success + + assert_select 'a.icon.icon-edit span.icon-label', text: 'Edit', count: 0 + assert_select 'a.icon.icon-lock span.icon-label', text: 'Lock', count: 1 + assert_select 'a.icon.icon-del span.icon-label', text: 'Delete', count: 1 + + assert_select 'a.submenu', text: I18n.t(:label_remove_user_from_group), count: 1 + assert_select 'a.submenu', text: I18n.t(:label_add_user_to_group), count: 1 + + assert_select 'li.folder' do |folders| + rem_folder = folders.find { |li| li.at_css('> a.submenu')&.text&.strip == I18n.t(:label_add_user_to_group) } + assert rem_folder, "a.submenu '#{I18n.t(:label_add_user_to_group)}' not found" + if rem_folder + assert_select rem_folder, '> ul > li', count: 1 + assert_select rem_folder, "ul > li > a[rel='nofollow'][data-method='post']", count: 1 + end + + rem_folder = folders.find { |li| li.at_css('> a.submenu')&.text&.strip == I18n.t(:label_remove_user_from_group) } + assert rem_folder, "a.submenu '#{I18n.t(:label_remove_user_from_group)}' not found" + if rem_folder + assert_select rem_folder, '> ul > li', count: 2 + assert_select rem_folder, "ul > li > a[rel='nofollow'][data-method='delete']", count: 2 + assert_select rem_folder, 'a[data-confirm]' do |links| + value = links.first['data-confirm'] + assert value.start_with?('Are you sure you want to remove 2 users') + end + end + end + end end diff --git a/test/functional/groups_controller_test.rb b/test/functional/groups_controller_test.rb index a8407e8e8..6ca008610 100644 --- a/test/functional/groups_controller_test.rb +++ b/test/functional/groups_controller_test.rb @@ -249,10 +249,10 @@ class GroupsControllerTest < Redmine::ControllerTest assert_match /John Smith/, response.body end - def test_remove_user + def test_remove_users assert_difference 'Group.find(10).users.count', -1 do delete( - :remove_user, + :remove_users, :params => { :id => 10, :user_id => '8' @@ -261,10 +261,10 @@ class GroupsControllerTest < Redmine::ControllerTest end end - def test_xhr_remove_user + def test_xhr_remove_users assert_difference 'Group.find(10).users.count', -1 do delete( - :remove_user, + :remove_users, :params => { :id => 10, :user_id => '8' @@ -276,6 +276,41 @@ class GroupsControllerTest < Redmine::ControllerTest end end + def test_remove_users_patch + group = Group.find(10) + user = User.find(9) + group.users << user + + assert_difference 'Group.find(10).users.count', -2 do + delete( + :remove_users, + :params => { + :id => 10, + :user_ids => ['8', '9'] + } + ) + end + end + + def test_xhr_remove_users_patch + group = Group.find(10) + user = User.find(9) + group.users << user + + assert_difference 'Group.find(10).users.count', -2 do + delete( + :remove_users, + :params => { + :id => 10, + :user_ids => ['8', '9'] + }, + :xhr => true + ) + assert_response :success + assert_equal 'text/javascript', response.media_type + end + end + def test_autocomplete_for_user get( :autocomplete_for_user, diff --git a/test/integration/api_test/api_routing_test.rb b/test/integration/api_test/api_routing_test.rb index 9ba547275..0266437de 100644 --- a/test/integration/api_test/api_routing_test.rb +++ b/test/integration/api_test/api_routing_test.rb @@ -51,7 +51,8 @@ class Redmine::ApiTest::ApiRoutingTest < Redmine::ApiTest::Routing def test_group_users should_route 'POST /groups/567/users' => 'groups#add_users', :id => '567' - should_route 'DELETE /groups/567/users/12' => 'groups#remove_user', :id => '567', :user_id => '12' + should_route 'DELETE /groups/567/users/12' => 'groups#remove_users', :id => '567', :user_id => '12' + should_route 'DELETE /groups/567/users' => 'groups#remove_users', :id => '567' end def test_issue_categories diff --git a/test/integration/api_test/groups_test.rb b/test/integration/api_test/groups_test.rb index 110c59051..5539e0d16 100644 --- a/test/integration/api_test/groups_test.rb +++ b/test/integration/api_test/groups_test.rb @@ -237,4 +237,40 @@ class Redmine::ApiTest::GroupsTest < Redmine::ApiTest::Base end assert_not_include User.find(8), group.reload.users end + + test "DELETE /groups/:id/users.xml should remove users from the group" do + group = Group.generate! + group.users << User.find(5) + group.users << User.find(6) + assert_difference 'group.reload.users.count', -2 do + delete( + "/groups/#{group.id}/users.xml", + :params => {:user_ids => [5, 6]}, + :headers => credentials('admin') + ) + assert_response :no_content + assert_equal '', @response.body + end + assert_not_include User.find(5), group.reload.users + assert_not_include User.find(6), group.reload.users + end + + test "DELETE /groups/:id/users.xml removes users and skips unknown user IDs" do + group = Group.generate! + group.users << User.find(5) + group.users << User.find(6) + group.users << User.find(7) + assert_difference 'group.reload.users.count', -2 do + delete( + "/groups/#{group.id}/users.xml", + :params => {:user_ids => [5, 6, 8]}, + :headers => credentials('admin') + ) + assert_response :no_content + assert_equal '', @response.body + end + assert_not_include User.find(5), group.reload.users + assert_not_include User.find(6), group.reload.users + assert_include User.find(7), group.reload.users + end end diff --git a/test/integration/routing/groups_test.rb b/test/integration/routing/groups_test.rb index 2ee5c27fa..03f1d50d5 100644 --- a/test/integration/routing/groups_test.rb +++ b/test/integration/routing/groups_test.rb @@ -37,6 +37,7 @@ class RoutingGroupsTest < Redmine::RoutingTest def test_group_users should_route 'GET /groups/567/users/new' => 'groups#new_users', :id => '567' should_route 'POST /groups/567/users' => 'groups#add_users', :id => '567' - should_route 'DELETE /groups/567/users/12' => 'groups#remove_user', :id => '567', :user_id => '12' + should_route 'DELETE /groups/567/users/12' => 'groups#remove_users', :id => '567', :user_id => '12' + should_route 'DELETE /groups/567/users' => 'groups#remove_users', :id => '567' end end -- 2.43.0