diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-29 15:10:19 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-29 15:10:19 +0300 |
commit | d15aa4cf2e1b1c55629f5b672366c5be40344aa5 (patch) | |
tree | 0b974d69a2046854d2edb01bff5f7a0429969bf2 /spec | |
parent | 385d7ee6af36be869f681b368bd9c607b45cc4cd (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
13 files changed, 900 insertions, 434 deletions
diff --git a/spec/features/merge_request/user_uses_quick_actions_spec.rb b/spec/features/merge_request/user_uses_quick_actions_spec.rb index 04a2e046f42..b48659353ec 100644 --- a/spec/features/merge_request/user_uses_quick_actions_spec.rb +++ b/spec/features/merge_request/user_uses_quick_actions_spec.rb @@ -41,5 +41,6 @@ RSpec.describe 'Merge request > User uses quick actions', :js do end it_behaves_like 'merge quick action' + it_behaves_like 'rebase quick action' end end diff --git a/spec/finders/concerns/packages/finder_helper_spec.rb b/spec/finders/concerns/packages/finder_helper_spec.rb new file mode 100644 index 00000000000..73f77647573 --- /dev/null +++ b/spec/finders/concerns/packages/finder_helper_spec.rb @@ -0,0 +1,161 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ::Packages::FinderHelper do + describe '#packages_visible_to_user' do + using RSpec::Parameterized::TableSyntax + + let_it_be(:user) { create(:user) } + let_it_be_with_reload(:group) { create(:group) } + let_it_be_with_reload(:project1) { create(:project, namespace: group) } + let_it_be(:package1) { create(:package, project: project1) } + let_it_be_with_reload(:subgroup) { create(:group, parent: group) } + let_it_be_with_reload(:project2) { create(:project, namespace: subgroup) } + let_it_be(:package2) { create(:package, project: project2) } + + let(:finder_class) do + Class.new do + include ::Packages::FinderHelper + + def initialize(user) + @current_user = user + end + + def execute(group) + packages_visible_to_user(@current_user, within_group: group) + end + end + end + + let(:finder) { finder_class.new(user) } + + subject { finder.execute(group) } + + shared_examples 'returning both packages' do + it { is_expected.to contain_exactly(package1, package2) } + end + + shared_examples 'returning package1' do + it { is_expected.to eq [package1]} + end + + shared_examples 'returning no packages' do + it { is_expected.to be_empty } + end + + where(:group_visibility, :subgroup_visibility, :project2_visibility, :user_role, :shared_example_name) do + 'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :maintainer | 'returning both packages' + 'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :developer | 'returning both packages' + 'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :guest | 'returning both packages' + 'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :anonymous | 'returning both packages' + 'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :maintainer | 'returning both packages' + 'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :developer | 'returning both packages' + 'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :guest | 'returning package1' + 'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :anonymous | 'returning package1' + 'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both packages' + 'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both packages' + 'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning package1' + 'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning package1' + 'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both packages' + 'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both packages' + 'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning no packages' + 'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning no packages' + end + + with_them do + before do + unless user_role == :anonymous + group.send("add_#{user_role}", user) + subgroup.send("add_#{user_role}", user) + project1.send("add_#{user_role}", user) + project2.send("add_#{user_role}", user) + end + + project2.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project2_visibility, false)) + subgroup.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false)) + project1.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false)) + group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false)) + end + + it_behaves_like params[:shared_example_name] + end + end + + describe '#projects_visible_to_user' do + using RSpec::Parameterized::TableSyntax + + let_it_be(:user) { create(:user) } + let_it_be_with_reload(:group) { create(:group) } + let_it_be_with_reload(:project1) { create(:project, namespace: group) } + let_it_be_with_reload(:subgroup) { create(:group, parent: group) } + let_it_be_with_reload(:project2) { create(:project, namespace: subgroup) } + + let(:finder_class) do + Class.new do + include ::Packages::FinderHelper + + def initialize(user) + @current_user = user + end + + def execute(group) + projects_visible_to_user(@current_user, within_group: group) + end + end + end + + let(:finder) { finder_class.new(user) } + + subject { finder.execute(group) } + + shared_examples 'returning both projects' do + it { is_expected.to contain_exactly(project1, project2) } + end + + shared_examples 'returning project1' do + it { is_expected.to eq [project1]} + end + + shared_examples 'returning no project' do + it { is_expected.to be_empty } + end + + where(:group_visibility, :subgroup_visibility, :project2_visibility, :user_role, :shared_example_name) do + 'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :maintainer | 'returning both projects' + 'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :developer | 'returning both projects' + 'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :guest | 'returning both projects' + 'PUBLIC' | 'PUBLIC' | 'PUBLIC' | :anonymous | 'returning both projects' + 'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :maintainer | 'returning both projects' + 'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :developer | 'returning both projects' + 'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :guest | 'returning project1' + 'PUBLIC' | 'PUBLIC' | 'PRIVATE' | :anonymous | 'returning project1' + 'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both projects' + 'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both projects' + 'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning project1' + 'PUBLIC' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning project1' + 'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :maintainer | 'returning both projects' + 'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :developer | 'returning both projects' + 'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :guest | 'returning no project' + 'PRIVATE' | 'PRIVATE' | 'PRIVATE' | :anonymous | 'returning no project' + end + + with_them do + before do + unless user_role == :anonymous + group.send("add_#{user_role}", user) + subgroup.send("add_#{user_role}", user) + project1.send("add_#{user_role}", user) + project2.send("add_#{user_role}", user) + end + + project2.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project2_visibility, false)) + subgroup.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false)) + project1.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false)) + group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false)) + end + + it_behaves_like params[:shared_example_name] + end + end +end diff --git a/spec/finders/packages/nuget/package_finder_spec.rb b/spec/finders/packages/nuget/package_finder_spec.rb index 9295d0c7a2f..10b5f6c8ec2 100644 --- a/spec/finders/packages/nuget/package_finder_spec.rb +++ b/spec/finders/packages/nuget/package_finder_spec.rb @@ -2,74 +2,117 @@ require 'spec_helper' RSpec.describe Packages::Nuget::PackageFinder do - let_it_be(:package1) { create(:nuget_package) } - let_it_be(:project) { package1.project } + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:subgroup) { create(:group, parent: group) } + let_it_be(:project) { create(:project, namespace: subgroup) } + let_it_be(:package1) { create(:nuget_package, project: project) } let_it_be(:package2) { create(:nuget_package, name: package1.name, version: '2.0.0', project: project) } let_it_be(:package3) { create(:nuget_package, name: 'Another.Dummy.Package', project: project) } + let_it_be(:other_package_1) { create(:nuget_package, name: package1.name, version: package1.version) } + let_it_be(:other_package_2) { create(:nuget_package, name: package1.name, version: package2.version) } let(:package_name) { package1.name } let(:package_version) { nil } let(:limit) { 50 } describe '#execute!' do - subject { described_class.new(project, package_name: package_name, package_version: package_version, limit: limit).execute } + subject { described_class.new(user, target, package_name: package_name, package_version: package_version, limit: limit).execute } - it { is_expected.to match_array([package1, package2]) } + shared_examples 'handling all the conditions' do + it { is_expected.to match_array([package1, package2]) } - context 'with lower case package name' do - let(:package_name) { package1.name.downcase } + context 'with lower case package name' do + let(:package_name) { package1.name.downcase } - it { is_expected.to match_array([package1, package2]) } - end + it { is_expected.to match_array([package1, package2]) } + end - context 'with unknown package name' do - let(:package_name) { 'foobar' } + context 'with unknown package name' do + let(:package_name) { 'foobar' } - it { is_expected.to be_empty } - end + it { is_expected.to be_empty } + end - context 'with valid version' do - let(:package_version) { '2.0.0' } + context 'with valid version' do + let(:package_version) { '2.0.0' } - it { is_expected.to match_array([package2]) } - end + it { is_expected.to match_array([package2]) } + end - context 'with unknown version' do - let(:package_version) { 'foobar' } + context 'with unknown version' do + let(:package_version) { 'foobar' } - it { is_expected.to be_empty } - end + it { is_expected.to be_empty } + end + + context 'with limit hit' do + let_it_be(:package4) { create(:nuget_package, name: package1.name, project: project) } + let_it_be(:package5) { create(:nuget_package, name: package1.name, project: project) } + let_it_be(:package6) { create(:nuget_package, name: package1.name, project: project) } + let(:limit) { 2 } + + it { is_expected.to match_array([package5, package6]) } + end + + context 'with downcase package name' do + let(:package_name) { package1.name.downcase } + + it { is_expected.to match_array([package1, package2]) } + end - context 'with limit hit' do - let_it_be(:package4) { create(:nuget_package, name: package1.name, project: project) } - let_it_be(:package5) { create(:nuget_package, name: package1.name, project: project) } - let_it_be(:package6) { create(:nuget_package, name: package1.name, project: project) } - let(:limit) { 2 } + context 'with prefix wildcard' do + let(:package_name) { "%#{package1.name[3..-1]}" } - it { is_expected.to match_array([package5, package6]) } + it { is_expected.to match_array([package1, package2]) } + end + + context 'with suffix wildcard' do + let(:package_name) { "#{package1.name[0..-3]}%" } + + it { is_expected.to match_array([package1, package2]) } + end + + context 'with surrounding wildcards' do + let(:package_name) { "%#{package1.name[3..-3]}%" } + + it { is_expected.to match_array([package1, package2]) } + end end - context 'with downcase package name' do - let(:package_name) { package1.name.downcase } + context 'with a project' do + let(:target) { project } - it { is_expected.to match_array([package1, package2]) } + before do + project.add_developer(user) + end + + it_behaves_like 'handling all the conditions' end - context 'with prefix wildcard' do - let(:package_name) { "%#{package1.name[3..-1]}" } + context 'with a subgroup' do + let(:target) { subgroup } - it { is_expected.to match_array([package1, package2]) } + before do + subgroup.add_developer(user) + end + + it_behaves_like 'handling all the conditions' end - context 'with suffix wildcard' do - let(:package_name) { "#{package1.name[0..-3]}%" } + context 'with a group' do + let(:target) { group } - it { is_expected.to match_array([package1, package2]) } + before do + group.add_developer(user) + end + + it_behaves_like 'handling all the conditions' end - context 'with surrounding wildcards' do - let(:package_name) { "%#{package1.name[3..-3]}%" } + context 'with nil' do + let(:target) { nil } - it { is_expected.to match_array([package1, package2]) } + it { is_expected.to be_empty } end end end diff --git a/spec/presenters/packages/nuget/service_index_presenter_spec.rb b/spec/presenters/packages/nuget/service_index_presenter_spec.rb index 19ef890e19f..9c95fbc8fd2 100644 --- a/spec/presenters/packages/nuget/service_index_presenter_spec.rb +++ b/spec/presenters/packages/nuget/service_index_presenter_spec.rb @@ -4,25 +4,64 @@ require 'spec_helper' RSpec.describe ::Packages::Nuget::ServiceIndexPresenter do let_it_be(:project) { create(:project) } - let_it_be(:presenter) { described_class.new(project) } + let_it_be(:group) { create(:group) } + + let(:presenter) { described_class.new(target) } describe '#version' do subject { presenter.version } - it { is_expected.to eq '3.0.0' } + context 'for a group' do + let(:target) { group } + + it { is_expected.to eq '3.0.0' } + end + + context 'for a project' do + let(:target) { project } + + it { is_expected.to eq '3.0.0' } + end end describe '#resources' do subject { presenter.resources } - it 'has valid resources' do - expect(subject.size).to eq 8 - subject.each do |resource| - %i[@id @type comment].each do |field| - expect(resource).to have_key(field) - expect(resource[field]).to be_a(String) + shared_examples 'returning valid resources' do |resources_count: 8, include_publish_service: true| + it 'has valid resources' do + expect(subject.size).to eq resources_count + subject.each do |resource| + %i[@id @type comment].each do |field| + expect(resource).to have_key(field) + expect(resource[field]).to be_a(String) + end + end + end + + it "does #{'not ' unless include_publish_service}return the publish resource" do + services_types = subject.map { |res| res[:@type] } + + described_class::SERVICE_VERSIONS[:publish].each do |publish_service_version| + if include_publish_service + expect(services_types).to include(publish_service_version) + else + expect(services_types).not_to include(publish_service_version) + end end end end + + context 'for a group' do + let(:target) { group } + + # at the group level we don't have the publish and download service + it_behaves_like 'returning valid resources', resources_count: 6, include_publish_service: false + end + + context 'for a project' do + let(:target) { project } + + it_behaves_like 'returning valid resources' + end end end diff --git a/spec/requests/api/nuget_group_packages_spec.rb b/spec/requests/api/nuget_group_packages_spec.rb new file mode 100644 index 00000000000..aeda51ad315 --- /dev/null +++ b/spec/requests/api/nuget_group_packages_spec.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true +require 'spec_helper' + +RSpec.describe API::NugetGroupPackages do + include_context 'nuget api setup' + + using RSpec::Parameterized::TableSyntax + + let_it_be_with_reload(:group) { create(:group) } + let_it_be_with_reload(:subgroup) { create(:group, parent: group) } + let_it_be_with_reload(:project) { create(:project, namespace: subgroup) } + let_it_be(:deploy_token) { create(:deploy_token, :group, read_package_registry: true, write_package_registry: true) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: deploy_token, group: group) } + + let(:target_type) { 'groups' } + + shared_examples 'handling all endpoints' do + describe 'GET /api/v4/groups/:id/packages/nuget' do + it_behaves_like 'handling nuget service requests', anonymous_requests_example_name: 'rejects nuget packages access', anonymous_requests_status: :unauthorized do + let(:url) { "/groups/#{target.id}/packages/nuget/index.json" } + end + end + + describe 'GET /api/v4/groups/:id/packages/nuget/metadata/*package_name/index' do + it_behaves_like 'handling nuget metadata requests with package name', anonymous_requests_example_name: 'rejects nuget packages access', anonymous_requests_status: :unauthorized do + let(:url) { "/groups/#{target.id}/packages/nuget/metadata/#{package_name}/index.json" } + end + end + + describe 'GET /api/v4/groups/:id/packages/nuget/metadata/*package_name/*package_version' do + it_behaves_like 'handling nuget metadata requests with package name and package version', anonymous_requests_example_name: 'rejects nuget packages access', anonymous_requests_status: :unauthorized do + let(:url) { "/groups/#{target.id}/packages/nuget/metadata/#{package_name}/#{package.version}.json" } + end + end + + describe 'GET /api/v4/groups/:id/packages/nuget/query' do + it_behaves_like 'handling nuget search requests', anonymous_requests_example_name: 'rejects nuget packages access', anonymous_requests_status: :unauthorized do + let(:url) { "/groups/#{target.id}/packages/nuget/query?#{query_parameters.to_query}" } + end + end + end + + context 'with a subgroup' do + # Bug: deploy tokens at parent group will not see the subgroup. + # https://gitlab.com/gitlab-org/gitlab/-/issues/285495 + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: deploy_token, group: subgroup) } + + let(:target) { subgroup } + + it_behaves_like 'handling all endpoints' + + def update_visibility_to(visibility) + project.update!(visibility_level: visibility) + subgroup.update!(visibility_level: visibility) + end + end + + context 'a group' do + let(:target) { group } + + it_behaves_like 'handling all endpoints' + + context 'with dummy packages and anonymous request' do + let_it_be(:package_name) { 'Dummy.Package' } + let_it_be(:packages) { create_list(:nuget_package, 5, :with_metadatum, name: package_name, project: project) } + let_it_be(:tags) { packages.each { |pkg| create(:packages_tag, package: pkg, name: 'test') } } + + let(:search_term) { 'umm' } + let(:take) { 26 } + let(:skip) { 0 } + let(:include_prereleases) { true } + let(:query_parameters) { { q: search_term, take: take, skip: skip, prerelease: include_prereleases } } + + subject { get api(url), headers: {}} + + shared_examples 'handling mixed visibilities' do + where(:group_visibility, :subgroup_visibility, :expected_status) do + 'PUBLIC' | 'PUBLIC' | :unauthorized + 'PUBLIC' | 'INTERNAL' | :unauthorized + 'PUBLIC' | 'PRIVATE' | :unauthorized + 'INTERNAL' | 'INTERNAL' | :unauthorized + 'INTERNAL' | 'PRIVATE' | :unauthorized + 'PRIVATE' | 'PRIVATE' | :unauthorized + end + + with_them do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false)) + subgroup.update!(visibility_level: Gitlab::VisibilityLevel.const_get(subgroup_visibility, false)) + group.update!(visibility_level: Gitlab::VisibilityLevel.const_get(group_visibility, false)) + end + + it_behaves_like 'returning response status', params[:expected_status] + end + end + + describe 'GET /api/v4/groups/:id/packages/nuget/metadata/*package_name/index' do + it_behaves_like 'handling mixed visibilities' do + let(:url) { "/groups/#{target.id}/packages/nuget/metadata/#{package_name}/index.json" } + end + end + + describe 'GET /api/v4/groups/:id/packages/nuget/metadata/*package_name/*package_version' do + it_behaves_like 'handling mixed visibilities' do + let(:url) { "/groups/#{target.id}/packages/nuget/metadata/#{package_name}/#{packages.first.version}.json" } + end + end + + describe 'GET /api/v4/groups/:id/packages/nuget/query' do + it_behaves_like 'handling mixed visibilities' do + let(:url) { "/groups/#{target.id}/packages/nuget/query?#{query_parameters.to_query}" } + end + end + end + + def update_visibility_to(visibility) + project.update!(visibility_level: visibility) + subgroup.update!(visibility_level: visibility) + group.update!(visibility_level: visibility) + end + end +end diff --git a/spec/requests/api/nuget_project_packages_spec.rb b/spec/requests/api/nuget_project_packages_spec.rb index df1daf39144..c64ac6f3a94 100644 --- a/spec/requests/api/nuget_project_packages_spec.rb +++ b/spec/requests/api/nuget_project_packages_spec.rb @@ -2,99 +2,202 @@ require 'spec_helper' RSpec.describe API::NugetProjectPackages do - include WorkhorseHelpers - include PackagesManagerApiSpecHelpers - include HttpBasicAuthHelpers + include_context 'nuget api setup' - let_it_be(:user) { create(:user) } - let_it_be(:project, reload: true) { create(:project, :public) } - let_it_be(:personal_access_token) { create(:personal_access_token, user: user) } + using RSpec::Parameterized::TableSyntax + + let_it_be_with_reload(:project) { create(:project, :public) } let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) } let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) } + let(:target) { project } + let(:target_type) { 'projects' } + describe 'GET /api/v4/projects/:id/packages/nuget' do it_behaves_like 'handling nuget service requests' do - let(:url) { "/projects/#{project.id}/packages/nuget/index.json" } + let(:url) { "/projects/#{target.id}/packages/nuget/index.json" } end end describe 'GET /api/v4/projects/:id/packages/nuget/metadata/*package_name/index' do it_behaves_like 'handling nuget metadata requests with package name' do - let(:url) { "/projects/#{project.id}/packages/nuget/metadata/#{package_name}/index.json" } + let(:url) { "/projects/#{target.id}/packages/nuget/metadata/#{package_name}/index.json" } end end describe 'GET /api/v4/projects/:id/packages/nuget/metadata/*package_name/*package_version' do it_behaves_like 'handling nuget metadata requests with package name and package version' do - let(:url) { "/projects/#{project.id}/packages/nuget/metadata/#{package_name}/#{package.version}.json" } + let(:url) { "/projects/#{target.id}/packages/nuget/metadata/#{package_name}/#{package.version}.json" } end end describe 'GET /api/v4/projects/:id/packages/nuget/query' do it_behaves_like 'handling nuget search requests' do - let(:url) { "/projects/#{project.id}/packages/nuget/query?#{query_parameters.to_query}" } + let(:url) { "/projects/#{target.id}/packages/nuget/query?#{query_parameters.to_query}" } end end + describe 'GET /api/v4/projects/:id/packages/nuget/download/*package_name/index' do + let_it_be(:package_name) { 'Dummy.Package' } + let_it_be(:packages) { create_list(:nuget_package, 5, name: package_name, project: project) } + + let(:url) { "/projects/#{target.id}/packages/nuget/download/#{package_name}/index.json" } + + subject { get api(url) } + + context 'with valid target' do + where(:visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + 'PUBLIC' | :developer | true | true | 'process nuget download versions request' | :success + 'PUBLIC' | :guest | true | true | 'process nuget download versions request' | :success + 'PUBLIC' | :developer | true | false | 'process nuget download versions request' | :success + 'PUBLIC' | :guest | true | false | 'process nuget download versions request' | :success + 'PUBLIC' | :developer | false | true | 'process nuget download versions request' | :success + 'PUBLIC' | :guest | false | true | 'process nuget download versions request' | :success + 'PUBLIC' | :developer | false | false | 'process nuget download versions request' | :success + 'PUBLIC' | :guest | false | false | 'process nuget download versions request' | :success + 'PUBLIC' | :anonymous | false | true | 'process nuget download versions request' | :success + 'PRIVATE' | :developer | true | true | 'process nuget download versions request' | :success + 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden + 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :guest | true | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :developer | false | true | 'rejects nuget packages access' | :not_found + 'PRIVATE' | :guest | false | true | 'rejects nuget packages access' | :not_found + 'PRIVATE' | :developer | false | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :guest | false | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized + end + + with_them do + let(:token) { user_token ? personal_access_token.token : 'wrong' } + let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) } + + subject { get api(url), headers: headers } + + before do + update_visibility_to(Gitlab::VisibilityLevel.const_get(visibility_level, false)) + end + + it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] + end + end + + it_behaves_like 'deploy token for package GET requests' + + it_behaves_like 'rejects nuget access with unknown target id' + + it_behaves_like 'rejects nuget access with invalid target id' + end + + describe 'GET /api/v4/projects/:id/packages/nuget/download/*package_name/*package_version/*package_filename' do + let_it_be(:package_name) { 'Dummy.Package' } + let_it_be(:package) { create(:nuget_package, project: project, name: package_name) } + + let(:url) { "/projects/#{target.id}/packages/nuget/download/#{package.name}/#{package.version}/#{package.name}.#{package.version}.nupkg" } + + subject { get api(url) } + + context 'with valid target' do + where(:visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + 'PUBLIC' | :developer | true | true | 'process nuget download content request' | :success + 'PUBLIC' | :guest | true | true | 'process nuget download content request' | :success + 'PUBLIC' | :developer | true | false | 'process nuget download content request' | :success + 'PUBLIC' | :guest | true | false | 'process nuget download content request' | :success + 'PUBLIC' | :developer | false | true | 'process nuget download content request' | :success + 'PUBLIC' | :guest | false | true | 'process nuget download content request' | :success + 'PUBLIC' | :developer | false | false | 'process nuget download content request' | :success + 'PUBLIC' | :guest | false | false | 'process nuget download content request' | :success + 'PUBLIC' | :anonymous | false | true | 'process nuget download content request' | :success + 'PRIVATE' | :developer | true | true | 'process nuget download content request' | :success + 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden + 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :guest | true | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :developer | false | true | 'rejects nuget packages access' | :not_found + 'PRIVATE' | :guest | false | true | 'rejects nuget packages access' | :not_found + 'PRIVATE' | :developer | false | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :guest | false | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized + end + + with_them do + let(:token) { user_token ? personal_access_token.token : 'wrong' } + let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) } + + subject { get api(url), headers: headers } + + before do + update_visibility_to(Gitlab::VisibilityLevel.const_get(visibility_level, false)) + end + + it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] + end + end + + it_behaves_like 'deploy token for package GET requests' do + before do + update_visibility_to(Gitlab::VisibilityLevel::PRIVATE) + end + end + + it_behaves_like 'rejects nuget access with unknown target id' + + it_behaves_like 'rejects nuget access with invalid target id' + end + describe 'PUT /api/v4/projects/:id/packages/nuget/authorize' do let_it_be(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') } let_it_be(:workhorse_header) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => workhorse_token } } - let(:url) { "/projects/#{project.id}/packages/nuget/authorize" } + let(:url) { "/projects/#{target.id}/packages/nuget/authorize" } let(:headers) { {} } subject { put api(url), headers: headers } - context 'without the need for a license' do - context 'with valid project' do - using RSpec::Parameterized::TableSyntax - - where(:project_visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do - 'PUBLIC' | :developer | true | true | 'process nuget workhorse authorization' | :success - 'PUBLIC' | :guest | true | true | 'rejects nuget packages access' | :forbidden - 'PUBLIC' | :developer | true | false | 'rejects nuget packages access' | :unauthorized - 'PUBLIC' | :guest | true | false | 'rejects nuget packages access' | :unauthorized - 'PUBLIC' | :developer | false | true | 'rejects nuget packages access' | :forbidden - 'PUBLIC' | :guest | false | true | 'rejects nuget packages access' | :forbidden - 'PUBLIC' | :developer | false | false | 'rejects nuget packages access' | :unauthorized - 'PUBLIC' | :guest | false | false | 'rejects nuget packages access' | :unauthorized - 'PUBLIC' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :developer | true | true | 'process nuget workhorse authorization' | :success - 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden - 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :guest | true | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :developer | false | true | 'rejects nuget packages access' | :not_found - 'PRIVATE' | :guest | false | true | 'rejects nuget packages access' | :not_found - 'PRIVATE' | :developer | false | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :guest | false | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized - end - - with_them do - let(:token) { user_token ? personal_access_token.token : 'wrong' } - let(:user_headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) } - let(:headers) { user_headers.merge(workhorse_header) } + context 'with valid project' do + where(:visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + 'PUBLIC' | :developer | true | true | 'process nuget workhorse authorization' | :success + 'PUBLIC' | :guest | true | true | 'rejects nuget packages access' | :forbidden + 'PUBLIC' | :developer | true | false | 'rejects nuget packages access' | :unauthorized + 'PUBLIC' | :guest | true | false | 'rejects nuget packages access' | :unauthorized + 'PUBLIC' | :developer | false | true | 'rejects nuget packages access' | :forbidden + 'PUBLIC' | :guest | false | true | 'rejects nuget packages access' | :forbidden + 'PUBLIC' | :developer | false | false | 'rejects nuget packages access' | :unauthorized + 'PUBLIC' | :guest | false | false | 'rejects nuget packages access' | :unauthorized + 'PUBLIC' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :developer | true | true | 'process nuget workhorse authorization' | :success + 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden + 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :guest | true | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :developer | false | true | 'rejects nuget packages access' | :not_found + 'PRIVATE' | :guest | false | true | 'rejects nuget packages access' | :not_found + 'PRIVATE' | :developer | false | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :guest | false | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized + end - before do - project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility_level, false)) - end + with_them do + let(:token) { user_token ? personal_access_token.token : 'wrong' } + let(:user_headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) } + let(:headers) { user_headers.merge(workhorse_header) } - it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] + before do + update_visibility_to(Gitlab::VisibilityLevel.const_get(visibility_level, false)) end + + it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] end + end - it_behaves_like 'deploy token for package uploads' + it_behaves_like 'deploy token for package uploads' - it_behaves_like 'rejects nuget access with unknown project id' + it_behaves_like 'rejects nuget access with unknown target id' - it_behaves_like 'rejects nuget access with invalid project id' - end + it_behaves_like 'rejects nuget access with invalid target id' end describe 'PUT /api/v4/projects/:id/packages/nuget' do let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') } let(:workhorse_header) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => workhorse_token } } let_it_be(:file_name) { 'package.nupkg' } - let(:url) { "/projects/#{project.id}/packages/nuget" } + let(:url) { "/projects/#{target.id}/packages/nuget" } let(:headers) { {} } let(:params) { { package: temp_file(file_name) } } let(:file_key) { :package } @@ -111,170 +214,61 @@ RSpec.describe API::NugetProjectPackages do ) end - context 'without the need for a license' do - context 'with valid project' do - using RSpec::Parameterized::TableSyntax - - where(:project_visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do - 'PUBLIC' | :developer | true | true | 'process nuget upload' | :created - 'PUBLIC' | :guest | true | true | 'rejects nuget packages access' | :forbidden - 'PUBLIC' | :developer | true | false | 'rejects nuget packages access' | :unauthorized - 'PUBLIC' | :guest | true | false | 'rejects nuget packages access' | :unauthorized - 'PUBLIC' | :developer | false | true | 'rejects nuget packages access' | :forbidden - 'PUBLIC' | :guest | false | true | 'rejects nuget packages access' | :forbidden - 'PUBLIC' | :developer | false | false | 'rejects nuget packages access' | :unauthorized - 'PUBLIC' | :guest | false | false | 'rejects nuget packages access' | :unauthorized - 'PUBLIC' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :developer | true | true | 'process nuget upload' | :created - 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden - 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :guest | true | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :developer | false | true | 'rejects nuget packages access' | :not_found - 'PRIVATE' | :guest | false | true | 'rejects nuget packages access' | :not_found - 'PRIVATE' | :developer | false | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :guest | false | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized - end - - with_them do - let(:token) { user_token ? personal_access_token.token : 'wrong' } - let(:user_headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) } - let(:headers) { user_headers.merge(workhorse_header) } - - before do - project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility_level, false)) - end - - it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] - end + context 'with valid project' do + where(:visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + 'PUBLIC' | :developer | true | true | 'process nuget upload' | :created + 'PUBLIC' | :guest | true | true | 'rejects nuget packages access' | :forbidden + 'PUBLIC' | :developer | true | false | 'rejects nuget packages access' | :unauthorized + 'PUBLIC' | :guest | true | false | 'rejects nuget packages access' | :unauthorized + 'PUBLIC' | :developer | false | true | 'rejects nuget packages access' | :forbidden + 'PUBLIC' | :guest | false | true | 'rejects nuget packages access' | :forbidden + 'PUBLIC' | :developer | false | false | 'rejects nuget packages access' | :unauthorized + 'PUBLIC' | :guest | false | false | 'rejects nuget packages access' | :unauthorized + 'PUBLIC' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :developer | true | true | 'process nuget upload' | :created + 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden + 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :guest | true | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :developer | false | true | 'rejects nuget packages access' | :not_found + 'PRIVATE' | :guest | false | true | 'rejects nuget packages access' | :not_found + 'PRIVATE' | :developer | false | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :guest | false | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized end - it_behaves_like 'deploy token for package uploads' - - it_behaves_like 'rejects nuget access with unknown project id' - - it_behaves_like 'rejects nuget access with invalid project id' - - context 'file size above maximum limit' do - let(:headers) { basic_auth_header(deploy_token.username, deploy_token.token).merge(workhorse_header) } + with_them do + let(:token) { user_token ? personal_access_token.token : 'wrong' } + let(:user_headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) } + let(:headers) { user_headers.merge(workhorse_header) } before do - allow_next_instance_of(UploadedFile) do |uploaded_file| - allow(uploaded_file).to receive(:size).and_return(project.actual_limits.nuget_max_file_size + 1) - end + update_visibility_to(Gitlab::VisibilityLevel.const_get(visibility_level, false)) end - it_behaves_like 'returning response status', :bad_request + it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] end end - end - - describe 'GET /api/v4/projects/:id/packages/nuget/download/*package_name/index' do - let_it_be(:package_name) { 'Dummy.Package' } - let_it_be(:packages) { create_list(:nuget_package, 5, name: package_name, project: project) } - let(:url) { "/projects/#{project.id}/packages/nuget/download/#{package_name}/index.json" } - - subject { get api(url) } - context 'without the need for a license' do - context 'with valid project' do - using RSpec::Parameterized::TableSyntax - - where(:project_visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do - 'PUBLIC' | :developer | true | true | 'process nuget download versions request' | :success - 'PUBLIC' | :guest | true | true | 'process nuget download versions request' | :success - 'PUBLIC' | :developer | true | false | 'process nuget download versions request' | :success - 'PUBLIC' | :guest | true | false | 'process nuget download versions request' | :success - 'PUBLIC' | :developer | false | true | 'process nuget download versions request' | :success - 'PUBLIC' | :guest | false | true | 'process nuget download versions request' | :success - 'PUBLIC' | :developer | false | false | 'process nuget download versions request' | :success - 'PUBLIC' | :guest | false | false | 'process nuget download versions request' | :success - 'PUBLIC' | :anonymous | false | true | 'process nuget download versions request' | :success - 'PRIVATE' | :developer | true | true | 'process nuget download versions request' | :success - 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden - 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :guest | true | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :developer | false | true | 'rejects nuget packages access' | :not_found - 'PRIVATE' | :guest | false | true | 'rejects nuget packages access' | :not_found - 'PRIVATE' | :developer | false | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :guest | false | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized - end + it_behaves_like 'deploy token for package uploads' - with_them do - let(:token) { user_token ? personal_access_token.token : 'wrong' } - let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) } + it_behaves_like 'rejects nuget access with unknown target id' - subject { get api(url), headers: headers } + it_behaves_like 'rejects nuget access with invalid target id' - before do - project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility_level, false)) - end + context 'file size above maximum limit' do + let(:headers) { basic_auth_header(deploy_token.username, deploy_token.token).merge(workhorse_header) } - it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] + before do + allow_next_instance_of(UploadedFile) do |uploaded_file| + allow(uploaded_file).to receive(:size).and_return(project.actual_limits.nuget_max_file_size + 1) end end - it_behaves_like 'deploy token for package GET requests' - - it_behaves_like 'rejects nuget access with unknown project id' - - it_behaves_like 'rejects nuget access with invalid project id' + it_behaves_like 'returning response status', :bad_request end end - describe 'GET /api/v4/projects/:id/packages/nuget/download/*package_name/*package_version/*package_filename' do - let_it_be(:package_name) { 'Dummy.Package' } - let_it_be(:package) { create(:nuget_package, project: project, name: package_name) } - - let(:url) { "/projects/#{project.id}/packages/nuget/download/#{package.name}/#{package.version}/#{package.name}.#{package.version}.nupkg" } - - subject { get api(url) } - - context 'without the need for a license' do - context 'with valid project' do - using RSpec::Parameterized::TableSyntax - - where(:project_visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do - 'PUBLIC' | :developer | true | true | 'process nuget download content request' | :success - 'PUBLIC' | :guest | true | true | 'process nuget download content request' | :success - 'PUBLIC' | :developer | true | false | 'process nuget download content request' | :success - 'PUBLIC' | :guest | true | false | 'process nuget download content request' | :success - 'PUBLIC' | :developer | false | true | 'process nuget download content request' | :success - 'PUBLIC' | :guest | false | true | 'process nuget download content request' | :success - 'PUBLIC' | :developer | false | false | 'process nuget download content request' | :success - 'PUBLIC' | :guest | false | false | 'process nuget download content request' | :success - 'PUBLIC' | :anonymous | false | true | 'process nuget download content request' | :success - 'PRIVATE' | :developer | true | true | 'process nuget download content request' | :success - 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden - 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :guest | true | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :developer | false | true | 'rejects nuget packages access' | :not_found - 'PRIVATE' | :guest | false | true | 'rejects nuget packages access' | :not_found - 'PRIVATE' | :developer | false | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :guest | false | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized - end - - with_them do - let(:token) { user_token ? personal_access_token.token : 'wrong' } - let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) } - - subject { get api(url), headers: headers } - - before do - project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility_level, false)) - end - - it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] - end - end - - it_behaves_like 'deploy token for package GET requests' - - it_behaves_like 'rejects nuget access with unknown project id' - - it_behaves_like 'rejects nuget access with invalid project id' - end + def update_visibility_to(visibility) + project.update!(visibility_level: visibility) end end diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index c13010b8b47..136a30387b4 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -76,7 +76,7 @@ RSpec.describe UsersController do end end - context 'json with events' do + context 'requested in json format' do let(:project) { create(:project) } before do @@ -86,31 +86,13 @@ RSpec.describe UsersController do sign_in(user) end - it 'loads events' do + it 'returns 404 with deprecation message' do # Requesting "/username?format=json" instead of "/username.json" get user_url user.username, params: { format: :json } + expect(response).to have_gitlab_http_status(:not_found) expect(response.media_type).to eq('application/json') - expect(Gitlab::Json.parse(response.body)['count']).to eq(1) - end - - it 'hides events if the user cannot read cross project' do - allow(Ability).to receive(:allowed?).and_call_original - expect(Ability).to receive(:allowed?).with(user, :read_cross_project) { false } - - get user_url user.username, params: { format: :json } - - expect(response.media_type).to eq('application/json') - expect(Gitlab::Json.parse(response.body)['count']).to eq(0) - end - - it 'hides events if the user has a private profile' do - Gitlab::DataBuilder::Push.build_sample(project, private_user) - - get user_url private_user.username, params: { format: :json } - - expect(response.media_type).to eq('application/json') - expect(Gitlab::Json.parse(response.body)['count']).to eq(0) + expect(Gitlab::Json.parse(response.body)['message']).to include('This endpoint is deprecated.') end end end @@ -183,7 +165,7 @@ RSpec.describe UsersController do end end - context 'json with events' do + context 'requested in json format' do let(:project) { create(:project) } before do diff --git a/spec/services/members/create_service_spec.rb b/spec/services/members/create_service_spec.rb index e8a4a798b20..7fd6b3e5b8d 100644 --- a/spec/services/members/create_service_spec.rb +++ b/spec/services/members/create_service_spec.rb @@ -2,26 +2,35 @@ require 'spec_helper' -RSpec.describe Members::CreateService do - let_it_be(:project) { create(:project) } +RSpec.describe Members::CreateService, :clean_gitlab_redis_shared_state, :sidekiq_inline do + let_it_be(:source) { create(:project) } let_it_be(:user) { create(:user) } - let_it_be(:project_user) { create(:user) } - let_it_be(:user_ids) { project_user.id.to_s } + let_it_be(:member) { create(:user) } + let_it_be(:user_ids) { member.id.to_s } let_it_be(:access_level) { Gitlab::Access::GUEST } let(:params) { { user_ids: user_ids, access_level: access_level } } - subject(:execute_service) { described_class.new(user, params).execute(project) } + subject(:execute_service) { described_class.new(user, params).execute(source) } before do - project.add_maintainer(user) - allow(Namespaces::OnboardingUserAddedWorker).to receive(:idempotent?).and_return(false) + source.is_a?(Project) ? source.add_maintainer(user) : source.add_owner(user) end context 'when passing valid parameters' do it 'adds a user to members' do expect(execute_service[:status]).to eq(:success) - expect(project.users).to include project_user - expect(Namespaces::OnboardingUserAddedWorker.jobs.last['args'][0]).to eq(project.id) + expect(source.users).to include member + expect(NamespaceOnboardingAction.completed?(source.namespace, :user_added)).to be(true) + end + + context 'when executing on a group' do + let_it_be(:source) { create(:group) } + + it 'adds a user to members' do + expect(execute_service[:status]).to eq(:success) + expect(source.users).to include member + expect(NamespaceOnboardingAction.completed?(source, :user_added)).to be(true) + end end end @@ -31,8 +40,8 @@ RSpec.describe Members::CreateService do it 'does not add a member' do expect(execute_service[:status]).to eq(:error) expect(execute_service[:message]).to be_present - expect(project.users).not_to include project_user - expect(Namespaces::OnboardingUserAddedWorker.jobs.size).to eq(0) + expect(source.users).not_to include member + expect(NamespaceOnboardingAction.completed?(source.namespace, :user_added)).to be(false) end end @@ -42,8 +51,8 @@ RSpec.describe Members::CreateService do it 'limits the number of users to 100' do expect(execute_service[:status]).to eq(:error) expect(execute_service[:message]).to be_present - expect(project.users).not_to include project_user - expect(Namespaces::OnboardingUserAddedWorker.jobs.size).to eq(0) + expect(source.users).not_to include member + expect(NamespaceOnboardingAction.completed?(source.namespace, :user_added)).to be(false) end end @@ -52,19 +61,19 @@ RSpec.describe Members::CreateService do it 'does not add a member' do expect(execute_service[:status]).to eq(:error) - expect(execute_service[:message]).to include("#{project_user.username}: Access level is not included in the list") - expect(project.users).not_to include project_user - expect(Namespaces::OnboardingUserAddedWorker.jobs.size).to eq(0) + expect(execute_service[:message]).to include("#{member.username}: Access level is not included in the list") + expect(source.users).not_to include member + expect(NamespaceOnboardingAction.completed?(source.namespace, :user_added)).to be(false) end end context 'when passing an existing invite user id' do - let(:user_ids) { create(:project_member, :invited, project: project).invite_email } + let(:user_ids) { create(:project_member, :invited, project: source).invite_email } it 'does not add a member' do expect(execute_service[:status]).to eq(:error) expect(execute_service[:message]).to eq('Invite email has already been taken') - expect(Namespaces::OnboardingUserAddedWorker.jobs.size).to eq(0) + expect(NamespaceOnboardingAction.completed?(source.namespace, :user_added)).to be(false) end end end diff --git a/spec/services/packages/nuget/search_service_spec.rb b/spec/services/packages/nuget/search_service_spec.rb index d163e7087e4..db758dc6672 100644 --- a/spec/services/packages/nuget/search_service_spec.rb +++ b/spec/services/packages/nuget/search_service_spec.rb @@ -1,8 +1,12 @@ # frozen_string_literal: true + require 'spec_helper' RSpec.describe Packages::Nuget::SearchService do - let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:subgroup) { create(:group, parent: group) } + let_it_be(:project) { create(:project, namespace: subgroup) } let_it_be(:package_a) { create(:nuget_package, project: project, name: 'DummyPackageA') } let_it_be(:packages_b) { create_list(:nuget_package, 5, project: project, name: 'DummyPackageB') } let_it_be(:packages_c) { create_list(:nuget_package, 5, project: project, name: 'DummyPackageC') } @@ -16,94 +20,126 @@ RSpec.describe Packages::Nuget::SearchService do let(:options) { { include_prerelease_versions: include_prerelease_versions, per_page: per_page, padding: padding } } describe '#execute' do - subject { described_class.new(project, search_term, options).execute } + subject { described_class.new(user, target, search_term, options).execute } - it { expect_search_results 3, package_a, packages_b, packages_c } + shared_examples 'handling all the conditions' do + it { expect_search_results 3, package_a, packages_b, packages_c } - context 'with a smaller per page count' do - let(:per_page) { 2 } + context 'with a smaller per page count' do + let(:per_page) { 2 } - it { expect_search_results 3, package_a, packages_b } - end + it { expect_search_results 3, package_a, packages_b } + end - context 'with 0 per page count' do - let(:per_page) { 0 } + context 'with 0 per page count' do + let(:per_page) { 0 } - it { expect_search_results 3, [] } - end + it { expect_search_results 3, [] } + end - context 'with a negative per page count' do - let(:per_page) { -1 } + context 'with a negative per page count' do + let(:per_page) { -1 } - it { expect { subject }.to raise_error(ArgumentError, 'negative per_page') } - end + it { expect { subject }.to raise_error(ArgumentError, 'negative per_page') } + end - context 'with a padding' do - let(:padding) { 2 } + context 'with a padding' do + let(:padding) { 2 } - it { expect_search_results 3, packages_c } - end + it { expect_search_results 3, packages_c } + end - context 'with a too big padding' do - let(:padding) { 5 } + context 'with a too big padding' do + let(:padding) { 5 } - it { expect_search_results 3, [] } - end + it { expect_search_results 3, [] } + end - context 'with a negative padding' do - let(:padding) { -1 } + context 'with a negative padding' do + let(:padding) { -1 } - it { expect { subject }.to raise_error(ArgumentError, 'negative padding') } - end + it { expect { subject }.to raise_error(ArgumentError, 'negative padding') } + end - context 'with search term' do - let(:search_term) { 'umm' } + context 'with search term' do + let(:search_term) { 'umm' } - it { expect_search_results 3, package_a, packages_b, packages_c } - end + it { expect_search_results 3, package_a, packages_b, packages_c } + end - context 'with nil search term' do - let(:search_term) { nil } + context 'with nil search term' do + let(:search_term) { nil } - it { expect_search_results 4, package_a, packages_b, packages_c, package_d } - end + it { expect_search_results 4, package_a, packages_b, packages_c, package_d } + end - context 'with empty search term' do - let(:search_term) { '' } + context 'with empty search term' do + let(:search_term) { '' } - it { expect_search_results 4, package_a, packages_b, packages_c, package_d } - end + it { expect_search_results 4, package_a, packages_b, packages_c, package_d } + end - context 'with prefix search term' do - let(:search_term) { 'dummy' } + context 'with prefix search term' do + let(:search_term) { 'dummy' } - it { expect_search_results 3, package_a, packages_b, packages_c } - end + it { expect_search_results 3, package_a, packages_b, packages_c } + end + + context 'with suffix search term' do + let(:search_term) { 'packagec' } + + it { expect_search_results 1, packages_c } + end + + context 'with pre release packages' do + let_it_be(:package_e) { create(:nuget_package, project: project, name: 'DummyPackageE', version: '3.2.1-alpha') } + + context 'including them' do + it { expect_search_results 4, package_a, packages_b, packages_c, package_e } + end + + context 'excluding them' do + let(:include_prerelease_versions) { false } - context 'with suffix search term' do - let(:search_term) { 'packagec' } + it { expect_search_results 3, package_a, packages_b, packages_c } - it { expect_search_results 1, packages_c } + context 'when mixed with release versions' do + let_it_be(:package_e_release) { create(:nuget_package, project: project, name: 'DummyPackageE', version: '3.2.1') } + + it { expect_search_results 4, package_a, packages_b, packages_c, package_e_release } + end + end + end end - context 'with pre release packages' do - let_it_be(:package_e) { create(:nuget_package, project: project, name: 'DummyPackageE', version: '3.2.1-alpha') } + context 'with project' do + let(:target) { project } - context 'including them' do - it { expect_search_results 4, package_a, packages_b, packages_c, package_e } + before do + project.add_developer(user) end - context 'excluding them' do - let(:include_prerelease_versions) { false } + it_behaves_like 'handling all the conditions' + end - it { expect_search_results 3, package_a, packages_b, packages_c } + context 'with subgroup' do + let(:target) { subgroup } - context 'when mixed with release versions' do - let_it_be(:package_e_release) { create(:nuget_package, project: project, name: 'DummyPackageE', version: '3.2.1') } + before do + subgroup.add_developer(user) + end - it { expect_search_results 4, package_a, packages_b, packages_c, package_e_release } - end + it_behaves_like 'handling all the conditions' + end + + context 'with group' do + let(:target) { group } + + before do + group.add_developer(user) end + + it_behaves_like 'handling all the conditions' end def expect_search_results(total_count, *results) diff --git a/spec/support/shared_contexts/requests/api/nuget_packages_shared_context.rb b/spec/support/shared_contexts/requests/api/nuget_packages_shared_context.rb new file mode 100644 index 00000000000..f877d6299bd --- /dev/null +++ b/spec/support/shared_contexts/requests/api/nuget_packages_shared_context.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +RSpec.shared_context 'nuget api setup' do + include WorkhorseHelpers + include PackagesManagerApiSpecHelpers + include HttpBasicAuthHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:personal_access_token) { create(:personal_access_token, user: user) } +end diff --git a/spec/support/shared_examples/quick_actions/merge_request/rebase_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/merge_request/rebase_quick_action_shared_examples.rb new file mode 100644 index 00000000000..2e8db16ad68 --- /dev/null +++ b/spec/support/shared_examples/quick_actions/merge_request/rebase_quick_action_shared_examples.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'rebase quick action' do + context 'when updating the description' do + before do + sign_in(user) + visit edit_project_merge_request_path(project, merge_request) + end + + it 'rebases the MR', :sidekiq_inline do + fill_in('Description', with: '/rebase') + click_button('Save changes') + + expect(page).not_to have_content('commit behind the target branch') + expect(merge_request.reload).not_to be_merged + end + + it 'ignores /merge if /rebase is specified', :sidekiq_inline do + fill_in('Description', with: "/merge\n/rebase") + click_button('Save changes') + + expect(page).not_to have_content('commit behind the target branch') + expect(merge_request.reload).not_to be_merged + end + end + + context 'when creating a new note' do + context 'when the current user can rebase the MR' do + before do + sign_in(user) + visit project_merge_request_path(project, merge_request) + end + + it 'rebase the MR', :sidekiq_inline do + add_note("/rebase") + + expect(page).to have_content "Scheduled a rebase of branch #{merge_request.source_branch}." + end + end + + context 'when the current user cannot rebase the MR' do + before do + project.add_guest(guest) + sign_in(guest) + visit project_merge_request_path(project, merge_request) + end + + it 'does not rebase the MR' do + add_note("/rebase") + + expect(page).not_to have_content 'Your commands have been executed!' + end + end + end +end diff --git a/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb b/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb index f808d12baf4..689bbf5c3db 100644 --- a/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb @@ -1,31 +1,31 @@ # frozen_string_literal: true -RSpec.shared_examples 'handling nuget service requests' do +RSpec.shared_examples 'handling nuget service requests' do |anonymous_requests_example_name: 'process nuget service index request', anonymous_requests_status: :success| subject { get api(url) } - context 'with valid project' do + context 'with valid target' do using RSpec::Parameterized::TableSyntax context 'personal token' do - where(:project_visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do - 'PUBLIC' | :developer | true | true | 'process nuget service index request' | :success - 'PUBLIC' | :guest | true | true | 'process nuget service index request' | :success - 'PUBLIC' | :developer | true | false | 'process nuget service index request' | :success - 'PUBLIC' | :guest | true | false | 'process nuget service index request' | :success - 'PUBLIC' | :developer | false | true | 'process nuget service index request' | :success - 'PUBLIC' | :guest | false | true | 'process nuget service index request' | :success - 'PUBLIC' | :developer | false | false | 'process nuget service index request' | :success - 'PUBLIC' | :guest | false | false | 'process nuget service index request' | :success - 'PUBLIC' | :anonymous | false | true | 'process nuget service index request' | :success - 'PRIVATE' | :developer | true | true | 'process nuget service index request' | :success - 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden - 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :guest | true | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :developer | false | true | 'rejects nuget packages access' | :not_found - 'PRIVATE' | :guest | false | true | 'rejects nuget packages access' | :not_found - 'PRIVATE' | :developer | false | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :guest | false | false | 'rejects nuget packages access' | :unauthorized - 'PRIVATE' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized + where(:visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + 'PUBLIC' | :developer | true | true | 'process nuget service index request' | :success + 'PUBLIC' | :guest | true | true | 'process nuget service index request' | :success + 'PUBLIC' | :developer | true | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :guest | true | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :developer | false | true | 'process nuget service index request' | :success + 'PUBLIC' | :guest | false | true | 'process nuget service index request' | :success + 'PUBLIC' | :developer | false | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :guest | false | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :anonymous | false | true | anonymous_requests_example_name | anonymous_requests_status + 'PRIVATE' | :developer | true | true | 'process nuget service index request' | :success + 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden + 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :guest | true | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :developer | false | true | 'rejects nuget packages access' | :not_found + 'PRIVATE' | :guest | false | true | 'rejects nuget packages access' | :not_found + 'PRIVATE' | :developer | false | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :guest | false | false | 'rejects nuget packages access' | :unauthorized + 'PRIVATE' | :anonymous | false | true | 'rejects nuget packages access' | :unauthorized end with_them do @@ -35,7 +35,7 @@ RSpec.shared_examples 'handling nuget service requests' do subject { get api(url), headers: headers } before do - project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility_level, false)) + update_visibility_to(Gitlab::VisibilityLevel.const_get(visibility_level, false)) end it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] @@ -43,7 +43,7 @@ RSpec.shared_examples 'handling nuget service requests' do end context 'with job token' do - where(:project_visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + where(:visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do 'PUBLIC' | :developer | true | true | 'process nuget service index request' | :success 'PUBLIC' | :guest | true | true | 'process nuget service index request' | :success 'PUBLIC' | :developer | true | false | 'rejects nuget packages access' | :unauthorized @@ -52,7 +52,7 @@ RSpec.shared_examples 'handling nuget service requests' do 'PUBLIC' | :guest | false | true | 'process nuget service index request' | :success 'PUBLIC' | :developer | false | false | 'rejects nuget packages access' | :unauthorized 'PUBLIC' | :guest | false | false | 'rejects nuget packages access' | :unauthorized - 'PUBLIC' | :anonymous | false | true | 'process nuget service index request' | :success + 'PUBLIC' | :anonymous | false | true | anonymous_requests_example_name | anonymous_requests_status 'PRIVATE' | :developer | true | true | 'process nuget service index request' | :success 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized @@ -71,7 +71,7 @@ RSpec.shared_examples 'handling nuget service requests' do subject { get api(url), headers: headers } before do - project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility_level, false)) + update_visibility_to(Gitlab::VisibilityLevel.const_get(visibility_level, false)) end it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] @@ -79,14 +79,18 @@ RSpec.shared_examples 'handling nuget service requests' do end end - it_behaves_like 'deploy token for package GET requests' + it_behaves_like 'deploy token for package GET requests' do + before do + update_visibility_to(Gitlab::VisibilityLevel::PRIVATE) + end + end - it_behaves_like 'rejects nuget access with unknown project id' + it_behaves_like 'rejects nuget access with unknown target id' - it_behaves_like 'rejects nuget access with invalid project id' + it_behaves_like 'rejects nuget access with invalid target id' end -RSpec.shared_examples 'handling nuget metadata requests with package name' do +RSpec.shared_examples 'handling nuget metadata requests with package name' do |anonymous_requests_example_name: 'process nuget metadata request at package name level', anonymous_requests_status: :success| include_context 'with expected presenters dependency groups' let_it_be(:package_name) { 'Dummy.Package' } @@ -99,19 +103,19 @@ RSpec.shared_examples 'handling nuget metadata requests with package name' do packages.each { |pkg| create_dependencies_for(pkg) } end - context 'with valid project' do + context 'with valid target' do using RSpec::Parameterized::TableSyntax - where(:project_visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + where(:visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do 'PUBLIC' | :developer | true | true | 'process nuget metadata request at package name level' | :success 'PUBLIC' | :guest | true | true | 'process nuget metadata request at package name level' | :success - 'PUBLIC' | :developer | true | false | 'process nuget metadata request at package name level' | :success - 'PUBLIC' | :guest | true | false | 'process nuget metadata request at package name level' | :success + 'PUBLIC' | :developer | true | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :guest | true | false | anonymous_requests_example_name | anonymous_requests_status 'PUBLIC' | :developer | false | true | 'process nuget metadata request at package name level' | :success 'PUBLIC' | :guest | false | true | 'process nuget metadata request at package name level' | :success - 'PUBLIC' | :developer | false | false | 'process nuget metadata request at package name level' | :success - 'PUBLIC' | :guest | false | false | 'process nuget metadata request at package name level' | :success - 'PUBLIC' | :anonymous | false | true | 'process nuget metadata request at package name level' | :success + 'PUBLIC' | :developer | false | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :guest | false | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :anonymous | false | true | anonymous_requests_example_name | anonymous_requests_status 'PRIVATE' | :developer | true | true | 'process nuget metadata request at package name level' | :success 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized @@ -130,21 +134,25 @@ RSpec.shared_examples 'handling nuget metadata requests with package name' do subject { get api(url), headers: headers } before do - project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility_level, false)) + update_visibility_to(Gitlab::VisibilityLevel.const_get(visibility_level, false)) end it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] end - it_behaves_like 'deploy token for package GET requests' + it_behaves_like 'deploy token for package GET requests' do + before do + update_visibility_to(Gitlab::VisibilityLevel::PRIVATE) + end + end - it_behaves_like 'rejects nuget access with unknown project id' + it_behaves_like 'rejects nuget access with unknown target id' - it_behaves_like 'rejects nuget access with invalid project id' + it_behaves_like 'rejects nuget access with invalid target id' end end -RSpec.shared_examples 'handling nuget metadata requests with package name and package version' do +RSpec.shared_examples 'handling nuget metadata requests with package name and package version' do |anonymous_requests_example_name: 'process nuget metadata request at package name and package version level', anonymous_requests_status: :success| include_context 'with expected presenters dependency groups' let_it_be(:package_name) { 'Dummy.Package' } @@ -157,19 +165,19 @@ RSpec.shared_examples 'handling nuget metadata requests with package name and pa create_dependencies_for(package) end - context 'with valid project' do + context 'with valid target' do using RSpec::Parameterized::TableSyntax - where(:project_visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + where(:visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do 'PUBLIC' | :developer | true | true | 'process nuget metadata request at package name and package version level' | :success 'PUBLIC' | :guest | true | true | 'process nuget metadata request at package name and package version level' | :success - 'PUBLIC' | :developer | true | false | 'process nuget metadata request at package name and package version level' | :success - 'PUBLIC' | :guest | true | false | 'process nuget metadata request at package name and package version level' | :success + 'PUBLIC' | :developer | true | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :guest | true | false | anonymous_requests_example_name | anonymous_requests_status 'PUBLIC' | :developer | false | true | 'process nuget metadata request at package name and package version level' | :success 'PUBLIC' | :guest | false | true | 'process nuget metadata request at package name and package version level' | :success - 'PUBLIC' | :developer | false | false | 'process nuget metadata request at package name and package version level' | :success - 'PUBLIC' | :guest | false | false | 'process nuget metadata request at package name and package version level' | :success - 'PUBLIC' | :anonymous | false | true | 'process nuget metadata request at package name and package version level' | :success + 'PUBLIC' | :developer | false | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :guest | false | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :anonymous | false | true | anonymous_requests_example_name | anonymous_requests_status 'PRIVATE' | :developer | true | true | 'process nuget metadata request at package name and package version level' | :success 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized @@ -188,23 +196,25 @@ RSpec.shared_examples 'handling nuget metadata requests with package name and pa subject { get api(url), headers: headers } before do - project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility_level, false)) + update_visibility_to(Gitlab::VisibilityLevel.const_get(visibility_level, false)) end it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] end end - it_behaves_like 'deploy token for package GET requests' + it_behaves_like 'deploy token for package GET requests' do + before do + update_visibility_to(Gitlab::VisibilityLevel::PRIVATE) + end + end - context 'with invalid package name' do - let_it_be(:package_name) { 'Unkown' } + it_behaves_like 'rejects nuget access with unknown target id' - it_behaves_like 'rejects nuget packages access', :developer, :not_found - end + it_behaves_like 'rejects nuget access with invalid target id' end -RSpec.shared_examples 'handling nuget search requests' do +RSpec.shared_examples 'handling nuget search requests' do |anonymous_requests_example_name: 'process nuget search request', anonymous_requests_status: :success| let_it_be(:package_a) { create(:nuget_package, :with_metadatum, name: 'Dummy.PackageA', project: project) } let_it_be(:tag) { create(:packages_tag, package: package_a, name: 'test') } let_it_be(:packages_b) { create_list(:nuget_package, 5, name: 'Dummy.PackageB', project: project) } @@ -219,19 +229,19 @@ RSpec.shared_examples 'handling nuget search requests' do subject { get api(url) } - context 'with valid project' do + context 'with valid target' do using RSpec::Parameterized::TableSyntax - where(:project_visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do + where(:visibility_level, :user_role, :member, :user_token, :shared_examples_name, :expected_status) do 'PUBLIC' | :developer | true | true | 'process nuget search request' | :success 'PUBLIC' | :guest | true | true | 'process nuget search request' | :success - 'PUBLIC' | :developer | true | false | 'process nuget search request' | :success - 'PUBLIC' | :guest | true | false | 'process nuget search request' | :success + 'PUBLIC' | :developer | true | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :guest | true | false | anonymous_requests_example_name | anonymous_requests_status 'PUBLIC' | :developer | false | true | 'process nuget search request' | :success 'PUBLIC' | :guest | false | true | 'process nuget search request' | :success - 'PUBLIC' | :developer | false | false | 'process nuget search request' | :success - 'PUBLIC' | :guest | false | false | 'process nuget search request' | :success - 'PUBLIC' | :anonymous | false | true | 'process nuget search request' | :success + 'PUBLIC' | :developer | false | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :guest | false | false | anonymous_requests_example_name | anonymous_requests_status + 'PUBLIC' | :anonymous | false | true | anonymous_requests_example_name | anonymous_requests_status 'PRIVATE' | :developer | true | true | 'process nuget search request' | :success 'PRIVATE' | :guest | true | true | 'rejects nuget packages access' | :forbidden 'PRIVATE' | :developer | true | false | 'rejects nuget packages access' | :unauthorized @@ -250,16 +260,20 @@ RSpec.shared_examples 'handling nuget search requests' do subject { get api(url), headers: headers } before do - project.update!(visibility_level: Gitlab::VisibilityLevel.const_get(project_visibility_level, false)) + update_visibility_to(Gitlab::VisibilityLevel.const_get(visibility_level, false)) end it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member] end end - it_behaves_like 'deploy token for package GET requests' + it_behaves_like 'deploy token for package GET requests' do + before do + update_visibility_to(Gitlab::VisibilityLevel::PRIVATE) + end + end - it_behaves_like 'rejects nuget access with unknown project id' + it_behaves_like 'rejects nuget access with unknown target id' - it_behaves_like 'rejects nuget access with invalid project id' + it_behaves_like 'rejects nuget access with invalid target id' end diff --git a/spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb index dc6ac5f0371..8b60857cdaf 100644 --- a/spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb @@ -3,7 +3,7 @@ RSpec.shared_examples 'rejects nuget packages access' do |user_type, status, add_member = true| context "for user type #{user_type}" do before do - project.send("add_#{user_type}", user) if add_member && user_type != :anonymous + target.send("add_#{user_type}", user) if add_member && user_type != :anonymous end it_behaves_like 'returning response status', status @@ -21,7 +21,7 @@ end RSpec.shared_examples 'process nuget service index request' do |user_type, status, add_member = true| context "for user type #{user_type}" do before do - project.send("add_#{user_type}", user) if add_member && user_type != :anonymous + target.send("add_#{user_type}", user) if add_member && user_type != :anonymous end it_behaves_like 'returning response status', status @@ -37,7 +37,7 @@ RSpec.shared_examples 'process nuget service index request' do |user_type, statu end context 'with invalid format' do - let(:url) { "/projects/#{project.id}/packages/nuget/index.xls" } + let(:url) { "/#{target_type}/#{target.id}/packages/nuget/index.xls" } it_behaves_like 'rejects nuget packages access', :anonymous, :not_found end @@ -57,7 +57,7 @@ end RSpec.shared_examples 'process nuget metadata request at package name level' do |user_type, status, add_member = true| context "for user type #{user_type}" do before do - project.send("add_#{user_type}", user) if add_member && user_type != :anonymous + target.send("add_#{user_type}", user) if add_member && user_type != :anonymous end it_behaves_like 'returning response status', status @@ -65,7 +65,7 @@ RSpec.shared_examples 'process nuget metadata request at package name level' do it_behaves_like 'returning nuget metadata json response with json schema', 'public_api/v4/packages/nuget/packages_metadata' context 'with invalid format' do - let(:url) { "/projects/#{project.id}/packages/nuget/metadata/#{package_name}/index.xls" } + let(:url) { "/#{target_type}/#{target.id}/packages/nuget/metadata/#{package_name}/index.xls" } it_behaves_like 'rejects nuget packages access', :anonymous, :not_found end @@ -83,7 +83,7 @@ end RSpec.shared_examples 'process nuget metadata request at package name and package version level' do |user_type, status, add_member = true| context "for user type #{user_type}" do before do - project.send("add_#{user_type}", user) if add_member && user_type != :anonymous + target.send("add_#{user_type}", user) if add_member && user_type != :anonymous end it_behaves_like 'returning response status', status @@ -91,7 +91,7 @@ RSpec.shared_examples 'process nuget metadata request at package name and packag it_behaves_like 'returning nuget metadata json response with json schema', 'public_api/v4/packages/nuget/package_metadata' context 'with invalid format' do - let(:url) { "/projects/#{project.id}/packages/nuget/metadata/#{package_name}/#{package.version}.xls" } + let(:url) { "/#{target_type}/#{target.id}/packages/nuget/metadata/#{package_name}/#{package.version}.xls" } it_behaves_like 'rejects nuget packages access', :anonymous, :not_found end @@ -109,7 +109,7 @@ end RSpec.shared_examples 'process nuget workhorse authorization' do |user_type, status, add_member = true| context "for user type #{user_type}" do before do - project.send("add_#{user_type}", user) if add_member && user_type != :anonymous + target.send("add_#{user_type}", user) if add_member && user_type != :anonymous end it_behaves_like 'returning response status', status @@ -128,7 +128,7 @@ RSpec.shared_examples 'process nuget workhorse authorization' do |user_type, sta end before do - project.add_maintainer(user) + target.add_maintainer(user) end it_behaves_like 'returning response status', :forbidden @@ -141,18 +141,18 @@ RSpec.shared_examples 'process nuget upload' do |user_type, status, add_member = it 'creates package files' do expect(::Packages::Nuget::ExtractionWorker).to receive(:perform_async).once expect { subject } - .to change { project.packages.count }.by(1) + .to change { target.packages.count }.by(1) .and change { Packages::PackageFile.count }.by(1) expect(response).to have_gitlab_http_status(status) - package_file = project.packages.last.package_files.reload.last + package_file = target.packages.last.package_files.reload.last expect(package_file.file_name).to eq('package.nupkg') end end context "for user type #{user_type}" do before do - project.send("add_#{user_type}", user) if add_member && user_type != :anonymous + target.send("add_#{user_type}", user) if add_member && user_type != :anonymous end context 'with object storage disabled' do @@ -206,7 +206,7 @@ RSpec.shared_examples 'process nuget upload' do |user_type, status, add_member = context 'with crafted package.path param' do let(:crafted_file) { Tempfile.new('nuget.crafted.package.path') } - let(:url) { "/projects/#{project.id}/packages/nuget?package.path=#{crafted_file.path}" } + let(:url) { "/#{target_type}/#{target.id}/packages/nuget?package.path=#{crafted_file.path}" } let(:params) { { file: temp_file(file_name) } } let(:file_key) { :file } @@ -255,7 +255,7 @@ RSpec.shared_examples 'process nuget download versions request' do |user_type, s context "for user type #{user_type}" do before do - project.send("add_#{user_type}", user) if add_member && user_type != :anonymous + target.send("add_#{user_type}", user) if add_member && user_type != :anonymous end it_behaves_like 'returning response status', status @@ -263,7 +263,7 @@ RSpec.shared_examples 'process nuget download versions request' do |user_type, s it_behaves_like 'returns a valid nuget download versions json response' context 'with invalid format' do - let(:url) { "/projects/#{project.id}/packages/nuget/download/#{package_name}/index.xls" } + let(:url) { "/#{target_type}/#{target.id}/packages/nuget/download/#{package_name}/index.xls" } it_behaves_like 'rejects nuget packages access', :anonymous, :not_found end @@ -281,7 +281,7 @@ end RSpec.shared_examples 'process nuget download content request' do |user_type, status, add_member = true| context "for user type #{user_type}" do before do - project.send("add_#{user_type}", user) if add_member && user_type != :anonymous + target.send("add_#{user_type}", user) if add_member && user_type != :anonymous end it_behaves_like 'returning response status', status @@ -295,7 +295,7 @@ RSpec.shared_examples 'process nuget download content request' do |user_type, st end context 'with invalid format' do - let(:url) { "/projects/#{project.id}/packages/nuget/download/#{package.name}/#{package.version}/#{package.name}.#{package.version}.xls" } + let(:url) { "/#{target_type}/#{target.id}/packages/nuget/download/#{package.name}/#{package.version}/#{package.name}.#{package.version}.xls" } it_behaves_like 'rejects nuget packages access', :anonymous, :not_found end @@ -331,7 +331,7 @@ RSpec.shared_examples 'process nuget search request' do |user_type, status, add_ context "for user type #{user_type}" do before do - project.send("add_#{user_type}", user) if add_member && user_type != :anonymous + target.send("add_#{user_type}", user) if add_member && user_type != :anonymous end it_behaves_like 'returns a valid json search response', status, 4, [1, 5, 5, 1] @@ -370,20 +370,20 @@ RSpec.shared_examples 'process nuget search request' do |user_type, status, add_ end end -RSpec.shared_examples 'rejects nuget access with invalid project id' do - context 'with a project id with invalid integers' do +RSpec.shared_examples 'rejects nuget access with invalid target id' do + context 'with a target id with invalid integers' do using RSpec::Parameterized::TableSyntax - let(:project) { OpenStruct.new(id: id) } + let(:target) { OpenStruct.new(id: id) } where(:id, :status) do - '/../' | :unauthorized + '/../' | :bad_request '' | :not_found - '%20' | :unauthorized - '%2e%2e%2f' | :unauthorized - 'NaN' | :unauthorized + '%20' | :bad_request + '%2e%2e%2f' | :bad_request + 'NaN' | :bad_request 00002345 | :unauthorized - 'anything25' | :unauthorized + 'anything25' | :bad_request end with_them do @@ -392,9 +392,9 @@ RSpec.shared_examples 'rejects nuget access with invalid project id' do end end -RSpec.shared_examples 'rejects nuget access with unknown project id' do - context 'with an unknown project' do - let(:project) { OpenStruct.new(id: 1234567890) } +RSpec.shared_examples 'rejects nuget access with unknown target id' do + context 'with an unknown target' do + let(:target) { OpenStruct.new(id: 1234567890) } context 'as anonymous' do it_behaves_like 'rejects nuget packages access', :anonymous, :unauthorized |