Commit e456516c authored by charlie ablett's avatar charlie ablett Committed by Alex Kalderimis

Add epic sort by last created or updated

- update tests
- update docs

Changelog: added
MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79923
EE: true
parent 571fcbff
...@@ -17041,12 +17041,16 @@ Roadmap sort values. ...@@ -17041,12 +17041,16 @@ Roadmap sort values.
| Value | Description | | Value | Description |
| ----- | ----------- | | ----- | ----------- |
| <a id="epicsortcreated_at_asc"></a>`CREATED_AT_ASC` | Sort by created_at by ascending order. |
| <a id="epicsortcreated_at_desc"></a>`CREATED_AT_DESC` | Sort by created_at by descending order. |
| <a id="epicsortend_date_asc"></a>`END_DATE_ASC` | Sort by end date in ascending order. | | <a id="epicsortend_date_asc"></a>`END_DATE_ASC` | Sort by end date in ascending order. |
| <a id="epicsortend_date_desc"></a>`END_DATE_DESC` | Sort by end date in descending order. | | <a id="epicsortend_date_desc"></a>`END_DATE_DESC` | Sort by end date in descending order. |
| <a id="epicsortstart_date_asc"></a>`START_DATE_ASC` | Sort by start date in ascending order. | | <a id="epicsortstart_date_asc"></a>`START_DATE_ASC` | Sort by start date in ascending order. |
| <a id="epicsortstart_date_desc"></a>`START_DATE_DESC` | Sort by start date in descending order. | | <a id="epicsortstart_date_desc"></a>`START_DATE_DESC` | Sort by start date in descending order. |
| <a id="epicsorttitle_asc"></a>`TITLE_ASC` | Sort by title in ascending order. | | <a id="epicsorttitle_asc"></a>`TITLE_ASC` | Sort by title in ascending order. |
| <a id="epicsorttitle_desc"></a>`TITLE_DESC` | Sort by title in descending order. | | <a id="epicsorttitle_desc"></a>`TITLE_DESC` | Sort by title in descending order. |
| <a id="epicsortupdated_at_asc"></a>`UPDATED_AT_ASC` | Sort by updated_at by ascending order. |
| <a id="epicsortupdated_at_desc"></a>`UPDATED_AT_DESC` | Sort by updated_at by descending order. |
| <a id="epicsortend_date_asc"></a>`end_date_asc` **{warning-solid}** | **Deprecated** in 13.11. Use END_DATE_ASC. | | <a id="epicsortend_date_asc"></a>`end_date_asc` **{warning-solid}** | **Deprecated** in 13.11. Use END_DATE_ASC. |
| <a id="epicsortend_date_desc"></a>`end_date_desc` **{warning-solid}** | **Deprecated** in 13.11. Use END_DATE_DESC. | | <a id="epicsortend_date_desc"></a>`end_date_desc` **{warning-solid}** | **Deprecated** in 13.11. Use END_DATE_DESC. |
| <a id="epicsortstart_date_asc"></a>`start_date_asc` **{warning-solid}** | **Deprecated** in 13.11. Use START_DATE_ASC. | | <a id="epicsortstart_date_asc"></a>`start_date_asc` **{warning-solid}** | **Deprecated** in 13.11. Use START_DATE_ASC. |
...@@ -60,6 +60,19 @@ module Resolvers ...@@ -60,6 +60,19 @@ module Resolvers
required: false, required: false,
description: 'Filter by reaction emoji applied by the current user.' description: 'Filter by reaction emoji applied by the current user.'
argument :created_after, Types::TimeType,
required: false,
description: 'Epics created after this date.'
argument :created_before, Types::TimeType,
required: false,
description: 'Epics created before this date.'
argument :updated_after, Types::TimeType,
required: false,
description: 'Epics updated after this date.'
argument :updated_before, Types::TimeType,
required: false,
description: 'Epics updated before this date.'
argument :not, ::Types::Epics::NegatedEpicFilterInputType, argument :not, ::Types::Epics::NegatedEpicFilterInputType,
required: false, required: false,
description: 'Negated epic arguments.' description: 'Negated epic arguments.'
......
...@@ -18,5 +18,9 @@ module Types ...@@ -18,5 +18,9 @@ module Types
value 'END_DATE_ASC', 'Sort by end date in ascending order.', value: :end_date_asc value 'END_DATE_ASC', 'Sort by end date in ascending order.', value: :end_date_asc
value 'TITLE_DESC', 'Sort by title in descending order.', value: :title_desc value 'TITLE_DESC', 'Sort by title in descending order.', value: :title_desc
value 'TITLE_ASC', 'Sort by title in ascending order.', value: :title_asc value 'TITLE_ASC', 'Sort by title in ascending order.', value: :title_asc
value 'CREATED_AT_ASC', 'Sort by created_at by ascending order.', value: :created_at_asc
value 'CREATED_AT_DESC', 'Sort by created_at by descending order.', value: :created_at_desc
value 'UPDATED_AT_ASC', 'Sort by updated_at by ascending order.', value: :updated_at_asc
value 'UPDATED_AT_DESC', 'Sort by updated_at by descending order.', value: :updated_at_desc
end end
end end
...@@ -6,6 +6,6 @@ RSpec.describe GitlabSchema.types['EpicSort'] do ...@@ -6,6 +6,6 @@ RSpec.describe GitlabSchema.types['EpicSort'] do
it { expect(described_class.graphql_name).to eq('EpicSort') } it { expect(described_class.graphql_name).to eq('EpicSort') }
it 'exposes all the existing epic sort orders' do it 'exposes all the existing epic sort orders' do
expect(described_class.values.keys).to include(*%w[start_date_desc start_date_asc end_date_desc end_date_asc START_DATE_DESC START_DATE_ASC END_DATE_DESC END_DATE_ASC TITLE_DESC TITLE_ASC]) expect(described_class.values.keys).to include(*%w[start_date_desc start_date_asc end_date_desc end_date_asc START_DATE_DESC START_DATE_ASC END_DATE_DESC END_DATE_ASC TITLE_DESC TITLE_ASC CREATED_AT_ASC CREATED_AT_DESC UPDATED_AT_ASC UPDATED_AT_DESC])
end end
end end
...@@ -52,6 +52,64 @@ RSpec.describe 'getting epics information' do ...@@ -52,6 +52,64 @@ RSpec.describe 'getting epics information' do
end end
end end
describe 'query for epics by created_at and updated_at' do
let_it_be(:epic1) { create(:epic, group: group, created_at: 2.weeks.ago, updated_at: 10.seconds.ago) }
let_it_be(:epic2) { create(:epic, group: group, created_at: 8.days.ago, updated_at: 2.minutes.ago) }
let_it_be(:epic3) { create(:epic, group: group, created_at: 2.hours.ago, updated_at: 9.minutes.ago) }
let_it_be(:epic4) { create(:epic, group: group, created_at: 15.minutes.ago, updated_at: 14.minutes.ago) }
# before(:all) do
# epic1.update_column(:updated_at, 10.seconds.ago)
# epic2.update_column(:updated_at, 2.minutes.ago)
# epic3.update_column(:updated_at, 9.minutes.ago)
# epic4.update_column(:updated_at, 14.minutes.ago)
# pp Time.now.strftime("%Y-%m-%d")
# pp epic4.updated_at
# end
it 'filters by createdBefore' do
post_graphql(epics_query(group, 'createdBefore', 5.days.ago), current_user: user)
expect_epics_response(epic1, epic2)
end
it 'filters by createdAfter' do
post_graphql(epics_query(group, 'createdAfter', 5.days.ago), current_user: user)
expect_epics_response(epic3, epic4)
end
it 'filters by updatedBefore' do
post_graphql(epics_query(group, 'updatedBefore', 7.minutes.ago), current_user: user)
expect_epics_response(epic3, epic4)
end
it 'filters by updatedAfter' do
post_graphql(epics_query(group, 'updatedAfter', 7.minutes.ago), current_user: user)
expect_epics_response(epic1, epic2)
end
it 'filters by a combination of created parameters provided' do
post_graphql(epics_query_by_hash(group, { 'createdBefore' => Time.zone.now, 'createdAfter' => 20.minutes.ago }), current_user: user)
expect_epics_response(epic4)
end
it 'filters by a combination of created/updated parameters provided' do
post_graphql(epics_query_by_hash(group, { 'updatedBefore' => 3.minutes.ago, 'createdAfter' => 20.minutes.ago }), current_user: user)
expect_epics_response(epic4)
end
it 'returns nothing for impossible parameters' do
post_graphql(epics_query_by_hash(group, { 'createdBefore' => 7.minutes.ago, 'createdAfter' => Time.zone.now }), current_user: user)
expect_epics_response # empty set
end
end
describe 'query for epics by time frame' do describe 'query for epics by time frame' do
let_it_be(:epic1) { create(:epic, group: group, state: :opened, start_date: "2019-08-13", end_date: "2019-08-20") } let_it_be(:epic1) { create(:epic, group: group, state: :opened, start_date: "2019-08-13", end_date: "2019-08-20") }
let_it_be(:epic2) { create(:epic, group: group, state: :closed, start_date: "2019-08-13", end_date: "2019-08-21") } let_it_be(:epic2) { create(:epic, group: group, state: :closed, start_date: "2019-08-13", end_date: "2019-08-21") }
...@@ -213,6 +271,7 @@ RSpec.describe 'getting epics information' do ...@@ -213,6 +271,7 @@ RSpec.describe 'getting epics information' do
end end
def expect_epics_response(*epics) def expect_epics_response(*epics)
epics ||= []
actual_epics = graphql_data['group']['epics']['nodes'].map { |epic| epic['id'] } actual_epics = graphql_data['group']['epics']['nodes'].map { |epic| epic['id'] }
expected_epics = epics.map { |epic| epic.to_global_id.to_s } expected_epics = epics.map { |epic| epic.to_global_id.to_s }
......
...@@ -66,14 +66,14 @@ RSpec.describe 'Epics through GroupQuery' do ...@@ -66,14 +66,14 @@ RSpec.describe 'Epics through GroupQuery' do
context 'with multiple epics' do context 'with multiple epics' do
let_it_be(:user2) { create(:user) } let_it_be(:user2) { create(:user) }
let_it_be(:epic2) { create(:epic, author: user2, group: group, title: 'foo', description: 'bar', created_at: 2.days.ago, updated_at: 3.days.ago, start_date: 3.days.ago, end_date: 3.days.ago ) } let_it_be(:epic2) { create(:epic, author: user2, group: group, title: 'foo', description: 'bar', created_at: 5.days.ago, updated_at: 3.days.ago, start_date: 3.days.ago, end_date: 3.days.ago ) }
before do before do
stub_licensed_features(epics: true) stub_licensed_features(epics: true)
end end
context 'with sort and pagination' do context 'with sort and pagination' do
let_it_be(:epic3) { create(:epic, group: group, start_date: 4.days.ago, end_date: 7.days.ago ) } let_it_be(:epic3) { create(:epic, group: group, start_date: 4.days.ago, end_date: 7.days.ago, created_at: 4.days.ago, updated_at: 1.day.ago ) }
let_it_be(:epic4) { create(:epic, group: group, start_date: 5.days.ago, end_date: 6.days.ago ) } let_it_be(:epic4) { create(:epic, group: group, start_date: 5.days.ago, end_date: 6.days.ago ) }
let(:current_user) { user } let(:current_user) { user }
...@@ -126,6 +126,38 @@ RSpec.describe 'Epics through GroupQuery' do ...@@ -126,6 +126,38 @@ RSpec.describe 'Epics through GroupQuery' do
let(:all_records) { global_ids(epic2, epic, epic4, epic3) } let(:all_records) { global_ids(epic2, epic, epic4, epic3) }
end end
end end
context 'with created_at_asc' do
it_behaves_like 'sorted paginated query', is_reversible: true do
let(:sort_param) { :CREATED_AT_ASC }
let(:first_param) { 2 }
let(:all_records) { global_ids(epic2, epic3, epic, epic4) }
end
end
context 'with created_at_desc' do
it_behaves_like 'sorted paginated query', is_reversible: true do
let(:sort_param) { :CREATED_AT_DESC }
let(:first_param) { 2 }
let(:all_records) { global_ids(epic4, epic, epic3, epic2) }
end
end
context 'with updated_at_asc' do
it_behaves_like 'sorted paginated query', is_reversible: true do
let(:sort_param) { :UPDATED_AT_ASC }
let(:first_param) { 2 }
let(:all_records) { global_ids(epic2, epic, epic3, epic4) }
end
end
context 'with updated_at_desc' do
it_behaves_like 'sorted paginated query', is_reversible: true do
let(:sort_param) { :UPDATED_AT_DESC }
let(:first_param) { 2 }
let(:all_records) { global_ids(epic4, epic3, epic, epic2) }
end
end
end end
it 'sorts by created_at descending by default' do it 'sorts by created_at descending by default' do
...@@ -212,6 +244,7 @@ RSpec.describe 'Epics through GroupQuery' do ...@@ -212,6 +244,7 @@ RSpec.describe 'Epics through GroupQuery' do
end end
end end
context 'filter' do
context 'with search params' do context 'with search params' do
it 'returns only matching epics' do it 'returns only matching epics' do
filter_params = { search: 'bar', in: [:DESCRIPTION] } filter_params = { search: 'bar', in: [:DESCRIPTION] }
...@@ -222,6 +255,40 @@ RSpec.describe 'Epics through GroupQuery' do ...@@ -222,6 +255,40 @@ RSpec.describe 'Epics through GroupQuery' do
expect_array_response([epic2.to_global_id.to_s]) expect_array_response([epic2.to_global_id.to_s])
end end
end end
context 'when searching by update time' do
let(:start_time) { 10.days.ago }
let(:cutoff) { start_time + 36.hours }
before do
all_merge_requests.each_with_index do |mr, i|
mr.updated_at = start_time + i.days
mr.save!(touch: false)
end
end
context 'when searching by updated_after' do
let(:search_params) { { updated_after: cutoff } }
let(:mrs) { all_merge_requests[2..] }
it_behaves_like 'when searching with parameters'
end
context 'when searching by updated_before' do
let(:search_params) { { updated_before: cutoff } }
let(:mrs) { all_merge_requests[0..1] }
it_behaves_like 'when searching with parameters'
end
context 'when searching by updated_before and updated_after' do
let(:search_params) { { updated_after: cutoff, updated_before: cutoff + 2.days } }
let(:mrs) { all_merge_requests[2..3] }
it_behaves_like 'when searching with parameters'
end
end
end
end end
context 'when error requests' do context 'when error requests' 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