diff options
Diffstat (limited to 'spec/requests/api/graphql/packages/package_spec.rb')
-rw-r--r-- | spec/requests/api/graphql/packages/package_spec.rb | 238 |
1 files changed, 146 insertions, 92 deletions
diff --git a/spec/requests/api/graphql/packages/package_spec.rb b/spec/requests/api/graphql/packages/package_spec.rb index a9019a7611a..2ff3bc7cc47 100644 --- a/spec/requests/api/graphql/packages/package_spec.rb +++ b/spec/requests/api/graphql/packages/package_spec.rb @@ -4,7 +4,9 @@ require 'spec_helper' RSpec.describe 'package details' do include GraphqlHelpers - let_it_be_with_reload(:project) { create(:project) } + let_it_be_with_reload(:group) { create(:group) } + let_it_be_with_reload(:project) { create(:project, group: group) } + let_it_be(:user) { create(:user) } let_it_be(:composer_package) { create(:composer_package, project: project) } let_it_be(:composer_json) { { name: 'name', type: 'type', license: 'license', version: 1 } } let_it_be(:composer_metadatum) do @@ -17,7 +19,6 @@ RSpec.describe 'package details' do let(:excluded) { %w[metadata apiFuzzingCiConfiguration pipeline packageFiles] } let(:metadata) { query_graphql_fragment('ComposerMetadata') } let(:package_files) {all_graphql_fields_for('PackageFile')} - let(:user) { project.owner } let(:package_global_id) { global_id_of(composer_package) } let(:package_details) { graphql_data_at(:package) } @@ -37,145 +38,198 @@ RSpec.describe 'package details' do subject { post_graphql(query, current_user: user) } - it_behaves_like 'a working graphql query' do + context 'with unauthorized user' do before do - subject + project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) end - it 'matches the JSON schema' do - expect(package_details).to match_schema('graphql/packages/package_details') + it 'returns no packages' do + subject + + expect(graphql_data_at(:package)).to be_nil end end - context 'there are other versions of this package' do - let(:depth) { 3 } - let(:excluded) { %w[metadata project tags pipelines] } # to limit the query complexity - - let_it_be(:siblings) { create_list(:composer_package, 2, project: project, name: composer_package.name) } + context 'with authorized user' do + before do + project.add_developer(user) + end - it 'includes the sibling versions' do - subject + it_behaves_like 'a working graphql query' do + before do + subject + end - expect(graphql_data_at(:package, :versions, :nodes)).to match_array( - siblings.map { |p| a_hash_including('id' => global_id_of(p)) } - ) + it 'matches the JSON schema' do + expect(package_details).to match_schema('graphql/packages/package_details') + end end - context 'going deeper' do - let(:depth) { 6 } + context 'there are other versions of this package' do + let(:depth) { 3 } + let(:excluded) { %w[metadata project tags pipelines] } # to limit the query complexity - it 'does not create a cycle of versions' do + let_it_be(:siblings) { create_list(:composer_package, 2, project: project, name: composer_package.name) } + + it 'includes the sibling versions' do subject - expect(graphql_data_at(:package, :versions, :nodes, :version)).to be_present - expect(graphql_data_at(:package, :versions, :nodes, :versions, :nodes)).to eq [nil, nil] + expect(graphql_data_at(:package, :versions, :nodes)).to match_array( + siblings.map { |p| a_hash_including('id' => global_id_of(p)) } + ) end - end - end - context 'with a batched query' do - let_it_be(:conan_package) { create(:conan_package, project: project) } + context 'going deeper' do + let(:depth) { 6 } - let(:batch_query) do - <<~QUERY - { - a: package(id: "#{global_id_of(composer_package)}") { name } - b: package(id: "#{global_id_of(conan_package)}") { name } - } - QUERY + it 'does not create a cycle of versions' do + subject + + expect(graphql_data_at(:package, :versions, :nodes, :version)).to be_present + expect(graphql_data_at(:package, :versions, :nodes, :versions, :nodes)).to match_array [nil, nil] + end + end end - let(:a_packages_names) { graphql_data_at(:a, :packages, :nodes, :name) } + context 'with package files pending destruction' do + let_it_be(:package_file) { create(:package_file, package: composer_package) } + let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: composer_package) } - it 'returns an error for the second package and data for the first' do - post_graphql(batch_query, current_user: user) + let(:package_file_ids) { graphql_data_at(:package, :package_files, :nodes).map { |node| node["id"] } } - expect(graphql_data_at(:a, :name)).to eq(composer_package.name) + it 'does not return them' do + subject - expect_graphql_errors_to_include [/Package details can be requested only for one package at a time/] - expect(graphql_data_at(:b)).to be(nil) - end - end + expect(package_file_ids).to contain_exactly(package_file.to_global_id.to_s) + end - context 'with unauthorized user' do - let_it_be(:user) { create(:user) } + context 'with packages_installable_package_files disabled' do + before do + stub_feature_flags(packages_installable_package_files: false) + end - before do - project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + it 'returns them' do + subject + + expect(package_file_ids).to contain_exactly(package_file_pending_destruction.to_global_id.to_s, package_file.to_global_id.to_s) + end + end end - it 'returns no packages' do - subject + context 'with a batched query' do + let_it_be(:conan_package) { create(:conan_package, project: project) } - expect(graphql_data_at(:package)).to be_nil - end - end + let(:batch_query) do + <<~QUERY + { + a: package(id: "#{global_id_of(composer_package)}") { name } + b: package(id: "#{global_id_of(conan_package)}") { name } + } + QUERY + end - context 'pipelines field', :aggregate_failures do - let(:pipelines) { create_list(:ci_pipeline, 6, project: project) } - let(:pipeline_gids) { pipelines.sort_by(&:id).map(&:to_gid).map(&:to_s).reverse } + let(:a_packages_names) { graphql_data_at(:a, :packages, :nodes, :name) } - before do - composer_package.pipelines = pipelines - composer_package.save! - end + it 'returns an error for the second package and data for the first' do + post_graphql(batch_query, current_user: user) - def run_query(args) - pipelines_nodes = <<~QUERY - nodes { - id - } - pageInfo { - startCursor - endCursor - } - QUERY + expect(graphql_data_at(:a, :name)).to eq(composer_package.name) - query = graphql_query_for(:package, { id: package_global_id }, query_graphql_field("pipelines", args, pipelines_nodes)) - post_graphql(query, current_user: user) + expect_graphql_errors_to_include [/Package details can be requested only for one package at a time/] + expect(graphql_data_at(:b)).to be(nil) + end end - it 'loads the second page with pagination first correctly' do - run_query(first: 2) - pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id') + context 'pipelines field', :aggregate_failures do + let(:pipelines) { create_list(:ci_pipeline, 6, project: project) } + let(:pipeline_gids) { pipelines.sort_by(&:id).map(&:to_gid).map(&:to_s).reverse } - expect(pipeline_ids).to eq(pipeline_gids[0..1]) + before do + composer_package.pipelines = pipelines + composer_package.save! + end - cursor = graphql_data.dig('package', 'pipelines', 'pageInfo', 'endCursor') + def run_query(args) + pipelines_nodes = <<~QUERY + nodes { + id + } + pageInfo { + startCursor + endCursor + } + QUERY + + query = graphql_query_for(:package, { id: package_global_id }, query_graphql_field("pipelines", args, pipelines_nodes)) + post_graphql(query, current_user: user) + end - run_query(first: 2, after: cursor) + it 'loads the second page with pagination first correctly' do + run_query(first: 2) + pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id') - pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id') + expect(pipeline_ids).to eq(pipeline_gids[0..1]) - expect(pipeline_ids).to eq(pipeline_gids[2..3]) - end + cursor = graphql_data.dig('package', 'pipelines', 'pageInfo', 'endCursor') - it 'loads the second page with pagination last correctly' do - run_query(last: 2) - pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id') + run_query(first: 2, after: cursor) - expect(pipeline_ids).to eq(pipeline_gids[4..5]) + pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id') - cursor = graphql_data.dig('package', 'pipelines', 'pageInfo', 'startCursor') + expect(pipeline_ids).to eq(pipeline_gids[2..3]) + end - run_query(last: 2, before: cursor) + it 'loads the second page with pagination last correctly' do + run_query(last: 2) + pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id') - pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id') + expect(pipeline_ids).to eq(pipeline_gids[4..5]) - expect(pipeline_ids).to eq(pipeline_gids[2..3]) - end + cursor = graphql_data.dig('package', 'pipelines', 'pageInfo', 'startCursor') + + run_query(last: 2, before: cursor) + + pipeline_ids = graphql_data.dig('package', 'pipelines', 'nodes').pluck('id') - context 'with unauthorized user' do - let_it_be(:user) { create(:user) } + expect(pipeline_ids).to eq(pipeline_gids[2..3]) + end + end + context 'package managers paths' do before do - project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + subject end - it 'returns no packages' do - run_query(first: 2) + it 'returns npm_url correctly' do + expect(graphql_data_at(:package, :npm_url)).to eq("http://localhost/api/v4/projects/#{project.id}/packages/npm") + end + + it 'returns maven_url correctly' do + expect(graphql_data_at(:package, :maven_url)).to eq("http://localhost/api/v4/projects/#{project.id}/packages/maven") + end + + it 'returns conan_url correctly' do + expect(graphql_data_at(:package, :conan_url)).to eq("http://localhost/api/v4/projects/#{project.id}/packages/conan") + end + + it 'returns nuget_url correctly' do + expect(graphql_data_at(:package, :nuget_url)).to eq("http://localhost/api/v4/projects/#{project.id}/packages/nuget/index.json") + end + + it 'returns pypi_url correctly' do + expect(graphql_data_at(:package, :pypi_url)).to eq("http://__token__:<your_personal_token>@localhost/api/v4/projects/#{project.id}/packages/pypi/simple") + end + + it 'returns pypi_setup_url correctly' do + expect(graphql_data_at(:package, :pypi_setup_url)).to eq("http://localhost/api/v4/projects/#{project.id}/packages/pypi") + end + + it 'returns composer_url correctly' do + expect(graphql_data_at(:package, :composer_url)).to eq("http://localhost/api/v4/group/#{group.id}/-/packages/composer/packages.json") + end - expect(graphql_data_at(:package)).to be_nil + it 'returns composer_config_repository_url correctly' do + expect(graphql_data_at(:package, :composer_config_repository_url)).to eq("localhost/#{group.id}") end end end |