Skip to content

Commit

Permalink
Add release functions tests (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucacome committed Mar 26, 2023
1 parent 126f368 commit d7e0d0e
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 8 deletions.
41 changes: 41 additions & 0 deletions __mocks__/@actions/github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const mockApi = {
rest: {
issues: {
addLabels: jest.fn(),
removeLabel: jest.fn(),
},
pulls: {
get: jest.fn().mockResolvedValue({}),
listFiles: {
endpoint: {
merge: jest.fn().mockReturnValue({}),
},
},
},
repos: {
getContent: jest.fn(),
listReleases: jest.fn(),
createRelease: jest.fn(),
updateRelease: jest.fn(),
generateReleaseNotes: jest.fn(),
},
},
paginate: jest.fn().mockImplementation(async (method, options) => {
const response = await method(options)
return response.data
}),
}
export const context = {
payload: {
pull_request: {
number: 123,
},
},
repo: {
owner: 'monalisa',
repo: 'helloworld',
},
ref: 'refs/heads/main',
}

export const getOctokit = jest.fn().mockImplementation(() => mockApi)
236 changes: 236 additions & 0 deletions __tests__/release.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
import {getRelease, createOrUpdateRelease} from '../src/release'
import * as github from '@actions/github'
import {Inputs} from '../src/context'

const fs = jest.requireActual('fs')

jest.mock('@actions/core')
jest.mock('@actions/github')

let gh: ReturnType<typeof github.getOctokit>

describe('getRelease', () => {
beforeEach(() => {
jest.clearAllMocks()
gh = github.getOctokit('_')
})

it('should return the latest release when multiple releases exist', async () => {
const mockResponse: any = {
headers: {},
status: 200,
data: [
{
tag_name: 'v1.0.2',
target_commitish: 'main',
draft: false,
},
{
tag_name: 'v1.0.1',
target_commitish: 'main',
draft: false,
},
{
tag_name: 'v1.0.0',
target_commitish: 'main',
draft: false,
},
],
}

const mockReleases = jest.spyOn(gh.rest.repos, 'listReleases')
mockReleases.mockResolvedValue(mockResponse)

const [releases, latestRelease] = await getRelease(gh)

expect(releases).toHaveLength(3)
expect(latestRelease).toBe('v1.0.2')
})

it('should return the latest for the current branch', async () => {
const mockResponse: any = {
headers: {},
status: 200,
data: [
{
tag_name: 'v1.0.2',
target_commitish: 'dev',
draft: false,
},
{
tag_name: 'v1.0.1',
target_commitish: 'main',
draft: false,
},
{
tag_name: 'v1.0.0',
target_commitish: 'main',
draft: false,
},
],
}

const mockReleases = jest.spyOn(gh.rest.repos, 'listReleases')
mockReleases.mockResolvedValue(mockResponse)

const [releases, latestRelease] = await getRelease(gh)

expect(releases).toHaveLength(3)
expect(latestRelease).toBe('v1.0.1')
})

it('should return the latest non-draft release', async () => {
const mockResponse: any = {
headers: {},
status: 200,
data: [
{
tag_name: 'v1.0.2',
target_commitish: 'dev',
draft: false,
},
{
tag_name: 'v1.0.1',
target_commitish: 'main',
draft: true,
},
{
tag_name: 'v1.0.0',
target_commitish: 'main',
draft: false,
},
],
}

const mockReleases = jest.spyOn(gh.rest.repos, 'listReleases')
mockReleases.mockResolvedValue(mockResponse)

const [releases, latestRelease] = await getRelease(gh)

expect(releases).toHaveLength(3)
expect(latestRelease).toBe('v1.0.0')
})

it('should return v0.0.0 when no releases exist', async () => {
const mockResponse: any = {
headers: {},
status: 200,
data: [],
}

const mockReleases = jest.spyOn(gh.rest.repos, 'listReleases')
mockReleases.mockResolvedValue(mockResponse)

const [releases, latestRelease] = await getRelease(gh)

expect(releases).toHaveLength(0)
expect(latestRelease).toBe('v0.0.0')
})
})

describe('createOrUpdateRelease', () => {
let mockResponse: any
let mockNotes: any
const inputs: Inputs = {
githubToken: '_',
majorLabel: 'major',
minorLabel: 'minor',
header: 'header',
footer: 'footer',
}
beforeEach(() => {
jest.clearAllMocks()
gh = github.getOctokit('_')
mockResponse = {
headers: {},
status: 200,
data: [
{
id: 1,
tag_name: 'v1.0.0',
target_commitish: 'main',
draft: false,
body: 'header',
},
{
id: 2,
tag_name: 'v1.0.1',
target_commitish: 'main',
draft: true,
body: 'header',
},
],
}

mockNotes = {
headers: {},
status: 200,
data: {
body: 'header',
name: 'v1.0.1',
},
}
})

it('should create a new release draft', async () => {
const mockInputCreate: any = {
headers: {},
status: 200,
data: [
{
id: 1,
tag_name: 'v1.0.0',
target_commitish: 'main',
draft: false,
},
],
}

const mockReleases = jest.spyOn(gh.rest.repos, 'createRelease')
mockReleases.mockResolvedValue(mockResponse)

const mockRelease = jest.spyOn(gh.rest.repos, 'listReleases')
mockRelease.mockResolvedValue(mockInputCreate)

const mockReleaseNotes = jest.spyOn(gh.rest.repos, 'generateReleaseNotes')
mockReleaseNotes.mockResolvedValue(mockNotes)

const response = await createOrUpdateRelease(gh, inputs, mockInputCreate.data, 'v1.0.0', 'v1.0.1')

expect(mockReleases).toHaveBeenCalledTimes(1)
})

it('should update an existing release draft', async () => {
const mockInputUpdate: any = {
headers: {},
status: 200,
data: [
{
id: 1,
tag_name: 'v1.0.0',
target_commitish: 'main',
draft: false,
},
{
id: 2,
tag_name: 'v1.0.1',
target_commitish: 'main',
draft: true,
},
],
}

const mockReleases = jest.spyOn(gh.rest.repos, 'updateRelease')
mockReleases.mockResolvedValue(mockResponse)

const mockRelease = jest.spyOn(gh.rest.repos, 'listReleases')
mockRelease.mockResolvedValue(mockInputUpdate)

const mockReleaseNotes = jest.spyOn(gh.rest.repos, 'generateReleaseNotes')
mockReleaseNotes.mockResolvedValue(mockNotes)

const response = await createOrUpdateRelease(gh, inputs, mockInputUpdate.data, 'v1.0.0', 'v1.0.1')

expect(mockReleases).toHaveBeenCalledTimes(1)
})
})
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"semver": "^7.3.8"
},
"devDependencies": {
"@types/jest": "^29.5.0",
"@types/js-yaml": "^4.0.5",
"@types/node": "^18.15.3",
"@typescript-eslint/parser": "^5.55.0",
Expand Down
20 changes: 12 additions & 8 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
{
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"outDir": "./lib", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"outDir": "./lib", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
},
"exclude": ["node_modules", "**/*.test.ts"]
"exclude": [
"node_modules",
"**/*.test.ts",
"**/__mocks__"
]
}

0 comments on commit d7e0d0e

Please sign in to comment.