Skip to content

Commit

Permalink
Add a unit test for the action entry point
Browse files Browse the repository at this point in the history
  • Loading branch information
Barry Gordon committed Aug 25, 2021
1 parent 34e6533 commit f5b8139
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 8 deletions.
21 changes: 21 additions & 0 deletions __fixtures__/events/default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"inputs": {
"jobID": "1",
"jobToken": "xxx",
"credentialsToken": "yyy",
"dependabotAPIURL": "http://localhost:9000"
},
"ref": "main",
"repository": {
"owner": {
"login": "dependabot"
},
"name": "dependabot-core"
},
"sender": {
"type": "User"
},
"installation": null,
"organization": null,
"workflow": "--workflow-yaml-goes-here--"
}
12 changes: 11 additions & 1 deletion __tests__/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const removeDanglingUpdaterContainers = async (): Promise<void> => {
await docker.pruneContainers()
}

export const runFakeDependabotApi = async (port: number): Promise<Function> => {
export const runFakeDependabotApi = async (port = 9000): Promise<Function> => {
const server = spawn('node', [
`${path.join(__dirname, 'server/server.js')}`,
`${port}`
Expand All @@ -44,3 +44,13 @@ export const runFakeDependabotApi = async (port: number): Promise<Function> => {
server.kill()
}
}

export const eventFixturePath = (fixtureName: string): string => {
return path.join(
__dirname,
'..',
'__fixtures__',
'events',
`${fixtureName}.json`
)
}
158 changes: 156 additions & 2 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,156 @@
// shows how the runner will run a javascript action with env / stdout protocol
test('test runs', () => {})
import * as core from '@actions/core'
import {Context} from '@actions/github/lib/context'
import {APIClient} from '../src/api-client'
import {Updater} from '../src/updater'
import * as inputs from '../src/inputs'
import {run} from '../src/main'

import {eventFixturePath} from './helpers'

// We do not need to build actual containers or run updates for this test.
jest.mock('../src/api-client')
jest.mock('../src/image-service')
jest.mock('../src/updater')

describe('run', () => {
let context: Context

beforeEach(async () => {
jest.spyOn(core, 'info').mockImplementation(jest.fn())
jest.spyOn(core, 'setFailed').mockImplementation(jest.fn())
})

afterEach(async () => {
jest.clearAllMocks() // Reset any mocked classes
})

describe('when the run follows the happy path', () => {
beforeAll(() => {
process.env.GITHUB_EVENT_PATH = eventFixturePath('default')
process.env.GITHUB_EVENT_NAME = 'workflow_dispatch'
context = new Context()
})

test('it signs off at completion without any errors', async () => {
await run(context)

expect(core.setFailed).not.toHaveBeenCalled()
expect(core.info).toHaveBeenCalledWith(
expect.stringContaining('🤖 ~fin~')
)
})
})

describe('when the action is triggered on an unsupported event', () => {
beforeAll(() => {
process.env.GITHUB_EVENT_PATH = eventFixturePath('default')
process.env.GITHUB_EVENT_NAME = 'issue_created'
context = new Context()
})

test('it explains the event is unsupported without logging to dependabot-api', async () => {
await run(context)

expect(core.setFailed).not.toHaveBeenCalled()
expect(core.info).toHaveBeenCalledWith(
expect.stringContaining(
"Dependabot Updater Action does not support 'issue_created' events."
)
)
})
})

describe('when there is an error retrieving job parameters', () => {
beforeEach(() => {
jest.spyOn(inputs, 'getJobParameters').mockImplementationOnce(
jest.fn(() => {
throw new Error('unexpected error retrieving job params')
})
)

process.env.GITHUB_EVENT_PATH = eventFixturePath('default')
process.env.GITHUB_EVENT_NAME = 'workflow_dispatch'
context = new Context()
})

test('it relays an error to dependabot-api and marks the job as processed', async () => {
await run(context)

expect(core.setFailed).toHaveBeenCalledWith(
expect.stringContaining('unexpected error retrieving job params')
)
})
})

describe('when there is an error retrieving job details from DependabotAPI', () => {
beforeEach(() => {
jest
.spyOn(APIClient.prototype, 'getJobDetails')
.mockImplementationOnce(
jest.fn(async () =>
Promise.reject(new Error('error getting job details'))
)
)

process.env.GITHUB_EVENT_PATH = eventFixturePath('default')
process.env.GITHUB_EVENT_NAME = 'workflow_dispatch'
context = new Context()
})

test('it relays an error to dependabot-api and marks the job as processed', async () => {
await run(context)

expect(core.setFailed).toHaveBeenCalledWith(
expect.stringContaining('error getting job details')
)
})
})

describe('when there is an error retrieving job credentials from DependabotAPI', () => {
beforeEach(() => {
jest
.spyOn(APIClient.prototype, 'getCredentials')
.mockImplementationOnce(
jest.fn(async () =>
Promise.reject(new Error('error getting credentials'))
)
)

process.env.GITHUB_EVENT_PATH = eventFixturePath('default')
process.env.GITHUB_EVENT_NAME = 'workflow_dispatch'
context = new Context()
})

test('it relays an error to dependabot-api and marks the job as processed', async () => {
await run(context)

expect(core.setFailed).toHaveBeenCalledWith(
expect.stringContaining('error getting credentials')
)
})
})

describe('when there is an error running the update', () => {
beforeAll(() => {
jest
.spyOn(Updater.prototype, 'runUpdater')
.mockImplementationOnce(
jest.fn(async () =>
Promise.reject(new Error('error running the update'))
)
)

process.env.GITHUB_EVENT_PATH = eventFixturePath('default')
process.env.GITHUB_EVENT_NAME = 'workflow_dispatch'
context = new Context()
})

test('it relays an error to dependabot-api and marks the job as processed', async () => {
await run(context)

expect(core.setFailed).toHaveBeenCalledWith(
expect.stringContaining('error running the update')
)
})
})
})
12 changes: 7 additions & 5 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import {Context} from '@actions/github/lib/context'
import {getJobParameters} from './inputs'
import {ImageService} from './image-service'
import {Updater} from './updater'
Expand All @@ -11,15 +12,15 @@ export const UPDATER_IMAGE_NAME =
export const PROXY_IMAGE_NAME =
'docker.pkg.github.com/github/dependabot-update-job-proxy:latest'

async function run(): Promise<void> {
export async function run(context: Context): Promise<void> {
try {
// Decode JobParameters:
const params = getJobParameters(github.context)
const params = getJobParameters(context)
if (params === null) {
return // No parameters, nothing to do
}

core.info(JSON.stringify(params))
core.debug(JSON.stringify(params))

core.setSecret(params.jobToken)
core.setSecret(params.credentialsToken)
Expand All @@ -39,9 +40,10 @@ async function run(): Promise<void> {
await ImageService.pull(PROXY_IMAGE_NAME)

await updater.runUpdater()
core.info('🤖 ~fin~')
} catch (error) {
core.setFailed(error.message)
core.setFailed(error)
}
}

run()
run(github.context)

0 comments on commit f5b8139

Please sign in to comment.