Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hawk.api",
"version": "1.4.9",
"version": "1.4.10",
"main": "index.ts",
"license": "BUSL-1.1",
"scripts": {
Expand Down
10 changes: 9 additions & 1 deletion src/models/eventsFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@
sort = 'BY_DATE',
filters = {},
Comment thread
Dobrunia marked this conversation as resolved.
search = '',
release
release,
assignee
) {
if (typeof search !== 'string') {
throw new Error('Search parameter must be a string');
Expand Down Expand Up @@ -334,10 +335,12 @@
}
: {};

const markFilters = ['resolved', 'starred', 'ignored'];
const matchFilter = filters
? Object.fromEntries(
Object
.entries(filters)
Comment thread
Dobrunia marked this conversation as resolved.
.filter(([mark]) => markFilters.includes(mark))

Check failure on line 343 in src/models/eventsFactory.js

View workflow job for this annotation

GitHub Actions / ESlint

A space is required before ']'

Check failure on line 343 in src/models/eventsFactory.js

View workflow job for this annotation

GitHub Actions / ESlint

A space is required after '['
.map(([mark, exists]) => [`event.marks.${mark}`, { $exists: exists } ])
)
: {};
Expand All @@ -361,6 +364,10 @@
}
: {};

const assigneeFilter = assignee
? { 'event.assignee': String(assignee) }
: {};

pipeline.push(
/**
* Left outer join original event on groupHash field
Expand Down Expand Up @@ -398,6 +405,7 @@
...matchFilter,
...searchFilter,
...releaseFilter,
...assigneeFilter,
},
},
{ $limit: limit + 1 },
Expand Down
12 changes: 10 additions & 2 deletions src/resolvers/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ module.exports = {
*
* @return {Promise<RecentEventSchema[]>}
*/
async dailyEventsPortion(project, { limit, nextCursor, sort, filters, search, release }, context) {
async dailyEventsPortion(project, { limit, nextCursor, sort, filters, search, release, assignee }, context) {
Comment thread
Dobrunia marked this conversation as resolved.
if (search) {
if (search.length > MAX_SEARCH_QUERY_LENGTH) {
search = search.slice(0, MAX_SEARCH_QUERY_LENGTH);
Expand All @@ -592,7 +592,15 @@ module.exports = {

const factory = getEventsFactory(context, project._id);

const dailyEventsPortion = await factory.findDailyEventsPortion(limit, nextCursor, sort, filters, search, release);
const dailyEventsPortion = await factory.findDailyEventsPortion(
limit,
nextCursor,
sort,
filters,
search,
release,
assignee
);

return dailyEventsPortion;
},
Expand Down
9 changes: 9 additions & 0 deletions src/typeDefs/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ input EventsFiltersInput {
If True, includes events with ignored mark to the output
"""
ignored: Boolean
"""
Includes only events assigned to passed user id
"""
assignee: ID
Comment thread
Dobrunia marked this conversation as resolved.
Outdated
}

"""
Expand Down Expand Up @@ -347,6 +351,11 @@ type Project {
Release label to filter events by payload.release
"""
release: String

"""
User id to filter events by assignee
"""
assignee: ID
): DailyEventsPortion

"""
Expand Down
89 changes: 89 additions & 0 deletions test/resolvers/project-daily-events-portion.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import '../../src/env-test';

jest.mock('../../src/integrations/github/service', () => require('../__mocks__/github-service'));

jest.mock('../../src/resolvers/helpers/eventsFactory', () => ({
__esModule: true,
default: jest.fn(),
}));

// @ts-expect-error - CommonJS module, TypeScript can't infer types properly
import projectResolverModule from '../../src/resolvers/project';
import getEventsFactory from '../../src/resolvers/helpers/eventsFactory';

const projectResolver = projectResolverModule as {
Project: {
dailyEventsPortion: (...args: unknown[]) => Promise<unknown>;
};
};

describe('Project resolver dailyEventsPortion', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should pass assignee filter to events factory', async () => {
const findDailyEventsPortion = jest.fn().mockResolvedValue({
nextCursor: null,
dailyEvents: [],
});
(getEventsFactory as unknown as jest.Mock).mockReturnValue({
findDailyEventsPortion,
});

const project = { _id: 'project-1' };
const args = {
limit: 50,
nextCursor: null,
sort: 'BY_DATE',
filters: { ignored: true },
search: 'TypeError',
release: '1.0.0',
assignee: 'user-123',
};

await projectResolver.Project.dailyEventsPortion(project, args, {});

expect(findDailyEventsPortion).toHaveBeenCalledWith(
50,
null,
'BY_DATE',
{ ignored: true },
'TypeError',
'1.0.0',
'user-123'
);
});

it('should keep old call shape when assignee is not provided', async () => {
const findDailyEventsPortion = jest.fn().mockResolvedValue({
nextCursor: null,
dailyEvents: [],
});
Comment thread
Dobrunia marked this conversation as resolved.
Outdated
(getEventsFactory as unknown as jest.Mock).mockReturnValue({
findDailyEventsPortion,
});

const project = { _id: 'project-1' };
const args = {
limit: 10,
nextCursor: null,
sort: 'BY_DATE',
filters: {},
search: '',
release: undefined,
};

await projectResolver.Project.dailyEventsPortion(project, args, {});

expect(findDailyEventsPortion).toHaveBeenCalledWith(
10,
null,
'BY_DATE',
{},
'',
undefined,
undefined
);
});
});
Loading