diff --git a/src/renderer/types.ts b/src/renderer/types.ts index c407c3f01..fd5fb54ae 100644 --- a/src/renderer/types.ts +++ b/src/renderer/types.ts @@ -293,7 +293,7 @@ export interface GitifyPullRequestReview { export type GitifyDiscussionState = DiscussionStateReason | 'OPEN' | 'ANSWERED'; -export type GitifyPullRequestState = PullRequestState | 'DRAFT'; +export type GitifyPullRequestState = PullRequestState | 'DRAFT' | 'MERGE_QUEUE'; export type GitifyIssueState = IssueState | IssueStateReason; diff --git a/src/renderer/utils/notifications/filters/state.test.ts b/src/renderer/utils/notifications/filters/state.test.ts index 0e2db8750..b2bd2df45 100644 --- a/src/renderer/utils/notifications/filters/state.test.ts +++ b/src/renderer/utils/notifications/filters/state.test.ts @@ -22,6 +22,7 @@ describe('renderer/utils/notifications/filters/state.ts', () => { NOT_PLANNED: 'closed', RESOLVED: 'closed', + MERGE_QUEUE: 'merged', MERGED: 'merged', DRAFT: 'draft', diff --git a/src/renderer/utils/notifications/filters/state.ts b/src/renderer/utils/notifications/filters/state.ts index 2fc5451dc..79fab7e36 100644 --- a/src/renderer/utils/notifications/filters/state.ts +++ b/src/renderer/utils/notifications/filters/state.ts @@ -82,6 +82,7 @@ function mapStateToFilter( case 'NOT_PLANNED': case 'RESOLVED': return 'closed'; + case 'MERGE_QUEUE': case 'MERGED': return 'merged'; case 'DRAFT': diff --git a/src/renderer/utils/notifications/handlers/pullRequest.test.ts b/src/renderer/utils/notifications/handlers/pullRequest.test.ts index d081f0cc3..2670c4683 100644 --- a/src/renderer/utils/notifications/handlers/pullRequest.test.ts +++ b/src/renderer/utils/notifications/handlers/pullRequest.test.ts @@ -122,6 +122,45 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { } as GitifySubject); }); + it('merge queue pull request state', async () => { + const mockPullRequest = mockPullRequestResponseNode({ + state: 'OPEN', + isInMergeQueue: true, + }); + + nock('https://api.github.com') + .post('/graphql') + .reply(200, { + data: { + repository: { + pullRequest: mockPullRequest, + }, + }, + }); + + const result = await pullRequestHandler.enrich( + mockNotification, + mockSettings, + ); + + expect(result).toEqual({ + number: 123, + state: 'MERGE_QUEUE', + user: { + login: mockAuthor.login, + html_url: mockAuthor.html_url, + avatar_url: mockAuthor.avatar_url, + type: mockAuthor.type, + }, + reviews: null, + labels: [], + linkedIssues: [], + comments: 0, + milestone: null, + htmlUrl: 'https://github.com/gitify-app/notifications-test/pulls/123', + } as GitifySubject); + }); + it('merged pull request state', async () => { const mockPullRequest = mockPullRequestResponseNode({ state: 'MERGED', @@ -349,6 +388,7 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { const cases = { CLOSED: 'GitPullRequestClosedIcon', DRAFT: 'GitPullRequestDraftIcon', + MERGE_QUEUE: 'GitMergeQueueIcon', MERGED: 'GitMergeIcon', OPEN: 'GitPullRequestIcon', } satisfies Record; @@ -368,6 +408,7 @@ describe('renderer/utils/notifications/handlers/pullRequest.ts', () => { const cases = { CLOSED: IconColor.RED, DRAFT: IconColor.GRAY, + MERGE_QUEUE: IconColor.YELLOW, MERGED: IconColor.PURPLE, OPEN: IconColor.GREEN, } satisfies Record; @@ -445,6 +486,7 @@ function mockPullRequestResponseNode(mocks: { state: PullRequestState; isDraft?: boolean; merged?: boolean; + isInMergeQueue?: boolean; }): PullRequestResponse { return { __typename: 'PullRequest', @@ -453,7 +495,7 @@ function mockPullRequestResponseNode(mocks: { state: mocks.state, isDraft: mocks.isDraft ?? false, merged: mocks.merged ?? false, - isInMergeQueue: false, + isInMergeQueue: mocks.isInMergeQueue ?? false, url: 'https://github.com/gitify-app/notifications-test/pulls/123', author: mockAuthor, labels: { nodes: [] }, diff --git a/src/renderer/utils/notifications/handlers/pullRequest.ts b/src/renderer/utils/notifications/handlers/pullRequest.ts index d3b35b412..c91c0eb21 100644 --- a/src/renderer/utils/notifications/handlers/pullRequest.ts +++ b/src/renderer/utils/notifications/handlers/pullRequest.ts @@ -3,6 +3,7 @@ import type { FC } from 'react'; import type { OcticonProps } from '@primer/octicons-react'; import { GitMergeIcon, + GitMergeQueueIcon, GitPullRequestClosedIcon, GitPullRequestDraftIcon, GitPullRequestIcon, @@ -22,6 +23,9 @@ import type { FetchPullRequestByNumberQuery } from '../../api/graphql/generated/ import { DefaultHandler, defaultHandler } from './default'; import { getNotificationAuthor } from './utils'; +type PullRequestReviews = + FetchPullRequestByNumberQuery['repository']['pullRequest']['reviews']['nodes']; + class PullRequestHandler extends DefaultHandler { readonly type = 'PullRequest' as const; @@ -35,6 +39,8 @@ class PullRequestHandler extends DefaultHandler { let prState: GitifyPullRequestState = pr.state; if (pr.isDraft) { prState = 'DRAFT'; + } else if (pr.isInMergeQueue) { + prState = 'MERGE_QUEUE'; } const prComment = pr.comments?.nodes[0]; @@ -64,6 +70,8 @@ class PullRequestHandler extends DefaultHandler { return GitPullRequestDraftIcon; case 'CLOSED': return GitPullRequestClosedIcon; + case 'MERGE_QUEUE': + return GitMergeQueueIcon; case 'MERGED': return GitMergeIcon; default: @@ -77,6 +85,8 @@ class PullRequestHandler extends DefaultHandler { return IconColor.GREEN; case 'CLOSED': return IconColor.RED; + case 'MERGE_QUEUE': + return IconColor.YELLOW; case 'MERGED': return IconColor.PURPLE; default: @@ -94,7 +104,7 @@ class PullRequestHandler extends DefaultHandler { export const pullRequestHandler = new PullRequestHandler(); export function getLatestReviewForReviewers( - reviews: FetchPullRequestByNumberQuery['repository']['pullRequest']['reviews']['nodes'], + reviews: PullRequestReviews, ): GitifyPullRequestReview[] { if (!reviews.length) { return null;