diff options
Diffstat (limited to 'spec')
26 files changed, 289 insertions, 39 deletions
diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb index 055c98ebdbc..906cc5cb336 100644 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ b/spec/controllers/import/bitbucket_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Import::BitbucketController do +RSpec.describe Import::BitbucketController, feature_category: :importers do include ImportSpecHelper let(:user) { create(:user) } @@ -445,5 +445,16 @@ RSpec.describe Import::BitbucketController do ) end end + + context 'when user can not import projects' do + let!(:other_namespace) { create(:group, name: 'other_namespace').tap { |other_namespace| other_namespace.add_developer(user) } } + + it 'returns 422 response' do + post :create, params: { target_namespace: other_namespace.name }, format: :json + + expect(response).to have_gitlab_http_status(:unprocessable_entity) + expect(response.parsed_body['errors']).to eq('You are not allowed to import projects in this namespace.') + end + end end end diff --git a/spec/controllers/import/bitbucket_server_controller_spec.rb b/spec/controllers/import/bitbucket_server_controller_spec.rb index ac56d3af54f..b2a56423253 100644 --- a/spec/controllers/import/bitbucket_server_controller_spec.rb +++ b/spec/controllers/import/bitbucket_server_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Import::BitbucketServerController do +RSpec.describe Import::BitbucketServerController, feature_category: :importers do let(:user) { create(:user) } let(:project_key) { 'test-project' } let(:repo_slug) { 'some-repo' } diff --git a/spec/controllers/import/fogbugz_controller_spec.rb b/spec/controllers/import/fogbugz_controller_spec.rb index e2d59fc213a..40a5c59fa2d 100644 --- a/spec/controllers/import/fogbugz_controller_spec.rb +++ b/spec/controllers/import/fogbugz_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Import::FogbugzController do +RSpec.describe Import::FogbugzController, feature_category: :importers do include ImportSpecHelper let(:user) { create(:user) } diff --git a/spec/controllers/import/gitea_controller_spec.rb b/spec/controllers/import/gitea_controller_spec.rb index 568712d29cb..7466ffb2393 100644 --- a/spec/controllers/import/gitea_controller_spec.rb +++ b/spec/controllers/import/gitea_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Import::GiteaController do +RSpec.describe Import::GiteaController, feature_category: :importers do include ImportSpecHelper let(:provider) { :gitea } diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb index 7b3978297fb..2c09f8c010e 100644 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ b/spec/controllers/import/gitlab_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Import::GitlabController do +RSpec.describe Import::GitlabController, feature_category: :importers do include ImportSpecHelper let(:user) { create(:user) } diff --git a/spec/controllers/import/manifest_controller_spec.rb b/spec/controllers/import/manifest_controller_spec.rb index 6f805b44e89..23d5d37ed88 100644 --- a/spec/controllers/import/manifest_controller_spec.rb +++ b/spec/controllers/import/manifest_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Import::ManifestController, :clean_gitlab_redis_shared_state do +RSpec.describe Import::ManifestController, :clean_gitlab_redis_shared_state, feature_category: :importers do include ImportSpecHelper let_it_be(:user) { create(:user) } @@ -45,7 +45,7 @@ RSpec.describe Import::ManifestController, :clean_gitlab_redis_shared_state do end end - context 'when the user cannot create projects in the group' do + context 'when the user cannot import projects in the group' do it 'displays an error' do sign_in(create(:user)) diff --git a/spec/controllers/projects/imports_controller_spec.rb b/spec/controllers/projects/imports_controller_spec.rb index b4704d56cd9..4502f3d7bd9 100644 --- a/spec/controllers/projects/imports_controller_spec.rb +++ b/spec/controllers/projects/imports_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Projects::ImportsController do +RSpec.describe Projects::ImportsController, feature_category: :importers do let(:user) { create(:user) } let(:project) { create(:project) } @@ -149,17 +149,7 @@ RSpec.describe Projects::ImportsController do import_state.update!(status: :started) end - context 'when group allows developers to create projects' do - let(:group) { create(:group, project_creation_level: Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) } - - it 'renders template' do - get :show, params: { namespace_id: project.namespace.to_param, project_id: project } - - expect(response).to render_template :show - end - end - - context 'when group prohibits developers to create projects' do + context 'when group prohibits developers to import projects' do let(:group) { create(:group, project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS) } it 'returns 404 response' do diff --git a/spec/finders/groups/accepting_project_imports_finder_spec.rb b/spec/finders/groups/accepting_project_imports_finder_spec.rb new file mode 100644 index 00000000000..4e06c2cbc67 --- /dev/null +++ b/spec/finders/groups/accepting_project_imports_finder_spec.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Groups::AcceptingProjectImportsFinder, feature_category: :importers do + let_it_be(:user) { create(:user) } + let_it_be(:group_where_direct_owner) { create(:group) } + let_it_be(:subgroup_of_group_where_direct_owner) { create(:group, parent: group_where_direct_owner) } + let_it_be(:group_where_direct_maintainer) { create(:group) } + let_it_be(:group_where_direct_maintainer_but_cant_create_projects) do + create(:group, project_creation_level: Gitlab::Access::NO_ONE_PROJECT_ACCESS) + end + + let_it_be(:group_where_direct_developer_but_developers_cannot_create_projects) { create(:group) } + let_it_be(:group_where_direct_developer) do + create(:group, project_creation_level: Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) + end + + let_it_be(:shared_with_group_where_direct_owner_as_owner) { create(:group) } + + let_it_be(:shared_with_group_where_direct_owner_as_developer) do + create(:group, project_creation_level: Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) + end + + let_it_be(:shared_with_group_where_direct_owner_as_developer_but_developers_cannot_create_projects) do + create(:group) + end + + let_it_be(:shared_with_group_where_direct_developer_as_maintainer) do + create(:group, project_creation_level: Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) + end + + let_it_be(:shared_with_group_where_direct_owner_as_guest) { create(:group) } + let_it_be(:shared_with_group_where_direct_owner_as_maintainer) { create(:group) } + let_it_be(:shared_with_group_where_direct_developer_as_owner) do + create(:group, project_creation_level: Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) + end + + let_it_be(:subgroup_of_shared_with_group_where_direct_owner_as_maintainer) do + create(:group, parent: shared_with_group_where_direct_owner_as_maintainer) + end + + before do + group_where_direct_owner.add_owner(user) + group_where_direct_maintainer.add_maintainer(user) + group_where_direct_developer_but_developers_cannot_create_projects.add_developer(user) + group_where_direct_developer.add_developer(user) + + create(:group_group_link, :owner, + shared_with_group: group_where_direct_owner, + shared_group: shared_with_group_where_direct_owner_as_owner + ) + + create(:group_group_link, :developer, + shared_with_group: group_where_direct_owner, + shared_group: shared_with_group_where_direct_owner_as_developer_but_developers_cannot_create_projects + ) + + create(:group_group_link, :maintainer, + shared_with_group: group_where_direct_developer, + shared_group: shared_with_group_where_direct_developer_as_maintainer + ) + + create(:group_group_link, :developer, + shared_with_group: group_where_direct_owner, + shared_group: shared_with_group_where_direct_owner_as_developer + ) + + create(:group_group_link, :guest, + shared_with_group: group_where_direct_owner, + shared_group: shared_with_group_where_direct_owner_as_guest + ) + + create(:group_group_link, :maintainer, + shared_with_group: group_where_direct_owner, + shared_group: shared_with_group_where_direct_owner_as_maintainer + ) + + create(:group_group_link, :owner, + shared_with_group: group_where_direct_developer_but_developers_cannot_create_projects, + shared_group: shared_with_group_where_direct_developer_as_owner + ) + end + + describe '#execute' do + subject(:result) { described_class.new(user).execute } + + it 'only returns groups where the user has access to import projects' do + expect(result).to match_array([ + group_where_direct_owner, + subgroup_of_group_where_direct_owner, + group_where_direct_maintainer, + # groups arising from group shares + shared_with_group_where_direct_owner_as_owner, + shared_with_group_where_direct_owner_as_maintainer, + subgroup_of_shared_with_group_where_direct_owner_as_maintainer + ]) + + expect(result).not_to include(group_where_direct_developer) + expect(result).not_to include(shared_with_group_where_direct_developer_as_owner) + expect(result).not_to include(shared_with_group_where_direct_developer_as_maintainer) + expect(result).not_to include(shared_with_group_where_direct_owner_as_developer) + end + end +end diff --git a/spec/finders/groups/user_groups_finder_spec.rb b/spec/finders/groups/user_groups_finder_spec.rb index 999079468e5..f6df396037c 100644 --- a/spec/finders/groups/user_groups_finder_spec.rb +++ b/spec/finders/groups/user_groups_finder_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Groups::UserGroupsFinder do +RSpec.describe Groups::UserGroupsFinder, feature_category: :subgroups do describe '#execute' do let_it_be(:user) { create(:user) } let_it_be(:root_group) { create(:group, name: 'Root group', path: 'root-group') } @@ -98,6 +98,24 @@ RSpec.describe Groups::UserGroupsFinder do end end + context 'when permission is :import_projects' do + let(:arguments) { { permission_scope: :import_projects } } + + specify do + is_expected.to contain_exactly( + public_maintainer_group, + public_owner_group, + private_maintainer_group + ) + end + + it_behaves_like 'user group finder searching by name or path' do + let(:keyword_search_expected_groups) do + [public_maintainer_group] + end + end + end + context 'when permission is :transfer_projects' do let(:arguments) { { permission_scope: :transfer_projects } } diff --git a/spec/frontend/import_entities/components/group_dropdown_spec.js b/spec/frontend/import_entities/components/group_dropdown_spec.js index b44bc33de6f..14f39a35387 100644 --- a/spec/frontend/import_entities/components/group_dropdown_spec.js +++ b/spec/frontend/import_entities/components/group_dropdown_spec.js @@ -6,7 +6,7 @@ import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import GroupDropdown from '~/import_entities/components/group_dropdown.vue'; import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants'; -import searchNamespacesWhereUserCanCreateProjectsQuery from '~/projects/new/queries/search_namespaces_where_user_can_create_projects.query.graphql'; +import searchNamespacesWhereUserCanImportProjectsQuery from '~/import_entities/import_projects/graphql/queries/search_namespaces_where_user_can_import_projects.query.graphql'; Vue.use(VueApollo); @@ -49,7 +49,7 @@ describe('Import entities group dropdown component', () => { const createComponent = (propsData) => { const apolloProvider = createMockApollo([ - [searchNamespacesWhereUserCanCreateProjectsQuery, () => SEARCH_NAMESPACES_MOCK], + [searchNamespacesWhereUserCanImportProjectsQuery, () => SEARCH_NAMESPACES_MOCK], ]); namespacesTracker = jest.fn(); diff --git a/spec/frontend/import_entities/import_groups/components/import_table_spec.js b/spec/frontend/import_entities/import_groups/components/import_table_spec.js index b1aa94cf418..dae5671777c 100644 --- a/spec/frontend/import_entities/import_groups/components/import_table_spec.js +++ b/spec/frontend/import_entities/import_groups/components/import_table_spec.js @@ -15,7 +15,7 @@ import ImportTable from '~/import_entities/import_groups/components/import_table import importGroupsMutation from '~/import_entities/import_groups/graphql/mutations/import_groups.mutation.graphql'; import PaginationBar from '~/vue_shared/components/pagination_bar/pagination_bar.vue'; import PaginationLinks from '~/vue_shared/components/pagination_links.vue'; -import searchNamespacesWhereUserCanCreateProjectsQuery from '~/projects/new/queries/search_namespaces_where_user_can_create_projects.query.graphql'; +import searchNamespacesWhereUserCanImportProjectsQuery from '~/import_entities/import_projects/graphql/queries/search_namespaces_where_user_can_import_projects.query.graphql'; import { AVAILABLE_NAMESPACES, @@ -74,7 +74,7 @@ describe('import table', () => { apolloProvider = createMockApollo( [ [ - searchNamespacesWhereUserCanCreateProjectsQuery, + searchNamespacesWhereUserCanImportProjectsQuery, () => Promise.resolve(availableNamespacesFixture), ], ], diff --git a/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js b/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js index a524d9ebdb0..a957e85723f 100644 --- a/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js +++ b/spec/frontend/import_entities/import_groups/components/import_target_cell_spec.js @@ -8,7 +8,7 @@ import ImportGroupDropdown from '~/import_entities/components/group_dropdown.vue import { STATUSES } from '~/import_entities/constants'; import ImportTargetCell from '~/import_entities/import_groups/components/import_target_cell.vue'; import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants'; -import searchNamespacesWhereUserCanCreateProjectsQuery from '~/projects/new/queries/search_namespaces_where_user_can_create_projects.query.graphql'; +import searchNamespacesWhereUserCanImportProjectsQuery from '~/import_entities/import_projects/graphql/queries/search_namespaces_where_user_can_import_projects.query.graphql'; import { generateFakeEntry, @@ -42,7 +42,7 @@ describe('import target cell', () => { const createComponent = (props) => { apolloProvider = createMockApollo([ [ - searchNamespacesWhereUserCanCreateProjectsQuery, + searchNamespacesWhereUserCanImportProjectsQuery, () => Promise.resolve(availableNamespacesFixture), ], ]); diff --git a/spec/frontend/projects/new/components/app_spec.js b/spec/frontend/projects/new/components/app_spec.js index 16576523c66..60d8385eb91 100644 --- a/spec/frontend/projects/new/components/app_spec.js +++ b/spec/frontend/projects/new/components/app_spec.js @@ -41,6 +41,22 @@ describe('Experimental new project creation app', () => { ).toBe(isCiCdAvailable); }); + it.each` + canImportProjects | outcome + ${false} | ${'do not show Import panel'} + ${true} | ${'show Import panel'} + `('$outcome when canImportProjects is $canImportProjects', ({ canImportProjects }) => { + createComponent({ + canImportProjects, + }); + + expect( + findNewNamespacePage() + .props() + .panels.some((p) => p.name === 'import_project'), + ).toBe(canImportProjects); + }); + it('creates correct breadcrumbs for top-level projects', () => { createComponent(); diff --git a/spec/helpers/avatars_helper_spec.rb b/spec/helpers/avatars_helper_spec.rb index 6eb97a99264..b7fdadbd036 100644 --- a/spec/helpers/avatars_helper_spec.rb +++ b/spec/helpers/avatars_helper_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe AvatarsHelper do +RSpec.describe AvatarsHelper, feature_category: :source_code_management do include UploadHelpers let_it_be(:user) { create(:user) } @@ -88,7 +88,7 @@ RSpec.describe AvatarsHelper do describe '#avatar_icon_for' do let!(:user) { create(:user, avatar: File.open(uploaded_image_temp_path), email: 'bar@example.com') } let(:email) { 'foo@example.com' } - let!(:another_user) { create(:user, avatar: File.open(uploaded_image_temp_path), email: email) } + let!(:another_user) { create(:user, :public_email, avatar: File.open(uploaded_image_temp_path), email: email) } it 'prefers the user to retrieve the avatar_url' do expect(helper.avatar_icon_for(user, email).to_s) @@ -102,7 +102,7 @@ RSpec.describe AvatarsHelper do end describe '#avatar_icon_for_email', :clean_gitlab_redis_cache do - let(:user) { create(:user, avatar: File.open(uploaded_image_temp_path)) } + let(:user) { create(:user, :public_email, avatar: File.open(uploaded_image_temp_path)) } subject { helper.avatar_icon_for_email(user.email).to_s } @@ -114,6 +114,14 @@ RSpec.describe AvatarsHelper do end end + context 'when a private email is used' do + it 'calls gravatar_icon' do + expect(helper).to receive(:gravatar_icon).with(user.commit_email, 20, 2) + + helper.avatar_icon_for_email(user.commit_email, 20, 2) + end + end + context 'when no user exists for the email' do it 'calls gravatar_icon' do expect(helper).to receive(:gravatar_icon).with('foo@example.com', 20, 2) @@ -136,7 +144,7 @@ RSpec.describe AvatarsHelper do it_behaves_like "returns avatar for email" it "caches the request" do - expect(User).to receive(:find_by_any_email).once.and_call_original + expect(User).to receive(:with_public_email).once.and_call_original expect(helper.avatar_icon_for_email(user.email).to_s).to eq(user.avatar.url) expect(helper.avatar_icon_for_email(user.email).to_s).to eq(user.avatar.url) diff --git a/spec/lib/banzai/filter/asset_proxy_filter_spec.rb b/spec/lib/banzai/filter/asset_proxy_filter_spec.rb index 004c70c28f1..dc6ac52a8c2 100644 --- a/spec/lib/banzai/filter/asset_proxy_filter_spec.rb +++ b/spec/lib/banzai/filter/asset_proxy_filter_spec.rb @@ -80,6 +80,15 @@ RSpec.describe Banzai::Filter::AssetProxyFilter, feature_category: :team_plannin expect(doc.at_css('img')['data-canonical-src']).to eq src end + it 'replaces invalid URLs' do + src = '///example.com/test.png' + new_src = 'https://assets.example.com/3368d2c7b9bed775bdd1e811f36a4b80a0dcd8ab/2f2f2f6578616d706c652e636f6d2f746573742e706e67' + doc = filter(image(src), @context) + + expect(doc.at_css('img')['src']).to eq new_src + expect(doc.at_css('img')['data-canonical-src']).to eq src + end + it 'skips internal images' do src = "#{Gitlab.config.gitlab.url}/test.png" doc = filter(image(src), @context) diff --git a/spec/lib/banzai/filter/commit_trailers_filter_spec.rb b/spec/lib/banzai/filter/commit_trailers_filter_spec.rb index 3ebe0798972..896f3beb7c2 100644 --- a/spec/lib/banzai/filter/commit_trailers_filter_spec.rb +++ b/spec/lib/banzai/filter/commit_trailers_filter_spec.rb @@ -218,7 +218,7 @@ RSpec.describe Banzai::Filter::CommitTrailersFilter, feature_category: :source_c # any path-only link will automatically be prefixed # with the path of its repository. # See: "build_relative_path" in "lib/banzai/filter/relative_link_filter.rb" - let(:user_with_avatar) { create(:user, :with_avatar, username: 'foobar') } + let(:user_with_avatar) { create(:user, :public_email, :with_avatar, username: 'foobar') } it 'returns a full path for avatar urls' do _, message_html = build_commit_message( diff --git a/spec/lib/gitlab/checks/branch_check_spec.rb b/spec/lib/gitlab/checks/branch_check_spec.rb index d6280d3c28c..7f535e86d69 100644 --- a/spec/lib/gitlab/checks/branch_check_spec.rb +++ b/spec/lib/gitlab/checks/branch_check_spec.rb @@ -26,8 +26,14 @@ RSpec.describe Gitlab::Checks::BranchCheck do expect { subject.validate! }.to raise_error(Gitlab::GitAccess::ForbiddenError, "You cannot create a branch with a 40-character hexadecimal branch name.") end + it "prohibits 40-character hexadecimal branch names as the start of a path" do + allow(subject).to receive(:branch_name).and_return("267208abfe40e546f5e847444276f7d43a39503e/test") + + expect { subject.validate! }.to raise_error(Gitlab::GitAccess::ForbiddenError, "You cannot create a branch with a 40-character hexadecimal branch name.") + end + it "doesn't prohibit a nested hexadecimal in a branch name" do - allow(subject).to receive(:branch_name).and_return("fix-267208abfe40e546f5e847444276f7d43a39503e") + allow(subject).to receive(:branch_name).and_return("267208abfe40e546f5e847444276f7d43a39503e-fix") expect { subject.validate! }.not_to raise_error end diff --git a/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb b/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb index de10653d87e..a2ab59f56ab 100644 --- a/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb +++ b/spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb @@ -23,8 +23,7 @@ RSpec.describe Preloaders::UserMaxAccessLevelInProjectsPreloader do # we have an existing N+1, one for each project for which user is not a member # in this spec, project_3, project_4, project_5 # https://gitlab.com/gitlab-org/gitlab/-/issues/362890 - ee_only_policy_check_queries = Gitlab.ee? ? 1 : 0 - expect { query }.to make_queries(projects.size + 3 + ee_only_policy_check_queries) + expect { query }.to make_queries(projects.size + 3) end end diff --git a/spec/policies/namespaces/user_namespace_policy_spec.rb b/spec/policies/namespaces/user_namespace_policy_spec.rb index bb821490e30..3488f33f15c 100644 --- a/spec/policies/namespaces/user_namespace_policy_spec.rb +++ b/spec/policies/namespaces/user_namespace_policy_spec.rb @@ -2,13 +2,13 @@ require 'spec_helper' -RSpec.describe Namespaces::UserNamespacePolicy do +RSpec.describe Namespaces::UserNamespacePolicy, feature_category: :subgroups do let_it_be(:user) { create(:user) } let_it_be(:owner) { create(:user) } let_it_be(:admin) { create(:admin) } let_it_be(:namespace) { create(:user_namespace, owner: owner) } - let(:owner_permissions) { [:owner_access, :create_projects, :admin_namespace, :read_namespace, :read_statistics, :transfer_projects, :admin_package, :read_billing, :edit_billing] } + let(:owner_permissions) { [:owner_access, :create_projects, :admin_namespace, :read_namespace, :read_statistics, :transfer_projects, :admin_package, :read_billing, :edit_billing, :import_projects] } subject { described_class.new(current_user, namespace) } @@ -34,6 +34,7 @@ RSpec.describe Namespaces::UserNamespacePolicy do it { is_expected.to be_disallowed(:create_projects) } it { is_expected.to be_disallowed(:transfer_projects) } + it { is_expected.to be_disallowed(:import_projects) } end context 'bot user' do @@ -41,6 +42,7 @@ RSpec.describe Namespaces::UserNamespacePolicy do it { is_expected.to be_disallowed(:create_projects) } it { is_expected.to be_disallowed(:transfer_projects) } + it { is_expected.to be_disallowed(:import_projects) } end end @@ -103,4 +105,26 @@ RSpec.describe Namespaces::UserNamespacePolicy do it { is_expected.to be_disallowed(:create_projects) } end end + + describe 'import projects' do + context 'when user can import projects' do + let(:current_user) { owner } + + before do + allow(current_user).to receive(:can_import_project?).and_return(true) + end + + it { is_expected.to be_allowed(:import_projects) } + end + + context 'when user cannot create projects' do + let(:current_user) { user } + + before do + allow(current_user).to receive(:can_import_project?).and_return(false) + end + + it { is_expected.to be_disallowed(:import_projects) } + end + end end diff --git a/spec/requests/import/gitlab_projects_controller_spec.rb b/spec/requests/import/gitlab_projects_controller_spec.rb index b2c2d306e53..fe3ea9e9c9e 100644 --- a/spec/requests/import/gitlab_projects_controller_spec.rb +++ b/spec/requests/import/gitlab_projects_controller_spec.rb @@ -90,4 +90,16 @@ RSpec.describe Import::GitlabProjectsController, feature_category: :importers do subject { post authorize_import_gitlab_project_path, headers: workhorse_headers } end end + + describe 'GET new' do + context 'when the user is not allowed to import projects' do + let!(:group) { create(:group).tap { |group| group.add_developer(user) } } + + it 'returns 404' do + get new_import_gitlab_project_path, params: { namespace_id: group.id } + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end end diff --git a/spec/services/import/bitbucket_server_service_spec.rb b/spec/services/import/bitbucket_server_service_spec.rb index aea6c45b3a8..ca554fb01c3 100644 --- a/spec/services/import/bitbucket_server_service_spec.rb +++ b/spec/services/import/bitbucket_server_service_spec.rb @@ -93,7 +93,7 @@ RSpec.describe Import::BitbucketServerService, feature_category: :importers do result = subject.execute(credentials) expect(result).to include( - message: "You don't have permissions to create this project", + message: "You don't have permissions to import this project", status: :error, http_status: :unauthorized ) diff --git a/spec/services/import/fogbugz_service_spec.rb b/spec/services/import/fogbugz_service_spec.rb index 6953213add7..ad02dc31da1 100644 --- a/spec/services/import/fogbugz_service_spec.rb +++ b/spec/services/import/fogbugz_service_spec.rb @@ -61,7 +61,7 @@ RSpec.describe Import::FogbugzService, feature_category: :importers do result = subject.execute(credentials) expect(result).to include( - message: "You don't have permissions to create this project", + message: "You don't have permissions to import this project", status: :error, http_status: :unauthorized ) diff --git a/spec/services/import/github_service_spec.rb b/spec/services/import/github_service_spec.rb index 5d762568a62..a8928fb5c09 100644 --- a/spec/services/import/github_service_spec.rb +++ b/spec/services/import/github_service_spec.rb @@ -291,7 +291,7 @@ RSpec.describe Import::GithubService, feature_category: :importers do { status: :error, http_status: :unprocessable_entity, - message: 'This namespace has already been taken. Choose a different one.' + message: 'You are not allowed to import projects in this namespace.' } end end diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index 495e2277d43..35b715d82ee 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -254,6 +254,23 @@ RSpec.describe Projects::CreateService, '#execute', feature_category: :projects end it_behaves_like 'has sync-ed traversal_ids' + + context 'when project is an import' do + context 'when user is not allowed to import projects' do + let(:group) do + create(:group).tap do |group| + group.add_developer(user) + end + end + + it 'does not create the project' do + project = create_project(user, opts.merge!(namespace_id: group.id, import_type: 'gitlab_project')) + + expect(project).not_to be_persisted + expect(project.errors.messages[:user].first).to eq('is not allowed to import projects') + end + end + end end context 'group sharing', :sidekiq_inline do diff --git a/spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb b/spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb index de38d1ff9f8..af1843bae28 100644 --- a/spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb +++ b/spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb @@ -138,6 +138,19 @@ RSpec.shared_examples 'a GitHub-ish import controller: GET status' do .not_to exceed_all_query_limit(control_count) end + context 'when user is not allowed to import projects' do + let(:user) { create(:user) } + let!(:group) { create(:group).tap { |group| group.add_developer(user) } } + + it 'returns 404' do + expect(stub_client(repos: [], orgs: [])).to receive(:repos) + + get :status, params: { namespace_id: group.id }, format: :html + + expect(response).to have_gitlab_http_status(:not_found) + end + end + context 'when filtering' do let(:repo_2) { repo_fake.new(login: 'emacs', full_name: 'asd/emacs', name: 'emacs', owner: { login: 'owner' }) } let(:project) { create(:project, import_type: provider, namespace: user.namespace, import_status: :finished, import_source: 'example/repo') } diff --git a/spec/support/shared_examples/controllers/import_controller_status_shared_examples.rb b/spec/support/shared_examples/controllers/import_controller_status_shared_examples.rb index 44baadaaade..e94f063399d 100644 --- a/spec/support/shared_examples/controllers/import_controller_status_shared_examples.rb +++ b/spec/support/shared_examples/controllers/import_controller_status_shared_examples.rb @@ -19,4 +19,26 @@ RSpec.shared_examples 'import controller status' do expect(json_response.dig("imported_projects", 0, "id")).to eq(project.id) expect(json_response.dig("provider_repos", 0, "id")).to eq(repo_id) end + + context 'when format is html' do + context 'when namespace_id is present' do + let!(:developer_group) { create(:group).tap { |g| g.add_developer(user) } } + + context 'when user cannot import projects' do + it 'returns 404' do + get :status, params: { namespace_id: developer_group.id }, format: :html + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when user can import projects' do + it 'returns 200' do + get :status, params: { namespace_id: group.id }, format: :html + + expect(response).to have_gitlab_http_status(:ok) + end + end + end + end end |