Commit 28282f0e authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'alexives/7783/filter_epics_by_reaction_emoji_in_api' into 'master'

Add api to lookup epics by reaction emoji

See merge request gitlab-org/gitlab!31479
parents 3a90c979 de161e6a
...@@ -67,6 +67,7 @@ GET /groups/:id/epics?state=opened ...@@ -67,6 +67,7 @@ GET /groups/:id/epics?state=opened
| `updated_before` | datetime | no | Return epics updated on or before the given time | | `updated_before` | datetime | no | Return epics updated on or before the given time |
| `include_ancestor_groups` | boolean | no | Include epics from the requested group's ancestors. Default is `false` | | `include_ancestor_groups` | boolean | no | Include epics from the requested group's ancestors. Default is `false` |
| `include_descendant_groups` | boolean | no | Include epics from the requested group's descendants. Default is `true` | | `include_descendant_groups` | boolean | no | Include epics from the requested group's descendants. Default is `true` |
| `my_reaction_emoji` | string | no | Return epics reacted by the authenticated user by the given emoji. `None` returns epics not given a reaction. `Any` returns epics given at least one reaction. Introduced in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31479)|
```shell ```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics
......
...@@ -34,6 +34,7 @@ class EpicsFinder < IssuableFinder ...@@ -34,6 +34,7 @@ class EpicsFinder < IssuableFinder
start_date start_date
end_date end_date
search search
my_reaction_emoji
] ]
end end
...@@ -63,6 +64,7 @@ class EpicsFinder < IssuableFinder ...@@ -63,6 +64,7 @@ class EpicsFinder < IssuableFinder
items = by_parent(items) items = by_parent(items)
items = by_iids(items) items = by_iids(items)
items = starts_with_iid(items) items = starts_with_iid(items)
items = by_my_reaction_emoji(items)
# This has to be last as we use a CTE as an optimization fence # This has to be last as we use a CTE as an optimization fence
# for counts by passing the force_cte param and enabling the # for counts by passing the force_cte param and enabling the
......
---
title: Add my_reaction_emoji param to epics list api
merge_request: 31479
author:
type: added
...@@ -37,6 +37,7 @@ module API ...@@ -37,6 +37,7 @@ module API
optional :updated_before, type: DateTime, desc: 'Return epics updated before the specified time' optional :updated_before, type: DateTime, desc: 'Return epics updated before the specified time'
optional :include_ancestor_groups, type: Boolean, default: false, desc: 'Include epics from ancestor groups' optional :include_ancestor_groups, type: Boolean, default: false, desc: 'Include epics from ancestor groups'
optional :include_descendant_groups, type: Boolean, default: true, desc: 'Include epics from descendant groups' optional :include_descendant_groups, type: Boolean, default: true, desc: 'Include epics from descendant groups'
optional :my_reaction_emoji, type: String, desc: 'Return epics reacted by the authenticated user by the given emoji'
use :pagination use :pagination
end end
get ':id/(-/)epics' do get ':id/(-/)epics' do
......
...@@ -3,14 +3,14 @@ ...@@ -3,14 +3,14 @@
require 'spec_helper' require 'spec_helper'
describe EpicsFinder do describe EpicsFinder do
let(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:search_user) { create(:user) } let_it_be(:search_user) { create(:user) }
let(:group) { create(:group, :private) } let_it_be(:group) { create(:group, :private) }
let(:another_group) { create(:group) } let_it_be(:another_group) { create(:group) }
let!(:epic1) { create(:epic, :opened, group: group, title: 'This is awesome epic', created_at: 1.week.ago) } let_it_be(:epic1) { create(:epic, :opened, group: group, title: 'This is awesome epic', created_at: 1.week.ago) }
let!(:epic2) { create(:epic, :opened, group: group, created_at: 4.days.ago, author: user, start_date: 2.days.ago, end_date: 3.days.from_now) } let_it_be(:epic2) { create(:epic, :opened, group: group, created_at: 4.days.ago, author: user, start_date: 2.days.ago, end_date: 3.days.from_now) }
let!(:epic3) { create(:epic, :closed, group: group, description: 'not so awesome', start_date: 5.days.ago, end_date: 3.days.ago) } let_it_be(:epic3) { create(:epic, :closed, group: group, description: 'not so awesome', start_date: 5.days.ago, end_date: 3.days.ago) }
let!(:epic4) { create(:epic, :closed, group: another_group) } let_it_be(:epic4) { create(:epic, :closed, group: another_group) }
describe '#execute' do describe '#execute' do
def epics(params = {}) def epics(params = {})
...@@ -91,6 +91,15 @@ describe EpicsFinder do ...@@ -91,6 +91,15 @@ describe EpicsFinder do
end end
end end
context 'by user reaction emoji' do
it 'returns epics reacted to by user' do
create(:award_emoji, name: 'thumbsup', awardable: epic1, user: search_user )
create(:award_emoji, name: 'star', awardable: epic3, user: search_user )
expect(epics(my_reaction_emoji: 'star')).to contain_exactly(epic3)
end
end
context 'by author' do context 'by author' do
it 'returns all epics authored by the given user' do it 'returns all epics authored by the given user' do
expect(epics(author_id: user.id)).to contain_exactly(epic2) expect(epics(author_id: user.id)).to contain_exactly(epic2)
...@@ -98,8 +107,8 @@ describe EpicsFinder do ...@@ -98,8 +107,8 @@ describe EpicsFinder do
end end
context 'by label' do context 'by label' do
let(:label) { create(:label) } let_it_be(:label) { create(:label) }
let!(:labeled_epic) { create(:labeled_epic, group: group, labels: [label]) } let_it_be(:labeled_epic) { create(:labeled_epic, group: group, labels: [label]) }
it 'returns all epics with given label' do it 'returns all epics with given label' do
expect(epics(label_name: label.title)).to contain_exactly(labeled_epic) expect(epics(label_name: label.title)).to contain_exactly(labeled_epic)
...@@ -113,10 +122,10 @@ describe EpicsFinder do ...@@ -113,10 +122,10 @@ describe EpicsFinder do
end end
context 'when subgroups are supported' do context 'when subgroups are supported' do
let(:subgroup) { create(:group, :private, parent: group) } let_it_be(:subgroup) { create(:group, :private, parent: group) }
let(:subgroup2) { create(:group, :private, parent: subgroup) } let_it_be(:subgroup2) { create(:group, :private, parent: subgroup) }
let!(:subgroup_epic) { create(:epic, group: subgroup) } let_it_be(:subgroup_epic) { create(:epic, group: subgroup) }
let!(:subgroup2_epic) { create(:epic, group: subgroup2) } let_it_be(:subgroup2_epic) { create(:epic, group: subgroup2) }
it 'returns all epics that belong to the given group and its subgroups' do it 'returns all epics that belong to the given group and its subgroups' do
expect(epics).to contain_exactly(epic1, epic2, epic3, subgroup_epic, subgroup2_epic) expect(epics).to contain_exactly(epic1, epic2, epic3, subgroup_epic, subgroup2_epic)
...@@ -220,8 +229,8 @@ describe EpicsFinder do ...@@ -220,8 +229,8 @@ describe EpicsFinder do
end end
context 'by iids' do context 'by iids' do
let(:subgroup) { create(:group, :private, parent: group) } let_it_be(:subgroup) { create(:group, :private, parent: group) }
let!(:subepic1) { create(:epic, group: subgroup, iid: epic1.iid) } let_it_be(:subepic1) { create(:epic, group: subgroup, iid: epic1.iid) }
it 'returns the specified epics' do it 'returns the specified epics' do
params = { iids: [epic1.iid, epic2.iid] } params = { iids: [epic1.iid, epic2.iid] }
...@@ -237,10 +246,10 @@ describe EpicsFinder do ...@@ -237,10 +246,10 @@ describe EpicsFinder do
end end
context 'when using iid starts with query' do context 'when using iid starts with query' do
let!(:epic1) { create(:epic, :opened, group: group, iid: '11') } let_it_be(:epic1) { create(:epic, :opened, group: group, iid: '11') }
let!(:epic2) { create(:epic, :opened, group: group, iid: '1112') } let_it_be(:epic2) { create(:epic, :opened, group: group, iid: '1112') }
let!(:epic3) { create(:epic, :closed, group: group, iid: '9978') } let_it_be(:epic3) { create(:epic, :closed, group: group, iid: '9978') }
let!(:epic4) { create(:epic, :closed, group: another_group, iid: '111') } let_it_be(:epic4) { create(:epic, :closed, group: another_group, iid: '111') }
it 'returns the expected epics if just the first two numbers are given' do it 'returns the expected epics if just the first two numbers are given' do
params = { iid_starts_with: '11' } params = { iid_starts_with: '11' }
...@@ -277,7 +286,7 @@ describe EpicsFinder do ...@@ -277,7 +286,7 @@ describe EpicsFinder do
context 'and two labels more search string are present' do context 'and two labels more search string are present' do
let_it_be(:label1) { create(:label) } let_it_be(:label1) { create(:label) }
let_it_be(:label2) { create(:label) } let_it_be(:label2) { create(:label) }
let!(:labeled_epic) { create(:labeled_epic, group: group, title: 'filtered epic', labels: [label1, label2]) } let_it_be(:labeled_epic) { create(:labeled_epic, group: group, title: 'filtered epic', labels: [label1, label2]) }
it 'returns correct epics' do it 'returns correct epics' do
filtered_epics = filtered_epics =
...@@ -310,10 +319,10 @@ describe EpicsFinder do ...@@ -310,10 +319,10 @@ describe EpicsFinder do
end end
describe '#row_count' do describe '#row_count' do
let(:label) { create(:label) } let_it_be(:label) { create(:label) }
let(:label2) { create(:label) } let_it_be(:label2) { create(:label) }
let!(:labeled_epic) { create(:labeled_epic, group: group, labels: [label]) } let_it_be(:labeled_epic) { create(:labeled_epic, group: group, labels: [label]) }
let!(:labeled_epic2) { create(:labeled_epic, group: group, labels: [label, label2]) } let_it_be(:labeled_epic2) { create(:labeled_epic, group: group, labels: [label, label2]) }
before do before do
group.add_developer(search_user) group.add_developer(search_user)
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
require 'spec_helper' require 'spec_helper'
describe API::Epics do describe API::Epics do
let(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:group) { create(:group) } let(:group) { create(:group) }
let(:project) { create(:project, :public, group: group) } let(:project) { create(:project, :public, group: group) }
let(:label) { create(:label) } let_it_be(:label) { create(:label) }
let!(:epic) { create(:labeled_epic, group: group, labels: [label]) } let!(:epic) { create(:labeled_epic, group: group, labels: [label]) }
let(:params) { nil } let(:params) { nil }
...@@ -178,6 +178,15 @@ describe API::Epics do ...@@ -178,6 +178,15 @@ describe API::Epics do
expect_paginated_array_response([epic2.id]) expect_paginated_array_response([epic2.id])
end end
it 'returns epics reacted to by current user' do
create(:award_emoji, awardable: epic, user: user, name: 'star')
create(:award_emoji, awardable: epic2, user: user2, name: 'star')
get api(url, user), params: { my_reaction_emoji: 'Any', scope: 'all' }
expect_paginated_array_response([epic.id])
end
it 'returns epics matching given search string for title' do it 'returns epics matching given search string for title' do
get api(url), params: { search: epic2.title } get api(url), params: { search: epic2.title }
......
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