Commit 8e55df8a authored by Felipe Artur's avatar Felipe Artur Committed by Sean McGivern

Allow to filter epics by timeframe or state using GraphQL

Add GraphQL parameters for epics to allow filtering by state, start_date
and end_date.
parent ae14efbd
...@@ -92,8 +92,8 @@ class EpicsFinder < IssuableFinder ...@@ -92,8 +92,8 @@ class EpicsFinder < IssuableFinder
def by_timeframe(items) def by_timeframe(items)
return items unless params[:start_date] && params[:end_date] return items unless params[:start_date] && params[:end_date]
end_date = params[:end_date].to_datetime.end_of_day end_date = params[:end_date].to_date
start_date = params[:start_date].to_datetime.beginning_of_day start_date = params[:start_date].to_date
items items
.where('epics.start_date is not NULL or epics.end_date is not NULL') .where('epics.start_date is not NULL or epics.end_date is not NULL')
......
...@@ -10,12 +10,26 @@ module Resolvers ...@@ -10,12 +10,26 @@ module Resolvers
required: false, required: false,
description: 'The list of IIDs of epics, e.g., [1, 2]' description: 'The list of IIDs of epics, e.g., [1, 2]'
argument :state, Types::EpicStateEnum,
required: false,
description: 'Filter epics by state'
argument :start_date, Types::TimeType,
required: false,
description: 'List epics within a time frame where epics.start_date is between start_date and end_date parameters (end_date parameter must be present)'
argument :end_date, Types::TimeType,
required: false,
description: 'List epics within a time frame where epics.end_date is between start_date and end_date parameters (start_date parameter must be present)'
type Types::EpicType, null: true type Types::EpicType, null: true
def resolve(**args) def resolve(**args)
return [] unless object.present? return [] unless object.present?
return [] unless epic_feature_enabled? return [] unless epic_feature_enabled?
validate_date_params!(args)
find_epics(transform_args(args)) find_epics(transform_args(args))
end end
...@@ -29,6 +43,16 @@ module Resolvers ...@@ -29,6 +43,16 @@ module Resolvers
group.feature_available?(:epics) group.feature_available?(:epics)
end end
def validate_date_params!(args)
return unless args[:start_date].present? || args[:end_date].present?
date_params_complete = args[:start_date] && args[:end_date]
unless date_params_complete
raise Gitlab::Graphql::Errors::ArgumentError, "Both start_date and end_date must be present."
end
end
def transform_args(args) def transform_args(args)
transformed = args.dup transformed = args.dup
transformed[:group_id] = group.id transformed[:group_id] = group.id
......
---
title: Allow to filter epics by timeframe or state using GraphQL
merge_request: 15110
author:
type: added
...@@ -60,6 +60,48 @@ describe Resolvers::EpicResolver do ...@@ -60,6 +60,48 @@ describe Resolvers::EpicResolver do
end end
end end
context 'within timeframe' do
let!(:epic1) { create(:epic, group: group, state: :closed, start_date: "2019-08-13", end_date: "2019-08-20") }
let!(:epic2) { create(:epic, group: group, state: :closed, start_date: "2019-08-13", end_date: "2019-08-21") }
context 'when start_date and end_date are present' do
it 'returns epics within timeframe' do
epics = resolve_epics(start_date: '2019-08-13', end_date: '2019-08-21')
expect(epics).to match_array([epic1, epic2])
end
end
context 'when only start_date is present' do
it 'returns epics within timeframe' do
expect { resolve_epics(start_date: '2019-08-13') }.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
end
end
context 'when only end_date is present' do
it 'returns epics within timeframe' do
expect { resolve_epics(end_date: '2019-08-13') }.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
end
end
end
context 'with state' do
let!(:epic1) { create(:epic, group: group, state: :opened, start_date: "2019-08-13", end_date: "2019-08-20") }
let!(:epic2) { create(:epic, group: group, state: :closed, start_date: "2019-08-13", end_date: "2019-08-21") }
it 'lists epics with opened state' do
epics = resolve_epics(state: 'opened')
expect(epics).to match_array([epic1])
end
it 'lists epics with closed state' do
epics = resolve_epics(state: 'closed')
expect(epics).to match_array([epic2])
end
end
context 'with subgroups' do context 'with subgroups' do
let(:sub_group) { create(:group, parent: group) } let(:sub_group) { create(:group, parent: group) }
let(:iids) { [epic1, epic2].map(&:iid) } let(:iids) { [epic1, epic2].map(&:iid) }
......
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