Commit a70e40a2 authored by Nick Kipling's avatar Nick Kipling Committed by Rémy Coutable

Adds package_type param to package list api

Update packages list api to support package_type
Update package_finder to support by type
Added tests
parent 22d65400
---
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).
> [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.
When accessed without authentication, only packages of public projects are returned.
Get a list of project packages. All package types are included in results. When
accessed without authentication, only packages of public projects are returned.
```
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) |
| `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. |
| `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm` or `nuget`. (_Introduced in GitLab 12.9_)
```shell
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
desc: 'Return packages ordered by `created_at`, `name`, `version` or `type` fields.'
optional :sort, type: String, values: %w[asc desc], default: 'asc',
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
get ':id/packages' do
packages = user_project.packages
if params[:order_by] && params[:sort]
packages = packages.sort_by_attribute("#{params[:order_by]}_#{params[:sort]}")
end
packages = ::Packages::PackagesFinder
.new(user_project, declared(params)).execute
present paginate(packages), with: EE::API::Entities::Package, user: current_user
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'
describe API::ProjectPackages do
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(:package_url) { "/projects/#{project.id}/packages/#{package1.id}" }
let!(:package2) { create(:nuget_package, project: project, version: '2.0.4') }
......@@ -94,6 +94,29 @@ describe API::ProjectPackages do
let(:packages) { [package3, package1, package2] }
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
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