diff --git a/__tests__/api-helper.test.ts b/__tests__/api-helper.test.ts index 4d8c0e3c..b780cebf 100644 --- a/__tests__/api-helper.test.ts +++ b/__tests__/api-helper.test.ts @@ -9,27 +9,28 @@ import { testLogger } from './util'; import { ApiHelper, Logger } from '../src'; import global from './global'; +const context = getContext({ + ref: 'refs/heads/test', + repo: { + owner: 'hello', + repo: 'world', + }, + sha: '7638417db6d59f3c431d3e1f261cc637155684cd', + payload: { + sender: { + type: 'User', + login: 'octocat', + }, + }, +}); +const octokit = new GitHub(''); + describe('ApiHelper', () => { disableNetConnect(nock); testEnv(); testLogger(); const helper = new ApiHelper(new Logger()); - const context = getContext({ - ref: 'refs/heads/test', - repo: { - owner: 'hello', - repo: 'world', - }, - sha: '7638417db6d59f3c431d3e1f261cc637155684cd', - payload: { - sender: { - type: 'User', - login: 'octocat', - }, - }, - }); - const octokit = new GitHub(''); /** * @param {T} data data @@ -269,6 +270,7 @@ describe('ApiHelper', () => { }); it('should commit', async() => { + const mockStdout = jest.spyOn(global.mockStdout, 'write'); nock('https://api.github.com') .persist() .get('/repos/hello/world/branches/test/protection') @@ -287,6 +289,17 @@ describe('ApiHelper', () => { .reply(200, () => getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.refs')); expect(await helper.commit(path.resolve(__dirname, 'fixtures'), 'test commit message', ['build1.json', 'build2.json'], octokit, context)).toBeTruthy(); + expect(mockStdout).toBeCalledTimes(10); + expect(mockStdout.mock.calls[0][0]).toBe('##[group]Start push to branch [test]' + EOL); + expect(mockStdout.mock.calls[1][0]).toBe('##[endgroup]' + EOL); + expect(mockStdout.mock.calls[2][0]).toBe('##[group]Creating blobs' + EOL); + expect(mockStdout.mock.calls[3][0]).toBe('##[endgroup]' + EOL); + expect(mockStdout.mock.calls[4][0]).toBe('##[group]Creating tree' + EOL); + expect(mockStdout.mock.calls[5][0]).toBe('##[endgroup]' + EOL); + expect(mockStdout.mock.calls[6][0]).toBe('##[group]Creating commit [cd8274d15fa3ae2ab983129fb037999f264ba9a7]' + EOL); + expect(mockStdout.mock.calls[7][0]).toBe('##[endgroup]' + EOL); + expect(mockStdout.mock.calls[8][0]).toBe('##[group]Updating ref [heads%2Ftest] [7638417db6d59f3c431d3e1f261cc637155684cd]' + EOL); + expect(mockStdout.mock.calls[9][0]).toBe('##[endgroup]' + EOL); }); }); @@ -338,3 +351,85 @@ describe('ApiHelper', () => { }); }); }); + +describe('ApiHelper with params', () => { + disableNetConnect(nock); + testEnv(); + testLogger(); + + const helper = new ApiHelper(new Logger(), {branch: 'test-branch', sender: 'test-sender', refForUpdate: 'test-ref'}); + + describe('commit', () => { + it('should commit', async() => { + const fn1 = jest.fn(); + const fn2 = jest.fn(); + const mockStdout = jest.spyOn(global.mockStdout, 'write'); + nock('https://api.github.com') + .persist() + .get('/repos/hello/world/branches/test/protection') + .reply(404) + .post('/repos/hello/world/git/blobs') + .reply(201, () => { + return getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.blobs'); + }) + .get('/repos/hello/world/git/commits/7638417db6d59f3c431d3e1f261cc637155684cd') + .reply(200, () => getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.commits.get')) + .post('/repos/hello/world/git/trees') + .reply(201, () => getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.trees')) + .post('/repos/hello/world/git/commits') + .reply(201, () => getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.commits')) + .patch('/repos/hello/world/git/refs/' + encodeURIComponent('heads/test')) + .reply(200, () => { + fn1(); + return getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.refs'); + }) + .patch('/repos/hello/world/git/refs/' + encodeURIComponent('test-ref')) + .reply(200, () => { + fn2(); + return getApiFixture(path.resolve(__dirname, 'fixtures'), 'repos.git.refs'); + }); + + expect(await helper.commit(path.resolve(__dirname, 'fixtures'), 'test commit message', ['build1.json', 'build2.json'], octokit, context)).toBeTruthy(); + expect(fn1).not.toBeCalled(); + expect(fn2).toBeCalledTimes(1); + expect(mockStdout).toBeCalledTimes(10); + expect(mockStdout.mock.calls[0][0]).toBe('##[group]Start push to branch [test-branch]' + EOL); + expect(mockStdout.mock.calls[1][0]).toBe('##[endgroup]' + EOL); + expect(mockStdout.mock.calls[2][0]).toBe('##[group]Creating blobs' + EOL); + expect(mockStdout.mock.calls[3][0]).toBe('##[endgroup]' + EOL); + expect(mockStdout.mock.calls[4][0]).toBe('##[group]Creating tree' + EOL); + expect(mockStdout.mock.calls[5][0]).toBe('##[endgroup]' + EOL); + expect(mockStdout.mock.calls[6][0]).toBe('##[group]Creating commit [cd8274d15fa3ae2ab983129fb037999f264ba9a7]' + EOL); + expect(mockStdout.mock.calls[7][0]).toBe('##[endgroup]' + EOL); + expect(mockStdout.mock.calls[8][0]).toBe('##[group]Updating ref [test-ref] [7638417db6d59f3c431d3e1f261cc637155684cd]' + EOL); + expect(mockStdout.mock.calls[9][0]).toBe('##[endgroup]' + EOL); + }); + }); + + describe('getUser', () => { + it('should get user', async() => { + const fn1 = jest.fn(); + const fn2 = jest.fn(); + nock('https://api.github.com') + .persist() + .get('/users/octocat') + .reply(200, () => { + fn1(); + return getApiFixture(path.resolve(__dirname, 'fixtures'), 'users.get'); + }) + .get('/users/test-sender') + .reply(200, () => { + fn2(); + return getApiFixture(path.resolve(__dirname, 'fixtures'), 'users.get'); + }); + + const user = await helper.getUser(octokit, context); + expect(fn1).not.toBeCalled(); + expect(fn2).toBeCalledTimes(1); + expect(user.login).toBe('octocat'); + expect(user.email).toBe('octocat@github.com'); + expect(user.name).toBe('monalisa octocat'); + expect(user.id).toBe(1); + }); + }); +}); diff --git a/jest.setup.ts b/jest.setup.ts index b0dcc017..be4da1ae 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -21,8 +21,4 @@ jest.mock('child_process', () => ({ exec: global.mockChildProcess.exec, })); -global.console.log = jest.fn(); -global.console.warn = jest.fn(); -global.console.error = jest.fn(); - process.env.GITHUB_ACTOR = 'octocat'; diff --git a/package.json b/package.json index de6cd5ec..aafc8eef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@technote-space/github-action-helper", - "version": "0.0.8", + "version": "0.0.9", "description": "Helper to filter GitHub Action.", "author": "Technote (https://technote.space)", "license": "MIT", diff --git a/src/api-helper.ts b/src/api-helper.ts index f3d9161f..7d2f45ba 100644 --- a/src/api-helper.ts +++ b/src/api-helper.ts @@ -4,20 +4,50 @@ import { GitHub } from '@actions/github/lib/github'; import { Context } from '@actions/github/lib/context'; import { Response, GitCreateTreeResponse, GitCreateCommitResponse, GitGetCommitResponse } from '@octokit/rest'; import { Logger } from './logger'; -import { getBranch, getRefForUpdate, getSender } from './utils'; +import { getBranch, getSender, getRefForUpdate } from './utils'; /** * Commit */ export default class ApiHelper { + private readonly branch?: string | undefined = undefined; + private readonly sender?: string | undefined = undefined; + private readonly refForUpdate?: string | undefined = undefined; + /** * @param {Logger} logger logger + * @param {object} options options + * @param {string|undefined} options.branch branch + * @param {string|undefined} options.sender sender + * @param {string|undefined} options.refForUpdate ref for update */ - constructor(private logger: Logger) { - + constructor(private readonly logger: Logger, options?: { branch?: string; sender?: string; refForUpdate?: string }) { + if (options) { + this.branch = options.branch; + this.sender = options.sender; + this.refForUpdate = options.refForUpdate; + } } + /** + * @param {Context} context context + * @return {string} branch + */ + private getBranch = (context: Context): string => this.branch ? this.branch : getBranch(context); + + /** + * @param {Context} context context + * @return {string|boolean} sender + */ + private getSender = (context: Context): string | false => this.sender ? this.sender : getSender(context); + + /** + * @param {Context} context context + * @return {string} ref for update + */ + private getRefForUpdate = (context: Context): string => this.refForUpdate ? this.refForUpdate : getRefForUpdate(context); + /** * @param {string} rootDir root dir * @param {string} filepath filepath @@ -108,7 +138,7 @@ export default class ApiHelper { await octokit.git.updateRef({ owner: context.repo.owner, repo: context.repo.repo, - ref: getRefForUpdate(context), + ref: this.getRefForUpdate(context), sha: commit.data.sha, }); }; @@ -119,14 +149,12 @@ export default class ApiHelper { * @return {Promise} result */ public checkProtected = async(octokit: GitHub, context: Context): Promise => { - const branch = getBranch(context); - try { // eslint-disable-next-line no-magic-numbers return 200 === (await octokit.repos.getBranchProtection({ owner: context.repo.owner, repo: context.repo.repo, - branch, + branch: this.getBranch(context), })).status; } catch (error) { return false; @@ -148,11 +176,11 @@ export default class ApiHelper { } if (await this.checkProtected(octokit, context)) { - this.logger.warn('Branch [%s] is protected', getBranch(context)); + this.logger.warn('Branch [%s] is protected', this.getBranch(context)); return false; } - this.logger.startProcess('Start push to branch [%s]', getBranch(context)); + this.logger.startProcess('Start push to branch [%s]', this.getBranch(context)); this.logger.startProcess('Creating blobs'); const blobs = await this.filesToBlobs(rootDir, files, octokit, context); @@ -163,9 +191,10 @@ export default class ApiHelper { this.logger.startProcess('Creating commit [%s]', tree.data.sha); const commit = await this.createCommit(commitMessage, tree, octokit, context); - this.logger.startProcess('Updating ref [%s] [%s]', getRefForUpdate(context), commit.data.sha); + this.logger.startProcess('Updating ref [%s] [%s]', this.getRefForUpdate(context), commit.data.sha); await this.updateRef(commit, octokit, context); + this.logger.endProcess(); return true; }; @@ -175,7 +204,7 @@ export default class ApiHelper { * @return {Promise<{ login: string, email: string, name: string, id: number }>} user */ public getUser = async(octokit: GitHub, context: Context): Promise<{ login: string; email: string; name: string; id: number }> => { - const sender = getSender(context); + const sender = this.getSender(context); if (false === sender) { throw new Error('Sender is not valid.'); }