Adding order by to list runner jobs api.

This commit is contained in:
sujay patel 2019-06-13 01:33:21 +05:30 committed by sujay
parent b71250ca0f
commit e241c89977
6 changed files with 63 additions and 35 deletions

View file

@ -3,7 +3,7 @@
class RunnerJobsFinder class RunnerJobsFinder
attr_reader :runner, :params attr_reader :runner, :params
ALLOWED_INDEXED_COLUMNS = %w[id created_at].freeze ALLOWED_INDEXED_COLUMNS = %w[id].freeze
def initialize(runner, params = {}) def initialize(runner, params = {})
@runner = runner @runner = runner
@ -28,13 +28,10 @@ class RunnerJobsFinder
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def sort_items(items) def sort_items(items)
order_by = if ALLOWED_INDEXED_COLUMNS.include?(params[:order_by]) return items unless ALLOWED_INDEXED_COLUMNS.include?(params[:order_by])
params[:order_by]
else
:id
end
sort = if params[:sort] =~ /\A(ASC|DESC)\z/i order_by = params[:order_by]
sort = if /\A(ASC|DESC)\z/i.match?(params[:sort])
params[:sort] params[:sort]
else else
:desc :desc

View file

@ -1,5 +1,5 @@
--- ---
title: 51794-add-order-by-to-list-runner-jobs-api title: Add order_by and sort params to list runner jobs api
merge_request: merge_request: 29629
author: Sujay Patel author: Sujay Patel
type: added type: added

View file

@ -291,7 +291,7 @@ GET /runners/:id/jobs
|-----------|---------|----------|---------------------| |-----------|---------|----------|---------------------|
| `id` | integer | yes | The ID of a runner | | `id` | integer | yes | The ID of a runner |
| `status` | string | no | Status of the job; one of: `running`, `success`, `failed`, `canceled` | | `status` | string | no | Status of the job; one of: `running`, `success`, `failed`, `canceled` |
| `order_by`| string | no | Order jobs by `id` or `created_at` (default: id) | | `order_by`| string | no | Order jobs by `id`. |
| `sort` | string | no | Sort jobs in `asc` or `desc` order (default: `desc`) | | `sort` | string | no | Sort jobs in `asc` or `desc` order (default: `desc`) |
``` ```

View file

@ -115,6 +115,8 @@ module API
params do params do
requires :id, type: Integer, desc: 'The ID of the runner' requires :id, type: Integer, desc: 'The ID of the runner'
optional :status, type: String, desc: 'Status of the job', values: Ci::Build::AVAILABLE_STATUSES optional :status, type: String, desc: 'Status of the job', values: Ci::Build::AVAILABLE_STATUSES
optional :order_by, type: String, desc: 'Order by `id` or not', values: RunnerJobsFinder::ALLOWED_INDEXED_COLUMNS
optional :sort, type: String, values: %w[asc desc], default: 'desc', desc: 'Sort by asc (ascending) or desc (descending)'
use :pagination use :pagination
end end
get ':id/jobs' do get ':id/jobs' do

View file

@ -37,38 +37,23 @@ describe RunnerJobsFinder do
end end
context 'when order_by and sort are specified' do context 'when order_by and sort are specified' do
context 'when order_by created_at' do context 'when order_by id and sort is asc' do
let(:params) { { order_by: 'created_at', sort: 'asc' } } let(:params) { { order_by: 'id', sort: 'asc' } }
let!(:jobs) { Array.new(2) { create(:ci_build, runner: runner, project: project, user: create(:user)) } } let!(:jobs) { create_list(:ci_build, 2, runner: runner, project: project, user: create(:user)) }
it 'sorts as created_at: :asc' do
is_expected.to match_array(jobs)
end
context 'when sort is invalid' do
let(:params) { { order_by: 'created_at', sort: 'invalid_sort' } }
it 'sorts as created_at: :desc' do
is_expected.to eq(jobs.sort_by { |p| -p.user.id })
end
end
end
context 'when order_by is invalid' do
let(:params) { { order_by: 'invalid_column', sort: 'asc' } }
let!(:jobs) { Array.new(2) { create(:ci_build, runner: runner, project: project, user: create(:user)) } }
it 'sorts as id: :asc' do it 'sorts as id: :asc' do
is_expected.to eq(jobs.sort_by { |p| p.id }) is_expected.to eq(jobs.sort_by(&:id))
end end
end end
end
context 'when both are nil' do context 'when order_by is specified and sort is not specified' do
let(:params) { { order_by: nil, sort: nil } } context 'when order_by id and sort is not specified' do
let!(:jobs) { Array.new(2) { create(:ci_build, runner: runner, project: project, user: create(:user)) } } let(:params) { { order_by: 'id' } }
let!(:jobs) { create_list(:ci_build, 2, runner: runner, project: project, user: create(:user)) }
it 'sorts as id: :desc' do it 'sorts as id: :desc' do
is_expected.to eq(jobs.sort_by { |p| -p.id }) is_expected.to eq(jobs.sort_by(&:id).reverse)
end end
end end
end end

View file

@ -584,6 +584,34 @@ describe API::Runners do
end end
end end
context 'when valid order_by is provided' do
context 'when sort order is not specified' do
it 'return jobs in descending order' do
get api("/runners/#{project_runner.id}/jobs?order_by=id", admin)
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an(Array)
expect(json_response.length).to eq(2)
expect(json_response.first).to include('id' => job_5.id)
end
end
context 'when sort order is specified as asc' do
it 'return jobs sorted in ascending order' do
get api("/runners/#{project_runner.id}/jobs?order_by=id&sort=asc", admin)
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an(Array)
expect(json_response.length).to eq(2)
expect(json_response.first).to include('id' => job_4.id)
end
end
end
context 'when invalid status is provided' do context 'when invalid status is provided' do
it 'return 400' do it 'return 400' do
get api("/runners/#{project_runner.id}/jobs?status=non-existing", admin) get api("/runners/#{project_runner.id}/jobs?status=non-existing", admin)
@ -591,6 +619,22 @@ describe API::Runners do
expect(response).to have_gitlab_http_status(400) expect(response).to have_gitlab_http_status(400)
end end
end end
context 'when invalid order_by is provided' do
it 'return 400' do
get api("/runners/#{project_runner.id}/jobs?order_by=non-existing", admin)
expect(response).to have_gitlab_http_status(400)
end
end
context 'when invalid sort is provided' do
it 'return 400' do
get api("/runners/#{project_runner.id}/jobs?sort=non-existing", admin)
expect(response).to have_gitlab_http_status(400)
end
end
end end
context "when runner doesn't exist" do context "when runner doesn't exist" do