Commit 77e928ea authored by Rémy Coutable's avatar Rémy Coutable

Merge branch '197918-add-package-type-to-project-packages-api' into 'master'

Add package_type as parameter to project packages list api

See merge request gitlab-org/gitlab!25816
parents 881c9510 a70e40a2
---
title: Add package_type as a filter option to the packages list API endpoint
merge_request: 25816
author:
type: added
...@@ -8,8 +8,8 @@ This is the API docs of [GitLab Packages](../administration/packages/index.md). ...@@ -8,8 +8,8 @@ This is the API docs of [GitLab Packages](../administration/packages/index.md).
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9259) in GitLab 11.8. > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9259) in GitLab 11.8.
Get a list of project packages. Both Maven and NPM packages are included in results. Get a list of project packages. All package types are included in results. When
When accessed without authentication, only packages of public projects are returned. accessed without authentication, only packages of public projects are returned.
``` ```
GET /projects/:id/packages GET /projects/:id/packages
...@@ -20,6 +20,7 @@ GET /projects/:id/packages ...@@ -20,6 +20,7 @@ GET /projects/:id/packages
| `id` | integer/string | yes | ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) | | `id` | integer/string | yes | ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
| `order_by`| string | no | The field to use as order. One of `created_at` (default), `name`, `version`, or `type`. | | `order_by`| string | no | The field to use as order. One of `created_at` (default), `name`, `version`, or `type`. |
| `sort` | string | no | The direction of the order, either `asc` (default) for ascending order or `desc` for descending order. | | `sort` | string | no | The direction of the order, either `asc` (default) for ascending order or `desc` for descending order. |
| `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm` or `nuget`. (_Introduced in GitLab 12.9_)
```shell ```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/packages curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/packages
......
# frozen_string_literal: true
module Packages
class PackagesFinder
attr_reader :params, :project
def initialize(project, params = {})
@project = project
@params = params
params[:order_by] ||= 'created_at'
params[:sort] ||= 'asc'
end
def execute
packages = project.packages
packages = filter_by_package_type(packages)
packages = order_packages(packages)
packages
end
private
def filter_by_package_type(packages)
return packages unless params[:package_type]
packages.with_package_type(params[:package_type])
end
def order_packages(packages)
packages.sort_by_attribute("#{params[:order_by]}_#{params[:sort]}")
end
end
end
...@@ -24,13 +24,12 @@ module API ...@@ -24,13 +24,12 @@ module API
desc: 'Return packages ordered by `created_at`, `name`, `version` or `type` fields.' desc: 'Return packages ordered by `created_at`, `name`, `version` or `type` fields.'
optional :sort, type: String, values: %w[asc desc], default: 'asc', optional :sort, type: String, values: %w[asc desc], default: 'asc',
desc: 'Return packages sorted in `asc` or `desc` order.' desc: 'Return packages sorted in `asc` or `desc` order.'
optional :package_type, type: String, values: %w[conan maven npm nuget],
desc: 'Return packages of a certain type'
end end
get ':id/packages' do get ':id/packages' do
packages = user_project.packages packages = ::Packages::PackagesFinder
.new(user_project, declared(params)).execute
if params[:order_by] && params[:sort]
packages = packages.sort_by_attribute("#{params[:order_by]}_#{params[:sort]}")
end
present paginate(packages), with: EE::API::Entities::Package, user: current_user present paginate(packages), with: EE::API::Entities::Package, user: current_user
end end
......
# frozen_string_literal: true
require 'spec_helper'
describe ::Packages::PackagesFinder do
let_it_be(:project) { create(:project) }
let_it_be(:maven_package) { create(:maven_package, project: project, created_at: 2.days.ago, name: 'maven', version: '2.0.0') }
let_it_be(:conan_package) { create(:conan_package, project: project, created_at: 1.day.ago, name: 'conan', version: '1.0.0') }
describe '#execute' do
let(:params) { {} }
subject { described_class.new(project, params).execute }
context 'with package_type' do
let_it_be(:npm_package1) { create(:npm_package, project: project) }
let_it_be(:npm_package2) { create(:npm_package, project: project) }
context 'conan packages' do
let(:params) { { package_type: 'conan' } }
it { is_expected.to eq([conan_package]) }
end
context 'npm packages' do
let(:params) { { package_type: 'npm' } }
it { is_expected.to match_array([npm_package1, npm_package2]) }
end
end
context 'with order_by' do
context 'by default is created_at' do
it { is_expected.to eq([maven_package, conan_package]) }
end
context 'order by name' do
let(:params) { { order_by: 'name' } }
it { is_expected.to eq([conan_package, maven_package]) }
end
context 'order by version' do
let(:params) { { order_by: 'version' } }
it { is_expected.to eq([conan_package, maven_package]) }
end
context 'order by type' do
let(:params) { { order_by: 'type' } }
it { is_expected.to eq([maven_package, conan_package]) }
end
end
context 'with sort' do
context 'by default is ascending' do
it { is_expected.to eq([maven_package, conan_package]) }
end
context 'can sort descended' do
let(:params) { { sort: 'desc' } }
it { is_expected.to eq([conan_package, maven_package]) }
end
end
context 'with nil params' do
it { is_expected.to match_array([conan_package, maven_package]) }
end
end
end
...@@ -4,7 +4,7 @@ require 'spec_helper' ...@@ -4,7 +4,7 @@ require 'spec_helper'
describe API::ProjectPackages do describe API::ProjectPackages do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project, :public) } let_it_be(:project) { create(:project, :public) }
let!(:package1) { create(:npm_package, project: project, version: '3.1.0', name: "@#{project.root_namespace.path}/foo1") } let!(:package1) { create(:npm_package, project: project, version: '3.1.0', name: "@#{project.root_namespace.path}/foo1") }
let(:package_url) { "/projects/#{project.id}/packages/#{package1.id}" } let(:package_url) { "/projects/#{project.id}/packages/#{package1.id}" }
let!(:package2) { create(:nuget_package, project: project, version: '2.0.4') } let!(:package2) { create(:nuget_package, project: project, version: '2.0.4') }
...@@ -94,6 +94,29 @@ describe API::ProjectPackages do ...@@ -94,6 +94,29 @@ describe API::ProjectPackages do
let(:packages) { [package3, package1, package2] } let(:packages) { [package3, package1, package2] }
end end
end end
describe 'filtering on package type' do
let_it_be(:package1) { create(:conan_package, project: project) }
let_it_be(:package2) { create(:maven_package, project: project) }
let_it_be(:package3) { create(:npm_package, project: project) }
let_it_be(:package4) { create(:nuget_package, project: project) }
context 'package types' do
%w[conan maven npm nuget].each do |package_type|
it "returns #{package_type} packages" do
url = package_type_url(package_type)
get api(url, user)
expect(json_response.length).to eq(1)
expect(json_response.map { |package| package['package_type'] }).to contain_exactly(package_type)
end
end
def package_type_url(package_type)
"/projects/#{project.id}/packages?package_type=#{package_type}"
end
end
end
end end
context 'packages feature disabled' do context 'packages feature disabled' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment