2019-04-15 10:17:05 +00:00
# frozen_string_literal: true
2017-09-13 15:16:30 +00:00
require 'spec_helper'
2016-01-24 00:08:15 +00:00
2020-06-04 03:08:05 +00:00
RSpec . describe GroupsController do
2019-04-09 15:38:58 +00:00
include ExternalAuthorizationServiceHelpers
2016-03-21 20:01:38 +00:00
let ( :user ) { create ( :user ) }
2017-09-07 18:35:45 +00:00
let ( :admin ) { create ( :admin ) }
2017-06-13 07:11:33 +00:00
let ( :group ) { create ( :group , :public ) }
2017-08-02 19:55:11 +00:00
let ( :project ) { create ( :project , namespace : group ) }
2016-03-21 20:01:38 +00:00
let! ( :group_member ) { create ( :group_member , group : group , user : user ) }
2017-09-07 18:35:45 +00:00
let! ( :owner ) { group . add_owner ( create ( :user ) ) . user }
2018-07-11 14:36:08 +00:00
let! ( :maintainer ) { group . add_maintainer ( create ( :user ) ) . user }
2017-09-07 18:35:45 +00:00
let! ( :developer ) { group . add_developer ( create ( :user ) ) . user }
let! ( :guest ) { group . add_guest ( create ( :user ) ) . user }
shared_examples 'member with ability to create subgroups' do
it 'renders the new page' do
sign_in ( member )
2018-12-17 22:52:17 +00:00
get :new , params : { parent_id : group . id }
2017-09-07 18:35:45 +00:00
expect ( response ) . to render_template ( :new )
end
end
shared_examples 'member without ability to create subgroups' do
it 'renders the 404 page' do
sign_in ( member )
2018-12-17 22:52:17 +00:00
get :new , params : { parent_id : group . id }
2017-09-07 18:35:45 +00:00
expect ( response ) . not_to render_template ( :new )
2020-03-31 21:08:05 +00:00
expect ( response ) . to have_gitlab_http_status ( :not_found )
2017-09-07 18:35:45 +00:00
end
end
2019-03-14 12:55:46 +00:00
shared_examples 'details view' do
2020-06-11 00:08:35 +00:00
let ( :namespace ) { group }
2019-03-14 12:55:46 +00:00
it { is_expected . to render_template ( 'groups/show' ) }
context 'as atom' do
let! ( :event ) { create ( :event , project : project ) }
let ( :format ) { :atom }
it { is_expected . to render_template ( 'groups/show' ) }
2019-10-23 09:06:03 +00:00
it 'assigns events for all the projects in the group' , :sidekiq_might_not_need_inline do
2019-03-14 12:55:46 +00:00
subject
2020-01-30 21:08:47 +00:00
expect ( assigns ( :events ) . map ( & :id ) ) . to contain_exactly ( event . id )
2019-03-14 12:55:46 +00:00
end
end
end
2017-10-20 13:39:15 +00:00
describe 'GET #show' do
before do
sign_in ( user )
project
end
2019-03-14 12:55:46 +00:00
let ( :format ) { :html }
2017-10-20 13:39:15 +00:00
2019-03-14 12:55:46 +00:00
subject { get :show , params : { id : group . to_param } , format : format }
2017-10-20 13:39:15 +00:00
2020-06-15 00:08:43 +00:00
context 'when the group is not importing' do
it_behaves_like 'details view'
end
context 'when the group is importing' do
before do
create ( :group_import_state , group : group )
end
it 'redirects to the import status page' do
expect ( subject ) . to redirect_to group_import_path ( group )
end
end
2019-03-14 12:55:46 +00:00
end
describe 'GET #details' do
before do
sign_in ( user )
project
2017-10-20 13:39:15 +00:00
end
2019-03-14 12:55:46 +00:00
let ( :format ) { :html }
subject { get :details , params : { id : group . to_param } , format : format }
it_behaves_like 'details view'
2017-10-20 13:39:15 +00:00
end
2018-09-03 13:16:23 +00:00
describe 'GET edit' do
it 'sets the badge API endpoint' do
sign_in ( owner )
2018-12-17 22:52:17 +00:00
get :edit , params : { id : group . to_param }
2018-09-03 13:16:23 +00:00
expect ( assigns ( :badge_api_endpoint ) ) . not_to be_nil
end
end
2017-09-07 18:35:45 +00:00
describe 'GET #new' do
2019-07-24 09:20:54 +00:00
context 'when creating subgroups' do
2017-09-07 18:35:45 +00:00
[ true , false ] . each do | can_create_group_status |
context " and can_create_group is #{ can_create_group_status } " do
before do
2018-07-11 14:36:08 +00:00
User . where ( id : [ admin , owner , maintainer , developer , guest ] ) . update_all ( can_create_group : can_create_group_status )
2017-09-07 18:35:45 +00:00
end
2020-02-05 18:09:06 +00:00
[ :admin , :owner , :maintainer ] . each do | member_type |
2017-09-07 18:35:45 +00:00
context " and logged in as #{ member_type . capitalize } " do
it_behaves_like 'member with ability to create subgroups' do
let ( :member ) { send ( member_type ) }
end
end
end
2020-02-05 18:09:06 +00:00
[ :guest , :developer ] . each do | member_type |
2017-09-07 18:35:45 +00:00
context " and logged in as #{ member_type . capitalize } " do
it_behaves_like 'member without ability to create subgroups' do
let ( :member ) { send ( member_type ) }
end
end
end
end
end
end
end
2018-01-30 23:45:23 +00:00
describe 'GET #activity' do
render_views
context 'as json' do
2020-01-30 21:08:47 +00:00
before do
sign_in ( user )
project
end
2019-10-23 09:06:03 +00:00
it 'includes events from all projects in group and subgroups' , :sidekiq_might_not_need_inline do
2019-07-01 11:17:47 +00:00
2 . times do
2018-01-30 23:45:23 +00:00
project = create ( :project , group : group )
create ( :event , project : project )
end
2019-07-01 11:17:47 +00:00
subgroup = create ( :group , parent : group )
project = create ( :project , group : subgroup )
create ( :event , project : project )
2018-01-30 23:45:23 +00:00
2018-12-17 22:52:17 +00:00
get :activity , params : { id : group . to_param } , format : :json
2018-01-30 23:45:23 +00:00
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :ok )
2018-01-30 23:45:23 +00:00
expect ( json_response [ 'count' ] ) . to eq ( 3 )
expect ( assigns ( :projects ) . limit_value ) . to be_nil
end
end
2020-01-30 21:08:47 +00:00
context 'when user has no permission to see the event' do
let ( :user ) { create ( :user ) }
let ( :group ) { create ( :group ) }
let ( :project ) { create ( :project , group : group ) }
let ( :project_with_restricted_access ) do
create ( :project , :public , issues_access_level : ProjectFeature :: PRIVATE , group : group )
end
before do
create ( :event , project : project )
create ( :event , :created , project : project_with_restricted_access , target : create ( :issue ) )
group . add_guest ( user )
sign_in ( user )
end
it 'filters out invisible event' do
get :activity , params : { id : group . to_param } , format : :json
expect ( json_response [ 'count' ] ) . to eq ( 1 )
end
end
2018-01-30 23:45:23 +00:00
end
2017-09-07 18:35:45 +00:00
describe 'POST #create' do
2019-06-03 07:32:12 +00:00
it 'allows creating a group' do
sign_in ( user )
expect do
post :create , params : { group : { name : 'new_group' , path : " new_group " } }
end . to change { Group . count } . by ( 1 )
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :found )
2019-06-03 07:32:12 +00:00
end
context 'authorization' do
it 'allows an admin to create a group' do
sign_in ( create ( :admin ) )
expect do
post :create , params : { group : { name : 'new_group' , path : " new_group " } }
end . to change { Group . count } . by ( 1 )
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :found )
2019-06-03 07:32:12 +00:00
end
end
2019-07-24 09:20:54 +00:00
context 'when creating subgroups' do
2017-09-07 18:35:45 +00:00
[ true , false ] . each do | can_create_group_status |
context " and can_create_group is #{ can_create_group_status } " do
context 'and logged in as Owner' do
it 'creates the subgroup' do
owner . update_attribute ( :can_create_group , can_create_group_status )
sign_in ( owner )
2018-12-17 22:52:17 +00:00
post :create , params : { group : { parent_id : group . id , path : 'subgroup' } }
2017-09-07 18:35:45 +00:00
expect ( response ) . to be_redirect
expect ( response . body ) . to match ( %r{ http://test.host/ #{ group . path } /subgroup } )
end
end
context 'and logged in as Developer' do
it 'renders the new template' do
developer . update_attribute ( :can_create_group , can_create_group_status )
sign_in ( developer )
previous_group_count = Group . count
2018-12-17 22:52:17 +00:00
post :create , params : { group : { parent_id : group . id , path : 'subgroup' } }
2017-09-07 18:35:45 +00:00
expect ( response ) . to render_template ( :new )
expect ( Group . count ) . to eq ( previous_group_count )
end
end
end
end
end
context 'when creating a top level group' do
before do
sign_in ( developer )
end
context 'and can_create_group is enabled' do
before do
developer . update_attribute ( :can_create_group , true )
end
it 'creates the Group' do
original_group_count = Group . count
2018-12-17 22:52:17 +00:00
post :create , params : { group : { path : 'subgroup' } }
2017-09-07 18:35:45 +00:00
expect ( Group . count ) . to eq ( original_group_count + 1 )
expect ( response ) . to be_redirect
end
end
context 'and can_create_group is disabled' do
before do
developer . update_attribute ( :can_create_group , false )
end
it 'does not create the Group' do
original_group_count = Group . count
2018-12-17 22:52:17 +00:00
post :create , params : { group : { path : 'subgroup' } }
2017-09-07 18:35:45 +00:00
expect ( Group . count ) . to eq ( original_group_count )
expect ( response ) . to render_template ( :new )
end
end
end
2020-03-26 18:08:03 +00:00
context " malicious group name " do
subject { post :create , params : { group : { name : " <script>alert('Mayday!');</script> " , path : " invalid_group_url " } } }
before do
sign_in ( user )
end
it { expect { subject } . not_to change { Group . count } }
it { expect ( subject ) . to render_template ( :new ) }
end
2020-04-24 09:09:44 +00:00
context 'when creating a group with `default_branch_protection` attribute' do
before do
sign_in ( user )
end
subject do
post :create , params : { group : { name : 'new_group' , path : 'new_group' , default_branch_protection : Gitlab :: Access :: PROTECTION_NONE } }
end
context 'for users who have the ability to create a group with `default_branch_protection`' do
it 'creates group with the specified branch protection level' do
subject
expect ( response ) . to have_gitlab_http_status ( :found )
expect ( Group . last . default_branch_protection ) . to eq ( Gitlab :: Access :: PROTECTION_NONE )
end
end
context 'for users who do not have the ability to create a group with `default_branch_protection`' do
it 'does not create the group with the specified branch protection level' do
allow ( Ability ) . to receive ( :allowed? ) . and_call_original
allow ( Ability ) . to receive ( :allowed? ) . with ( user , :create_group_with_default_branch_protection ) { false }
subject
expect ( response ) . to have_gitlab_http_status ( :found )
expect ( Group . last . default_branch_protection ) . not_to eq ( Gitlab :: Access :: PROTECTION_NONE )
end
end
end
2020-06-10 18:09:15 +00:00
describe 'tracking group creation for onboarding issues experiment' do
before do
sign_in ( user )
end
subject ( :create_namespace ) { post :create , params : { group : { name : 'new_group' , path : 'new_group' } } }
context 'experiment disabled' do
before do
stub_experiment ( onboarding_issues : false )
end
it 'does not track anything' do
expect ( Gitlab :: Tracking ) . not_to receive ( :event )
create_namespace
end
end
context 'experiment enabled' do
before do
stub_experiment ( onboarding_issues : true )
end
context 'and the user is part of the control group' do
before do
stub_experiment_for_user ( onboarding_issues : false )
end
it 'tracks the event with the "created_namespace" action with the "control_group" property' do
expect ( Gitlab :: Tracking ) . to receive ( :event ) . with (
'Growth::Conversion::Experiment::OnboardingIssues' ,
'created_namespace' ,
label : anything ,
property : 'control_group'
)
create_namespace
end
end
context 'and the user is part of the experimental group' do
before do
stub_experiment_for_user ( onboarding_issues : true )
end
it 'tracks the event with the "created_namespace" action with the "experimental_group" property' do
expect ( Gitlab :: Tracking ) . to receive ( :event ) . with (
'Growth::Conversion::Experiment::OnboardingIssues' ,
'created_namespace' ,
label : anything ,
property : 'experimental_group'
)
create_namespace
end
end
end
end
2017-09-07 18:35:45 +00:00
end
2016-03-21 20:01:38 +00:00
describe 'GET #index' do
2016-01-24 00:08:15 +00:00
context 'as a user' do
it 'redirects to Groups Dashboard' do
2016-03-21 20:01:38 +00:00
sign_in ( user )
2016-01-24 00:08:15 +00:00
get :index
expect ( response ) . to redirect_to ( dashboard_groups_path )
end
end
context 'as a guest' do
it 'redirects to Explore Groups' do
get :index
expect ( response ) . to redirect_to ( explore_groups_path )
end
end
end
2017-05-03 23:51:25 +00:00
2019-10-23 09:06:03 +00:00
describe 'GET #issues' , :sidekiq_might_not_need_inline do
2018-09-05 11:10:36 +00:00
let ( :issue_1 ) { create ( :issue , project : project , title : 'foo' ) }
let ( :issue_2 ) { create ( :issue , project : project , title : 'bar' ) }
2016-03-21 20:01:38 +00:00
before do
2016-04-16 19:09:08 +00:00
create_list ( :award_emoji , 3 , awardable : issue_2 )
create_list ( :award_emoji , 2 , awardable : issue_1 )
2017-05-03 11:27:17 +00:00
create_list ( :award_emoji , 2 , :downvote , awardable : issue_2 )
2016-03-21 20:01:38 +00:00
sign_in ( user )
end
context 'sorting by votes' do
it 'sorts most popular issues' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : group . to_param , sort : 'upvotes_desc' }
2016-03-21 20:01:38 +00:00
expect ( assigns ( :issues ) ) . to eq [ issue_2 , issue_1 ]
end
it 'sorts least popular issues' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : group . to_param , sort : 'downvotes_desc' }
2016-03-21 20:01:38 +00:00
expect ( assigns ( :issues ) ) . to eq [ issue_2 , issue_1 ]
end
end
2018-09-05 11:10:36 +00:00
context 'searching' do
2018-10-05 10:46:54 +00:00
before do
2019-02-19 20:51:11 +00:00
stub_feature_flags ( attempt_group_search_optimizations : true )
2018-10-05 10:46:54 +00:00
end
2018-09-05 11:10:36 +00:00
it 'works with popularity sort' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : group . to_param , search : 'foo' , sort : 'popularity' }
2018-09-05 11:10:36 +00:00
expect ( assigns ( :issues ) ) . to eq ( [ issue_1 ] )
end
it 'works with priority sort' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : group . to_param , search : 'foo' , sort : 'priority' }
2018-09-05 11:10:36 +00:00
expect ( assigns ( :issues ) ) . to eq ( [ issue_1 ] )
end
it 'works with label priority sort' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : group . to_param , search : 'foo' , sort : 'label_priority' }
2018-09-05 11:10:36 +00:00
expect ( assigns ( :issues ) ) . to eq ( [ issue_1 ] )
end
end
2016-03-21 20:01:38 +00:00
end
2019-10-23 09:06:03 +00:00
describe 'GET #merge_requests' , :sidekiq_might_not_need_inline do
2016-03-21 20:01:38 +00:00
let ( :merge_request_1 ) { create ( :merge_request , source_project : project ) }
let ( :merge_request_2 ) { create ( :merge_request , :simple , source_project : project ) }
before do
2016-04-16 19:09:08 +00:00
create_list ( :award_emoji , 3 , awardable : merge_request_2 )
create_list ( :award_emoji , 2 , awardable : merge_request_1 )
2016-06-01 09:23:09 +00:00
create_list ( :award_emoji , 2 , :downvote , awardable : merge_request_2 )
2016-03-21 20:01:38 +00:00
sign_in ( user )
end
context 'sorting by votes' do
it 'sorts most popular merge requests' do
2018-12-17 22:52:17 +00:00
get :merge_requests , params : { id : group . to_param , sort : 'upvotes_desc' }
2016-03-21 20:01:38 +00:00
expect ( assigns ( :merge_requests ) ) . to eq [ merge_request_2 , merge_request_1 ]
end
it 'sorts least popular merge requests' do
2018-12-17 22:52:17 +00:00
get :merge_requests , params : { id : group . to_param , sort : 'downvotes_desc' }
2016-03-21 20:01:38 +00:00
expect ( assigns ( :merge_requests ) ) . to eq [ merge_request_2 , merge_request_1 ]
end
end
end
2016-05-29 02:54:17 +00:00
describe 'DELETE #destroy' do
context 'as another user' do
it 'returns 404' do
sign_in ( create ( :user ) )
2018-12-17 22:52:17 +00:00
delete :destroy , params : { id : group . to_param }
2016-05-29 02:54:17 +00:00
2020-03-31 21:08:05 +00:00
expect ( response ) . to have_gitlab_http_status ( :not_found )
2016-05-29 02:54:17 +00:00
end
end
context 'as the group owner' do
before do
sign_in ( user )
end
it 'schedules a group destroy' do
2016-08-15 21:26:40 +00:00
Sidekiq :: Testing . fake! do
2018-12-17 22:52:17 +00:00
expect { delete :destroy , params : { id : group . to_param } } . to change ( GroupDestroyWorker . jobs , :size ) . by ( 1 )
2016-08-15 21:26:40 +00:00
end
2016-05-29 02:54:17 +00:00
end
it 'redirects to the root path' do
2018-12-17 22:52:17 +00:00
delete :destroy , params : { id : group . to_param }
2016-05-29 02:54:17 +00:00
expect ( response ) . to redirect_to ( root_path )
end
end
end
2016-12-20 16:52:27 +00:00
describe 'PUT update' do
before do
sign_in ( user )
end
2017-05-01 20:46:30 +00:00
it 'updates the path successfully' do
2018-12-17 22:52:17 +00:00
post :update , params : { id : group . to_param , group : { path : 'new_path' } }
2016-12-20 16:52:27 +00:00
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :found )
2016-12-20 16:52:27 +00:00
expect ( controller ) . to set_flash [ :notice ]
end
it 'does not update the path on error' do
allow_any_instance_of ( Group ) . to receive ( :move_dir ) . and_raise ( Gitlab :: UpdatePathError )
2018-12-17 22:52:17 +00:00
post :update , params : { id : group . to_param , group : { path : 'new_path' } }
2016-12-20 16:52:27 +00:00
2016-12-21 12:29:27 +00:00
expect ( assigns ( :group ) . errors ) . not_to be_empty
expect ( assigns ( :group ) . path ) . not_to eq ( 'new_path' )
2016-12-20 16:52:27 +00:00
end
2019-04-05 18:49:46 +00:00
it 'updates the project_creation_level successfully' do
post :update , params : { id : group . to_param , group : { project_creation_level : :: Gitlab :: Access :: MAINTAINER_PROJECT_ACCESS } }
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :found )
2019-04-05 18:49:46 +00:00
expect ( group . reload . project_creation_level ) . to eq ( :: Gitlab :: Access :: MAINTAINER_PROJECT_ACCESS )
end
2019-10-16 09:07:51 +00:00
2020-04-24 09:09:44 +00:00
context 'updating default_branch_protection' do
subject do
put :update , params : { id : group . to_param , group : { default_branch_protection : :: Gitlab :: Access :: PROTECTION_DEV_CAN_MERGE } }
end
2020-03-02 12:07:57 +00:00
2020-04-24 09:09:44 +00:00
context 'for users who have the ability to update default_branch_protection' do
it 'updates the attribute' do
subject
expect ( response ) . to have_gitlab_http_status ( :found )
expect ( group . reload . default_branch_protection ) . to eq ( :: Gitlab :: Access :: PROTECTION_DEV_CAN_MERGE )
end
end
context 'for users who do not have the ability to update default_branch_protection' do
it 'does not update the attribute' do
allow ( Ability ) . to receive ( :allowed? ) . and_call_original
allow ( Ability ) . to receive ( :allowed? ) . with ( user , :update_default_branch_protection , group ) { false }
subject
expect ( response ) . to have_gitlab_http_status ( :found )
expect ( group . reload . default_branch_protection ) . not_to eq ( :: Gitlab :: Access :: PROTECTION_DEV_CAN_MERGE )
end
end
2020-03-02 12:07:57 +00:00
end
2020-08-26 03:10:11 +00:00
context 'when there is a conflicting group path' do
render_views
let! ( :conflict_group ) { create ( :group , path : SecureRandom . hex ( 12 ) ) }
let! ( :old_name ) { group . name }
it 'does not render references to the conflicting group' do
put :update , params : { id : group . to_param , group : { path : conflict_group . path } }
expect ( response ) . to have_gitlab_http_status ( :ok )
expect ( group . reload . name ) . to eq ( old_name )
expect ( response . body ) . not_to include ( conflict_group . path )
end
end
2019-10-16 09:07:51 +00:00
context 'when a project inside the group has container repositories' do
before do
stub_container_registry_config ( enabled : true )
stub_container_registry_tags ( repository : / image / , tags : %w[ rc1 ] )
create ( :container_repository , project : project , name : :image )
end
it 'does allow the group to be renamed' do
post :update , params : { id : group . to_param , group : { name : 'new_name' } }
expect ( controller ) . to set_flash [ :notice ]
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :found )
2019-10-16 09:07:51 +00:00
expect ( group . reload . name ) . to eq ( 'new_name' )
end
it 'does not allow to path of the group to be changed' do
post :update , params : { id : group . to_param , group : { path : 'new_path' } }
expect ( assigns ( :group ) . errors [ :base ] . first ) . to match ( / Docker images in their Container Registry / )
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :ok )
2019-10-16 09:07:51 +00:00
end
end
2017-05-18 19:56:39 +00:00
end
describe '#ensure_canonical_path' do
before do
sign_in ( user )
end
context 'for a GET request' do
context 'when requesting groups at the root path' do
before do
allow ( request ) . to receive ( :original_fullpath ) . and_return ( " / #{ group_full_path } " )
2018-12-17 22:52:17 +00:00
get :show , params : { id : group_full_path }
2017-05-18 19:56:39 +00:00
end
2017-05-01 20:46:30 +00:00
2017-05-18 19:56:39 +00:00
context 'when requesting the canonical path with different casing' do
let ( :group_full_path ) { group . to_param . upcase }
2017-05-01 20:46:30 +00:00
2017-05-18 19:56:39 +00:00
it 'redirects to the correct casing' do
expect ( response ) . to redirect_to ( group )
expect ( controller ) . not_to set_flash [ :notice ]
end
end
context 'when requesting a redirected path' do
let ( :redirect_route ) { group . redirect_routes . create ( path : 'old-path' ) }
let ( :group_full_path ) { redirect_route . path }
it 'redirects to the canonical path' do
expect ( response ) . to redirect_to ( group )
expect ( controller ) . to set_flash [ :notice ] . to ( group_moved_message ( redirect_route , group ) )
end
context 'when the old group path is a substring of the scheme or host' do
let ( :redirect_route ) { group . redirect_routes . create ( path : 'http' ) }
it 'does not modify the requested host' do
expect ( response ) . to redirect_to ( group )
expect ( controller ) . to set_flash [ :notice ] . to ( group_moved_message ( redirect_route , group ) )
end
end
context 'when the old group path is substring of groups' do
# I.e. /groups/oups should not become /grfoo/oups
let ( :redirect_route ) { group . redirect_routes . create ( path : 'oups' ) }
it 'does not modify the /groups part of the path' do
expect ( response ) . to redirect_to ( group )
expect ( controller ) . to set_flash [ :notice ] . to ( group_moved_message ( redirect_route , group ) )
end
end
end
2017-05-01 20:46:30 +00:00
end
2017-05-18 19:56:39 +00:00
context 'when requesting groups under the /groups path' do
2017-05-18 23:23:05 +00:00
context 'when requesting the canonical path' do
context 'non-show path' do
context 'with exactly matching casing' do
it 'does not redirect' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : group . to_param }
2017-05-18 23:23:05 +00:00
2020-01-27 12:08:35 +00:00
expect ( response ) . not_to have_gitlab_http_status ( :moved_permanently )
2017-05-18 23:23:05 +00:00
end
end
2017-05-01 20:46:30 +00:00
2017-05-18 23:23:05 +00:00
context 'with different casing' do
it 'redirects to the correct casing' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : group . to_param . upcase }
2017-05-18 23:23:05 +00:00
expect ( response ) . to redirect_to ( issues_group_path ( group . to_param ) )
expect ( controller ) . not_to set_flash [ :notice ]
end
end
end
context 'show path' do
context 'with exactly matching casing' do
it 'does not redirect' do
2018-12-17 22:52:17 +00:00
get :show , params : { id : group . to_param }
2017-05-18 23:23:05 +00:00
2020-01-27 12:08:35 +00:00
expect ( response ) . not_to have_gitlab_http_status ( :moved_permanently )
2017-05-18 23:23:05 +00:00
end
end
context 'with different casing' do
it 'redirects to the correct casing at the root path' do
2018-12-17 22:52:17 +00:00
get :show , params : { id : group . to_param . upcase }
2017-05-18 23:23:05 +00:00
expect ( response ) . to redirect_to ( group )
expect ( controller ) . not_to set_flash [ :notice ]
end
end
2017-05-18 19:56:39 +00:00
end
end
context 'when requesting a redirected path' do
let ( :redirect_route ) { group . redirect_routes . create ( path : 'old-path' ) }
it 'redirects to the canonical path' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : redirect_route . path }
2017-05-18 19:56:39 +00:00
expect ( response ) . to redirect_to ( issues_group_path ( group . to_param ) )
expect ( controller ) . to set_flash [ :notice ] . to ( group_moved_message ( redirect_route , group ) )
end
context 'when the old group path is a substring of the scheme or host' do
let ( :redirect_route ) { group . redirect_routes . create ( path : 'http' ) }
it 'does not modify the requested host' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : redirect_route . path }
2017-05-18 19:56:39 +00:00
expect ( response ) . to redirect_to ( issues_group_path ( group . to_param ) )
expect ( controller ) . to set_flash [ :notice ] . to ( group_moved_message ( redirect_route , group ) )
end
end
context 'when the old group path is substring of groups' do
# I.e. /groups/oups should not become /grfoo/oups
let ( :redirect_route ) { group . redirect_routes . create ( path : 'oups' ) }
it 'does not modify the /groups part of the path' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : redirect_route . path }
2017-05-18 19:56:39 +00:00
expect ( response ) . to redirect_to ( issues_group_path ( group . to_param ) )
expect ( controller ) . to set_flash [ :notice ] . to ( group_moved_message ( redirect_route , group ) )
end
end
context 'when the old group path is substring of groups plus the new path' do
# I.e. /groups/oups/oup should not become /grfoos
let ( :redirect_route ) { group . redirect_routes . create ( path : 'oups/oup' ) }
it 'does not modify the /groups part of the path' do
2018-12-17 22:52:17 +00:00
get :issues , params : { id : redirect_route . path }
2017-05-18 19:56:39 +00:00
expect ( response ) . to redirect_to ( issues_group_path ( group . to_param ) )
expect ( controller ) . to set_flash [ :notice ] . to ( group_moved_message ( redirect_route , group ) )
end
end
end
2017-05-01 20:46:30 +00:00
end
2017-09-05 15:27:55 +00:00
2017-09-13 15:16:30 +00:00
context 'for a POST request' do
context 'when requesting the canonical path with different casing' do
it 'does not 404' do
2018-12-17 22:52:17 +00:00
post :update , params : { id : group . to_param . upcase , group : { path : 'new_path' } }
2017-05-18 19:56:39 +00:00
2020-01-27 12:08:35 +00:00
expect ( response ) . not_to have_gitlab_http_status ( :not_found )
2017-09-13 15:16:30 +00:00
end
2017-05-18 19:56:39 +00:00
2017-09-13 15:16:30 +00:00
it 'does not redirect to the correct casing' do
2018-12-17 22:52:17 +00:00
post :update , params : { id : group . to_param . upcase , group : { path : 'new_path' } }
2017-05-18 19:56:39 +00:00
2020-01-27 12:08:35 +00:00
expect ( response ) . not_to have_gitlab_http_status ( :moved_permanently )
2017-09-13 15:16:30 +00:00
end
2017-05-18 19:56:39 +00:00
end
2017-09-13 15:16:30 +00:00
context 'when requesting a redirected path' do
let ( :redirect_route ) { group . redirect_routes . create ( path : 'old-path' ) }
2017-05-01 20:46:30 +00:00
2017-09-13 15:16:30 +00:00
it 'returns not found' do
2018-12-17 22:52:17 +00:00
post :update , params : { id : redirect_route . path , group : { path : 'new_path' } }
2017-05-01 20:46:30 +00:00
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :not_found )
2017-09-13 15:16:30 +00:00
end
2017-05-18 19:56:39 +00:00
end
2017-05-01 20:46:30 +00:00
end
2017-05-11 20:57:03 +00:00
2017-09-13 15:16:30 +00:00
context 'for a DELETE request' do
context 'when requesting the canonical path with different casing' do
it 'does not 404' do
2018-12-17 22:52:17 +00:00
delete :destroy , params : { id : group . to_param . upcase }
2017-05-18 17:30:17 +00:00
2020-01-27 12:08:35 +00:00
expect ( response ) . not_to have_gitlab_http_status ( :not_found )
2017-09-13 15:16:30 +00:00
end
2017-05-18 17:30:17 +00:00
2017-09-13 15:16:30 +00:00
it 'does not redirect to the correct casing' do
2018-12-17 22:52:17 +00:00
delete :destroy , params : { id : group . to_param . upcase }
2017-05-18 19:56:39 +00:00
2020-01-27 12:08:35 +00:00
expect ( response ) . not_to have_gitlab_http_status ( :moved_permanently )
2017-09-13 15:16:30 +00:00
end
2017-05-18 19:56:39 +00:00
end
2017-09-13 15:16:30 +00:00
context 'when requesting a redirected path' do
let ( :redirect_route ) { group . redirect_routes . create ( path : 'old-path' ) }
2017-05-18 19:56:39 +00:00
2017-09-13 15:16:30 +00:00
it 'returns not found' do
2018-12-17 22:52:17 +00:00
delete :destroy , params : { id : redirect_route . path }
2017-05-18 19:56:39 +00:00
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :not_found )
2017-09-13 15:16:30 +00:00
end
2017-05-18 19:56:39 +00:00
end
2017-05-18 17:30:17 +00:00
end
end
2017-09-13 15:16:30 +00:00
def group_moved_message ( redirect_route , group )
" Group ' #{ redirect_route . path } ' was moved to ' #{ group . full_path } '. Please update any links and bookmarks that may still have the old path. "
end
2017-05-11 20:57:03 +00:00
end
2018-02-06 00:10:58 +00:00
2019-07-24 09:20:54 +00:00
describe 'PUT transfer' do
2018-02-06 00:10:58 +00:00
before do
sign_in ( user )
end
2018-10-30 10:53:01 +00:00
context 'when transferring to a subgroup goes right' do
2018-02-06 00:10:58 +00:00
let ( :new_parent_group ) { create ( :group , :public ) }
let! ( :group_member ) { create ( :group_member , :owner , group : group , user : user ) }
let! ( :new_parent_group_member ) { create ( :group_member , :owner , group : new_parent_group , user : user ) }
before do
put :transfer ,
2018-12-17 22:52:17 +00:00
params : {
id : group . to_param ,
new_parent_group_id : new_parent_group . id
}
2018-02-06 00:10:58 +00:00
end
2019-04-05 08:43:27 +00:00
it 'returns a notice' do
2018-02-06 00:10:58 +00:00
expect ( flash [ :notice ] ) . to eq ( " Group ' #{ group . name } ' was successfully transferred. " )
end
2019-04-05 08:43:27 +00:00
it 'redirects to the new path' do
2018-02-06 00:10:58 +00:00
expect ( response ) . to redirect_to ( " / #{ new_parent_group . path } / #{ group . path } " )
end
end
context 'when converting to a root group goes right' do
let ( :group ) { create ( :group , :public , :nested ) }
let! ( :group_member ) { create ( :group_member , :owner , group : group , user : user ) }
before do
put :transfer ,
2018-12-17 22:52:17 +00:00
params : {
id : group . to_param ,
new_parent_group_id : ''
}
2018-02-06 00:10:58 +00:00
end
2019-04-05 08:43:27 +00:00
it 'returns a notice' do
2018-02-06 00:10:58 +00:00
expect ( flash [ :notice ] ) . to eq ( " Group ' #{ group . name } ' was successfully transferred. " )
end
2019-04-05 08:43:27 +00:00
it 'redirects to the new path' do
2018-02-06 00:10:58 +00:00
expect ( response ) . to redirect_to ( " / #{ group . path } " )
end
end
context 'When the transfer goes wrong' do
let ( :new_parent_group ) { create ( :group , :public ) }
let! ( :group_member ) { create ( :group_member , :owner , group : group , user : user ) }
let! ( :new_parent_group_member ) { create ( :group_member , :owner , group : new_parent_group , user : user ) }
before do
allow_any_instance_of ( :: Groups :: TransferService ) . to receive ( :proceed_to_transfer ) . and_raise ( Gitlab :: UpdatePathError , 'namespace directory cannot be moved' )
put :transfer ,
2018-12-17 22:52:17 +00:00
params : {
id : group . to_param ,
new_parent_group_id : new_parent_group . id
}
2018-02-06 00:10:58 +00:00
end
2019-04-05 08:43:27 +00:00
it 'returns an alert' do
2018-02-06 00:10:58 +00:00
expect ( flash [ :alert ] ) . to eq " Transfer failed: namespace directory cannot be moved "
end
2019-04-05 08:43:27 +00:00
it 'redirects to the current path' do
2019-04-02 01:14:19 +00:00
expect ( response ) . to redirect_to ( edit_group_path ( group ) )
2018-02-06 00:10:58 +00:00
end
end
context 'when the user is not allowed to transfer the group' do
let ( :new_parent_group ) { create ( :group , :public ) }
let! ( :group_member ) { create ( :group_member , :guest , group : group , user : user ) }
let! ( :new_parent_group_member ) { create ( :group_member , :guest , group : new_parent_group , user : user ) }
before do
put :transfer ,
2018-12-17 22:52:17 +00:00
params : {
id : group . to_param ,
new_parent_group_id : new_parent_group . id
}
2018-02-06 00:10:58 +00:00
end
2019-04-05 08:43:27 +00:00
it 'is denied' do
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :not_found )
2018-02-06 00:10:58 +00:00
end
end
2019-10-16 09:07:51 +00:00
context 'transferring when a project has container images' do
let ( :group ) { create ( :group , :public , :nested ) }
let! ( :group_member ) { create ( :group_member , :owner , group : group , user : user ) }
before do
stub_container_registry_config ( enabled : true )
stub_container_registry_tags ( repository : / image / , tags : %w[ rc1 ] )
create ( :container_repository , project : project , name : :image )
put :transfer ,
params : {
id : group . to_param ,
new_parent_group_id : ''
}
end
it 'does not allow the group to be transferred' do
expect ( controller ) . to set_flash [ :alert ] . to match ( / Docker images in their Container Registry / )
expect ( response ) . to redirect_to ( edit_group_path ( group ) )
end
end
2018-02-06 00:10:58 +00:00
end
2018-11-28 19:06:02 +00:00
2020-04-09 12:09:24 +00:00
describe 'POST #export' do
context 'when the group export feature flag is not enabled' do
before do
sign_in ( admin )
stub_feature_flags ( group_import_export : false )
end
it 'returns a not found error' do
post :export , params : { id : group . to_param }
expect ( response ) . to have_gitlab_http_status ( :not_found )
end
end
context 'when the user does not have permission to export the group' do
before do
sign_in ( guest )
end
it 'returns an error' do
post :export , params : { id : group . to_param }
expect ( response ) . to have_gitlab_http_status ( :not_found )
end
end
context 'when supplied valid params' do
before do
sign_in ( admin )
end
it 'triggers the export job' do
expect ( GroupExportWorker ) . to receive ( :perform_async ) . with ( admin . id , group . id , { } )
post :export , params : { id : group . to_param }
end
it 'redirects to the edit page' do
post :export , params : { id : group . to_param }
expect ( response ) . to have_gitlab_http_status ( :found )
end
end
context 'when the endpoint receives requests above the rate limit' do
before do
sign_in ( admin )
2020-06-03 12:08:21 +00:00
allow ( Gitlab :: ApplicationRateLimiter )
. to receive ( :increment )
2020-07-07 15:08:49 +00:00
. and_return ( Gitlab :: ApplicationRateLimiter . rate_limits [ :group_export ] [ :threshold ] . call + 1 )
2020-04-09 12:09:24 +00:00
end
it 'throttles the endpoint' do
post :export , params : { id : group . to_param }
2020-06-03 12:08:21 +00:00
expect ( response . body ) . to eq ( 'This endpoint has been requested too many times. Try again later.' )
expect ( response ) . to have_gitlab_http_status :too_many_requests
2020-04-09 12:09:24 +00:00
end
end
end
describe 'GET #download_export' do
context 'when there is a file available to download' do
let ( :export_file ) { fixture_file_upload ( 'spec/fixtures/group_export.tar.gz' ) }
before do
sign_in ( admin )
create ( :import_export_upload , group : group , export_file : export_file )
end
it 'sends the file' do
get :download_export , params : { id : group . to_param }
expect ( response . body ) . to eq export_file . tempfile . read
end
end
context 'when there is no file available to download' do
before do
sign_in ( admin )
end
it 'returns not found' do
get :download_export , params : { id : group . to_param }
expect ( flash [ :alert ] )
. to eq 'Group export link has expired. Please generate a new export from your group settings.'
expect ( response ) . to redirect_to ( edit_group_path ( group ) )
end
end
context 'when the group export feature flag is not enabled' do
before do
sign_in ( admin )
stub_feature_flags ( group_import_export : false )
end
it 'returns a not found error' do
post :export , params : { id : group . to_param }
expect ( response ) . to have_gitlab_http_status ( :not_found )
end
end
context 'when the user does not have the required permissions' do
before do
sign_in ( guest )
end
it 'returns not_found' do
get :download_export , params : { id : group . to_param }
expect ( response ) . to have_gitlab_http_status ( :not_found )
end
end
context 'when the endpoint receives requests above the rate limit' do
before do
sign_in ( admin )
2020-06-03 12:08:21 +00:00
allow ( Gitlab :: ApplicationRateLimiter )
. to receive ( :increment )
2020-07-07 15:08:49 +00:00
. and_return ( Gitlab :: ApplicationRateLimiter . rate_limits [ :group_download_export ] [ :threshold ] . call + 1 )
2020-04-09 12:09:24 +00:00
end
it 'throttles the endpoint' do
get :download_export , params : { id : group . to_param }
2020-06-03 12:08:21 +00:00
expect ( response . body ) . to eq ( 'This endpoint has been requested too many times. Try again later.' )
expect ( response ) . to have_gitlab_http_status :too_many_requests
2020-04-09 12:09:24 +00:00
end
end
end
2018-11-28 19:06:02 +00:00
context 'token authentication' do
it_behaves_like 'authenticates sessionless user' , :show , :atom , public : true do
before do
default_params . merge! ( id : group )
end
end
it_behaves_like 'authenticates sessionless user' , :issues , :atom , public : true do
before do
default_params . merge! ( id : group , author_id : user . id )
end
end
it_behaves_like 'authenticates sessionless user' , :issues_calendar , :ics , public : true do
before do
default_params . merge! ( id : group )
end
end
end
2019-04-09 15:38:58 +00:00
describe 'external authorization' do
before do
group . add_owner ( user )
sign_in ( user )
end
context 'with external authorization service enabled' do
before do
enable_external_authorization_service_check
end
describe 'GET #show' do
it 'is successful' do
get :show , params : { id : group . to_param }
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :ok )
2019-04-09 15:38:58 +00:00
end
it 'does not allow other formats' do
get :show , params : { id : group . to_param } , format : :atom
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :forbidden )
2019-04-09 15:38:58 +00:00
end
end
describe 'GET #edit' do
it 'is successful' do
get :edit , params : { id : group . to_param }
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :ok )
2019-04-09 15:38:58 +00:00
end
end
describe 'GET #new' do
it 'is successful' do
get :new
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :ok )
2019-04-09 15:38:58 +00:00
end
end
describe 'GET #index' do
it 'is successful' do
get :index
# Redirects to the dashboard
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :found )
2019-04-09 15:38:58 +00:00
end
end
describe 'POST #create' do
it 'creates a group' do
expect do
post :create , params : { group : { name : 'a name' , path : 'a-name' } }
end . to change { Group . count } . by ( 1 )
end
end
describe 'PUT #update' do
it 'updates a group' do
expect do
put :update , params : { id : group . to_param , group : { name : 'world' } }
end . to change { group . reload . name }
end
2020-03-26 18:08:03 +00:00
context " malicious group name " do
subject { put :update , params : { id : group . to_param , group : { name : " <script>alert('Attack!');</script> " } } }
it { is_expected . to render_template ( :edit ) }
it 'does not update name' do
expect { subject } . not_to change { group . reload . name }
end
end
2019-04-09 15:38:58 +00:00
end
describe 'DELETE #destroy' do
it 'deletes the group' do
delete :destroy , params : { id : group . to_param }
2020-01-27 12:08:35 +00:00
expect ( response ) . to have_gitlab_http_status ( :found )
2019-04-09 15:38:58 +00:00
end
end
end
describe 'GET #activity' do
subject { get :activity , params : { id : group . to_param } }
it_behaves_like 'disabled when using an external authorization service'
end
2020-06-19 18:08:39 +00:00
describe " GET # activity as JSON " do
include DesignManagementTestHelpers
render_views
let ( :project ) { create ( :project , :public , group : group ) }
let ( :other_project ) { create ( :project , :public , group : group ) }
def get_activity
get :activity , params : { format : :json , id : group . to_param }
end
before do
enable_design_management
issue = create ( :issue , project : project )
create ( :event , :created , project : project , target : issue )
create ( :design_event , project : project )
create ( :design_event , project : other_project )
sign_in ( user )
request . cookies [ :event_filter ] = 'all'
end
it 'returns count' do
get_activity
expect ( json_response [ 'count' ] ) . to eq ( 3 )
end
end
2019-04-09 15:38:58 +00:00
describe 'GET #issues' do
subject { get :issues , params : { id : group . to_param } }
it_behaves_like 'disabled when using an external authorization service'
end
describe 'GET #merge_requests' do
subject { get :merge_requests , params : { id : group . to_param } }
it_behaves_like 'disabled when using an external authorization service'
end
end
2016-01-24 00:08:15 +00:00
end