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,14 +244,49 @@ RSpec.describe 'Epics through GroupQuery' do ...@@ -212,14 +244,49 @@ RSpec.describe 'Epics through GroupQuery' do
end end
end end
context 'with search params' do context 'filter' do
it 'returns only matching epics' do context 'with search params' do
filter_params = { search: 'bar', in: [:DESCRIPTION] } it 'returns only matching epics' do
graphql_query = query(filter_params) filter_params = { search: 'bar', in: [:DESCRIPTION] }
graphql_query = query(filter_params)
post_graphql(graphql_query, current_user: user) post_graphql(graphql_query, current_user: user)
expect_array_response([epic2.to_global_id.to_s])
end
end
context 'when searching by update time' do
let(:start_time) { 10.days.ago }
let(:cutoff) { start_time + 36.hours }
expect_array_response([epic2.to_global_id.to_s]) 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
end end
......
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