This commit is contained in:
Michael Shick 2022-11-04 18:21:20 -04:00
parent 94fd7ef52f
commit 80f4918ea8
No known key found for this signature in database
GPG key ID: ADF5BC9704BB4A61
5 changed files with 2381 additions and 4681 deletions

View file

@ -1,9 +1,11 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import { WebhookPayload } from '@actions/github/lib/interfaces'
import * as fs from 'fs'
import nock from 'nock'
import * as path from 'path'
import { rest } from 'msw'
import { setupServer } from 'msw/node'
import * as fs from 'node:fs'
import * as path from 'node:path'
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
import run from '../src/main'
import apiResponse from './sample-pulls-api-response.json'
@ -19,8 +21,6 @@ const multilineMessageWindows = fs
.readFileSync(path.resolve(__dirname, './message-windows.txt'))
.toString()
let issueNumber = 1
const inputs = {
message: '',
'repo-token': '',
@ -28,10 +28,71 @@ const inputs = {
'allow-repeats': 'false',
}
beforeEach(() => {
issueNumber = 1
jest.resetModules()
jest.spyOn(core, 'getInput').mockImplementation((name: string): string => {
let issueNumber = 1
let getCommitPullsResponse
let getIssueCommentsResponse
vi.mock('@actions/core')
export const handlers = [
rest.post(
`https://api.github.com/repos/${repoFullName}/issues/:issueNumber/comments`,
(req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
url: 'https://github.com/#example',
}),
)
},
),
rest.get(
`https://api.github.com/repos/${repoFullName}/issues/:issueNumber/comments`,
(req, res, ctx) => {
return res(ctx.status(200), ctx.json(getIssueCommentsResponse))
},
),
rest.get(
`https://api.github.com/repos/${repoFullName}/commits/:commitSha/pulls`,
(req, res, ctx) => {
return res(ctx.status(200), ctx.json(getCommitPullsResponse))
},
),
]
const server = setupServer(...handlers)
describe('add-pr-comment action', () => {
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterAll(() => server.close())
beforeEach(() => {
issueNumber = 1
vi.resetModules()
github.context.sha = commitSha
// https://developer.github.com/webhooks/event-payloads/#issues
github.context.payload = {
pull_request: {
number: issueNumber,
},
repository: {
full_name: repoFullName,
name: 'bar',
owner: {
login: 'bar',
},
},
} as WebhookPayload
})
afterEach(() => {
vi.clearAllMocks()
server.resetHandlers()
})
vi.mocked(core.getInput).mockImplementation((name: string) => {
switch (name) {
case 'message':
return inputs.message
@ -44,56 +105,13 @@ beforeEach(() => {
}
})
github.context.sha = commitSha
// https://developer.github.com/webhooks/event-payloads/#issues
github.context.payload = {
pull_request: {
number: issueNumber,
},
repository: {
full_name: repoFullName,
name: 'bar',
owner: {
login: 'bar',
},
},
} as WebhookPayload
})
afterEach(() => {
jest.restoreAllMocks()
expect(nock.pendingMocks()).toEqual([])
nock.isDone()
nock.cleanAll()
})
describe('add-pr-comment action', () => {
it('creates a comment', async () => {
inputs.message = simpleMessage
inputs['repo-token'] = repoToken
inputs['allow-repeats'] = 'true'
const originalSetOutput = core.setOutput
jest.spyOn(core, 'setOutput').mockImplementation((key: string, value: string): void => {
if (key === 'comment-created') {
expect(value).toBe('true')
}
return originalSetOutput(key, value)
})
nock('https://api.github.com')
.post(
`/repos/${repoFullName}/issues/${issueNumber}/comments`,
({ body }) => body === simpleMessage,
)
.reply(200, {
url: 'https://github.com/#example',
})
await expect(run()).resolves.not.toThrow()
expect(core.setOutput).toHaveBeenCalledWith('comment-created', 'true')
})
it('creates a comment in an existing PR', async () => {
@ -110,31 +128,12 @@ describe('add-pr-comment action', () => {
},
} as WebhookPayload
const originalSetOutput = core.setOutput
jest.spyOn(core, 'setOutput').mockImplementation((key: string, value: string): void => {
if (key === 'comment-created') {
expect(value).toBe('true')
}
return originalSetOutput(key, value)
})
issueNumber = apiResponse.result[0].number
nock('https://api.github.com')
.get(`/repos/${repoFullName}/commits/${commitSha}/pulls`)
.reply(200, apiResponse.result)
nock('https://api.github.com')
.post(
`/repos/${repoFullName}/issues/${issueNumber}/comments`,
({ body }) => body === simpleMessage,
)
.reply(200, {
url: 'https://github.com/#example',
})
getCommitPullsResponse = apiResponse.result
await expect(run()).resolves.not.toThrow()
expect(core.setOutput).toHaveBeenCalledWith('comment-created', 'true')
})
it('safely exits when no issue can be found [using GITHUB_TOKEN in env]', async () => {
@ -150,21 +149,10 @@ describe('add-pr-comment action', () => {
},
} as WebhookPayload
const originalSetOutput = core.setOutput
jest.spyOn(core, 'setOutput').mockImplementation((key: string, value: string): void => {
if (key === 'comment-created') {
expect(value).toBe('false')
}
return originalSetOutput(key, value)
})
nock('https://api.github.com')
.get(`/repos/${repoFullName}/commits/${commitSha}/pulls`)
.reply(200, [])
getCommitPullsResponse = []
await run()
expect(core.setOutput).toHaveBeenCalledWith('comment-created', 'false')
})
it('identifies repeat messages and does not create a comment [user login provided]', async () => {
@ -173,16 +161,6 @@ describe('add-pr-comment action', () => {
inputs['repo-token-user-login'] = userLogin
inputs['allow-repeats'] = 'false'
const originalSetOutput = core.setOutput
jest.spyOn(core, 'setOutput').mockImplementation((key: string, value: string): void => {
if (key === 'comment-created') {
expect(value).toBe('false')
}
return originalSetOutput(key, value)
})
const replyBody = [
{
body: simpleMessage,
@ -192,11 +170,11 @@ describe('add-pr-comment action', () => {
},
]
nock('https://api.github.com')
.get(`/repos/${repoFullName}/issues/1/comments`)
.reply(200, replyBody)
getIssueCommentsResponse = replyBody
await run()
expect(core.setOutput).toHaveBeenCalledWith('comment-created', 'false')
})
it('matches multiline messages with windows line feeds against api responses with unix linefeeds [no user login provided]', async () => {
@ -204,16 +182,6 @@ describe('add-pr-comment action', () => {
inputs['repo-token'] = repoToken
inputs['allow-repeats'] = 'false'
const originalSetOutput = core.setOutput
jest.spyOn(core, 'setOutput').mockImplementation((key: string, value: string): void => {
if (key === 'comment-created') {
expect(value).toBe('false')
}
return originalSetOutput(key, value)
})
const replyBody = [
{
body: multilineMessage,
@ -223,10 +191,9 @@ describe('add-pr-comment action', () => {
},
]
nock('https://api.github.com')
.get(`/repos/${repoFullName}/issues/1/comments`)
.reply(200, replyBody)
getIssueCommentsResponse = replyBody
await run()
expect(core.setOutput).toHaveBeenCalledWith('comment-created', 'false')
})
})

View file

@ -1,11 +0,0 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
testRunner: 'jest-circus/runner',
transform: {
'^.+\\.ts$': 'ts-jest',
},
verbose: true,
}

6845
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -26,7 +26,8 @@
"clean": "rm -rf node_modules dist package-lock.json __tests__/runner/**/*",
"lint": "eslint src/**/*.ts",
"package": "ncc build --source-map --license licenses.txt",
"test": "jest"
"test": "vitest run",
"watch": "vitest"
},
"prettier": {
"bracketSpacing": true,
@ -107,7 +108,6 @@
},
"devDependencies": {
"@octokit/types": "^8.0.0",
"@types/jest": "^29.2.2",
"@types/node": "^18.11.9",
"@typescript-eslint/eslint-plugin": "^5.42.0",
"@typescript-eslint/parser": "^5.42.0",
@ -119,12 +119,11 @@
"eslint-plugin-json-format": "^2.0.1",
"eslint-plugin-mdx": "^2.0.5",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.2.2",
"jest-circus": "^29.2.2",
"msw": "^0.47.4",
"nock": "^13.2.9",
"prettier": "^2.7.1",
"ts-jest": "^29.0.3",
"typescript": "^4.8.4"
"typescript": "^4.8.4",
"vitest": "^0.24.5"
},
"engines": {
"node": "^14.15.0 || ^16.13.0 || ^18.0.0"

View file

@ -200,6 +200,8 @@ const run = async (): Promise<void> => {
} catch (err) {
if (err instanceof Error) {
core.setFailed(err.message)
} else {
core.setFailed('unknown failure')
}
}
}