diff --git a/__tests__/add-to-project.test.ts b/__tests__/add-to-project.test.ts index 3733647..8f0f8ed 100644 --- a/__tests__/add-to-project.test.ts +++ b/__tests__/add-to-project.test.ts @@ -1,6 +1,6 @@ import * as core from '@actions/core' import * as github from '@actions/github' -import {addToProject} from '../src/add-to-project' +import {addToProject, mustGetOwnerTypeQuery} from '../src/add-to-project' describe('addToProject', () => { let outputs: Record @@ -94,6 +94,49 @@ describe('addToProject', () => { expect(outputs.itemId).toEqual('project-next-item-id') }) + test('adds matching pull-requests with a label filter without label-operator', async () => { + mockGetInput({ + 'project-url': 'https://github.com/orgs/github/projects/1', + 'github-token': 'gh_token', + labeled: 'bug, new' + }) + + github.context.payload = { + // eslint-disable-next-line camelcase + pull_request: { + number: 1, + labels: [{name: 'bug'}] + } + } + + mockGraphQL( + { + test: /getProject/, + return: { + organization: { + projectNext: { + id: 'project-next-id' + } + } + } + }, + { + test: /addProjectNextItem/, + return: { + addProjectNextItem: { + projectNextItem: { + id: 'project-next-item-id' + } + } + } + } + ) + + await addToProject() + + expect(outputs.itemId).toEqual('project-next-item-id') + }) + test('does not add un-matching issues with a label filter without label-operator', async () => { mockGetInput({ 'project-url': 'https://github.com/orgs/github/projects/1', @@ -230,7 +273,7 @@ describe('addToProject', () => { mockGetInput({ 'project-url': 'https://github.com/orgs/github/projects/1', 'github-token': 'gh_token', - labeled: 'accessibility,backend,bug' + labeled: 'accessibility, backend, bug' }) github.context.payload = { @@ -249,6 +292,53 @@ describe('addToProject', () => { expect(gqlMock).not.toHaveBeenCalled() }) + test('handles spaces and extra commas gracefully in label filter input', async () => { + mockGetInput({ + 'project-url': 'https://github.com/orgs/github/projects/1', + 'github-token': 'gh_token', + labeled: 'accessibility , backend ,, . , bug' + }) + + github.context.payload = { + issue: { + number: 1, + labels: [{name: 'accessibility'}, {name: 'backend'}, {name: 'bug'}], + 'label-operator': 'AND' + } + } + + const gqlMock = mockGraphQL( + { + test: /getProject/, + return: { + organization: { + projectNext: { + id: 'project-next-id' + } + } + } + }, + { + test: /addProjectNextItem/, + return: { + addProjectNextItem: { + projectNextItem: { + id: 'project-next-item-id' + } + } + } + } + ) + + const infoSpy = jest.spyOn(core, 'info') + + await addToProject() + + expect(gqlMock).toHaveBeenCalled() + expect(infoSpy).not.toHaveBeenCalled() + expect(outputs.itemId).toEqual('project-next-item-id') + }) + test(`throws an error when url isn't a valid project url`, async () => { mockGetInput({ 'project-url': 'https://github.com/orgs/github/repositories', @@ -384,6 +474,26 @@ describe('addToProject', () => { }) }) +describe('mustGetOwnerTypeQuery', () => { + test('returns organization for orgs ownerType', async () => { + const ownerTypeQuery = mustGetOwnerTypeQuery('orgs') + + expect(ownerTypeQuery).toEqual('organization') + }) + + test('returns user for users ownerType', async () => { + const ownerTypeQuery = mustGetOwnerTypeQuery('users') + + expect(ownerTypeQuery).toEqual('user') + }) + + test('throws an error when an unsupported ownerType is set', async () => { + expect(() => { + mustGetOwnerTypeQuery('unknown') + }).toThrow(`Unsupported ownerType: unknown. Must be one of 'orgs' or 'users'`) + }) +}) + function mockGetInput(mocks: Record): jest.SpyInstance { const mock = (key: string) => mocks[key] ?? '' return jest.spyOn(core, 'getInput').mockImplementation(mock) diff --git a/src/add-to-project.ts b/src/add-to-project.ts index b0ae6c7..19c6715 100644 --- a/src/add-to-project.ts +++ b/src/add-to-project.ts @@ -115,7 +115,7 @@ export async function addToProject(): Promise { core.setOutput('itemId', addResp.addProjectNextItem.projectNextItem.id) } -function mustGetOwnerTypeQuery(ownerType?: string): 'organization' | 'user' { +export function mustGetOwnerTypeQuery(ownerType?: string): 'organization' | 'user' { const ownerTypeQuery = ownerType === 'orgs' ? 'organization' : ownerType === 'users' ? 'user' : null if (!ownerTypeQuery) {