Commit fc0bcf9b authored by Stan Hu's avatar Stan Hu

Merge branch '33099-updated_at-filters-for-pipelines-api' into 'master'

Resolve "Add "updated_after" parameter to the Pipelines API endpoint"

Closes #33099

See merge request gitlab-org/gitlab!21133
parents b6cad446 476b5eed
......@@ -25,6 +25,7 @@ class PipelinesFinder
items = by_name(items)
items = by_username(items)
items = by_yaml_errors(items)
items = by_updated_at(items)
sort_items(items)
end
......@@ -128,6 +129,13 @@ class PipelinesFinder
end
# rubocop: enable CodeReuse/ActiveRecord
def by_updated_at(items)
items = items.updated_before(params[:updated_before]) if params[:updated_before].present?
items = items.updated_after(params[:updated_after]) if params[:updated_after].present?
items
end
# rubocop: disable CodeReuse/ActiveRecord
def sort_items(items)
order_by = if ALLOWED_INDEXED_COLUMNS.include?(params[:order_by])
......
......@@ -14,6 +14,7 @@ module Ci
include HasRef
include ShaAttribute
include FromUnion
include UpdatedAtFilterable
sha_attribute :source_sha
sha_attribute :target_sha
......
---
title: Add updated_before and updated_after filters to the Pipelines API endpoint
merge_request: 21133
author:
type: added
......@@ -18,6 +18,8 @@ GET /projects/:id/pipelines
| `yaml_errors`| boolean | no | Returns pipelines with invalid configurations |
| `name`| string | no | The name of the user who triggered pipelines |
| `username`| string | no | The username of the user who triggered pipelines |
| `updated_after` | datetime | no | Return pipelines updated after the specified date. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `updated_before` | datetime | no | Return pipelines updated before the specified date. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `order_by`| string | no | Order pipelines by `id`, `status`, `ref`, `updated_at` or `user_id` (default: `id`) |
| `sort` | string | no | Sort pipelines in `asc` or `desc` order (default: `desc`) |
......
......@@ -25,6 +25,8 @@ module API
optional :yaml_errors, type: Boolean, desc: 'Returns pipelines with invalid configurations'
optional :name, type: String, desc: 'The name of the user who triggered pipelines'
optional :username, type: String, desc: 'The username of the user who triggered pipelines'
optional :updated_before, type: DateTime, desc: 'Return pipelines updated before the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ'
optional :updated_after, type: DateTime, desc: 'Return pipelines updated after the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ'
optional :order_by, type: String, values: PipelinesFinder::ALLOWED_INDEXED_COLUMNS, default: 'id',
desc: 'Order pipelines'
optional :sort, type: String, values: %w[asc desc], default: 'desc',
......
......@@ -170,41 +170,14 @@ describe PipelinesFinder do
end
end
context 'when order_by and sort are specified' do
context 'when order_by user_id' do
let(:params) { { order_by: 'user_id', sort: 'asc' } }
let(:users) { Array.new(2) { create(:user, developer_projects: [project]) } }
let!(:pipelines) { users.map { |user| create(:ci_pipeline, project: project, user: user) } }
context 'when updated_at filters are specified' do
let(:params) { { updated_before: 1.day.ago, updated_after: 3.days.ago } }
let!(:pipeline1) { create(:ci_pipeline, project: project, updated_at: 2.days.ago) }
let!(:pipeline2) { create(:ci_pipeline, project: project, updated_at: 4.days.ago) }
let!(:pipeline3) { create(:ci_pipeline, project: project, updated_at: 1.hour.ago) }
it 'sorts as user_id: :asc' do
is_expected.to match_array(pipelines)
end
context 'when sort is invalid' do
let(:params) { { order_by: 'user_id', sort: 'invalid_sort' } }
it 'sorts as user_id: :desc' do
is_expected.to eq(pipelines.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!(:pipelines) { create_list(:ci_pipeline, 2, project: project) }
it 'sorts as id: :asc' do
is_expected.to eq(pipelines.sort_by { |p| p.id })
end
end
context 'when both are nil' do
let(:params) { { order_by: nil, sort: nil } }
let!(:pipelines) { create_list(:ci_pipeline, 2, project: project) }
it 'sorts as id: :desc' do
is_expected.to eq(pipelines.sort_by { |p| -p.id })
end
it 'returns deployments with matched updated_at' do
is_expected.to match_array([pipeline1])
end
end
......@@ -249,5 +222,36 @@ describe PipelinesFinder do
end
end
end
describe 'ordering' do
using RSpec::Parameterized::TableSyntax
let(:params) { { order_by: order_by, sort: sort } }
let!(:pipeline_1) { create(:ci_pipeline, :scheduled, project: project, iid: 11, ref: 'master', created_at: Time.now, updated_at: Time.now, user: create(:user)) }
let!(:pipeline_2) { create(:ci_pipeline, :created, project: project, iid: 12, ref: 'feature', created_at: 1.day.ago, updated_at: 2.hours.ago, user: create(:user)) }
let!(:pipeline_3) { create(:ci_pipeline, :success, project: project, iid: 8, ref: 'patch', created_at: 2.days.ago, updated_at: 1.hour.ago, user: create(:user)) }
where(:order_by, :sort, :ordered_pipelines) do
'id' | 'asc' | [:pipeline_1, :pipeline_2, :pipeline_3]
'id' | 'desc' | [:pipeline_3, :pipeline_2, :pipeline_1]
'ref' | 'asc' | [:pipeline_2, :pipeline_1, :pipeline_3]
'ref' | 'desc' | [:pipeline_3, :pipeline_1, :pipeline_2]
'status' | 'asc' | [:pipeline_2, :pipeline_1, :pipeline_3]
'status' | 'desc' | [:pipeline_3, :pipeline_1, :pipeline_2]
'updated_at' | 'asc' | [:pipeline_2, :pipeline_3, :pipeline_1]
'updated_at' | 'desc' | [:pipeline_1, :pipeline_3, :pipeline_2]
'user_id' | 'asc' | [:pipeline_1, :pipeline_2, :pipeline_3]
'user_id' | 'desc' | [:pipeline_3, :pipeline_2, :pipeline_1]
'invalid' | 'asc' | [:pipeline_1, :pipeline_2, :pipeline_3]
'id' | 'err' | [:pipeline_3, :pipeline_2, :pipeline_1]
end
with_them do
it 'returns the pipelines ordered' do
expect(subject).to eq(ordered_pipelines.map { |name| public_send(name) })
end
end
end
end
end
......@@ -30,6 +30,16 @@ describe API::Deployments do
expect(json_response.last['iid']).to eq(deployment_3.iid)
end
context 'with updated_at filters specified' do
it 'returns projects deployments with last update in specified datetime range' do
get api("/projects/#{project.id}/deployments", user), params: { updated_before: 30.minutes.ago, updated_after: 90.minutes.ago }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response.first['id']).to eq(deployment_3.id)
end
end
describe 'ordering' do
let(:order_by) { 'iid' }
let(:sort) { 'desc' }
......
......@@ -237,6 +237,20 @@ describe API::Pipelines do
end
end
context 'when updated_at filters are specified' do
let!(:pipeline1) { create(:ci_pipeline, project: project, updated_at: 2.days.ago) }
let!(:pipeline2) { create(:ci_pipeline, project: project, updated_at: 4.days.ago) }
let!(:pipeline3) { create(:ci_pipeline, project: project, updated_at: 1.hour.ago) }
it 'returns pipelines with last update date in specified datetime range' do
get api("/projects/#{project.id}/pipelines", user), params: { updated_before: 1.day.ago, updated_after: 3.days.ago }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response.first['id']).to eq(pipeline1.id)
end
end
context 'when order_by and sort are specified' do
context 'when order_by user_id' do
before 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