From 5da4f8ce64ecabcda87fcdddaf5d684ca82e076f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominykas=20Blyz=CC=8Ce=CC=87?= Date: Sun, 18 Apr 2021 12:40:40 +0300 Subject: [PATCH] fix: avoid crashing when getting results for a missing branch Bullet point in #46 --- lib/result.js | 19 +++++- test/cli/result.js | 56 +++++++++++++++-- .../result/result-output-missing-branch.md | 21 +++++++ .../result/result-output-multiple-pass.md | 24 +++++++ ...t.md => result-output-multiple-pending.md} | 0 ...result-command-empty-branch-checks-flat.js | 2 + .../result-command-empty-branch-checks.js | 2 + .../http/result-command-missing-branch.js | 63 +++++++++++++++++++ .../result-command-positive-checks-failed.js | 2 + .../http/result-command-positive-pass.js | 63 +++++++++++++++++++ ....js => result-command-positive-pending.js} | 8 +++ test/result.js | 6 +- 12 files changed, 256 insertions(+), 10 deletions(-) create mode 100644 test/fixtures/expected-outputs/result/result-output-missing-branch.md create mode 100644 test/fixtures/expected-outputs/result/result-output-multiple-pass.md rename test/fixtures/expected-outputs/result/{result-output-multiple-dependant.md => result-output-multiple-pending.md} (100%) create mode 100644 test/fixtures/http/result-command-missing-branch.js create mode 100644 test/fixtures/http/result-command-positive-pass.js rename test/fixtures/http/{result-command-positive.js => result-command-positive-pending.js} (80%) diff --git a/lib/result.js b/lib/result.js index 93ce1d4..6b82f25 100644 --- a/lib/result.js +++ b/lib/result.js @@ -9,10 +9,14 @@ const debug = logger('wiby:result') // enum containing possible pipeline checks statuses const pipelineStatusesEnum = module.exports.pipelineStatusesEnum = Object.freeze({ + // statuses returned by github FAILED: 'failure', QUEUED: 'queued', PENDING: 'pending', - SUCCEED: 'success' + SUCCEED: 'success', + + // custom statuses + MISSING: 'test branch missing' }) const PENDING_RESULT_EXIT_CODE = 64 @@ -36,6 +40,16 @@ module.exports = async function ({ dependents }) { const parentBranchName = await context.getParentBranchName() const branch = await context.getTestingBranchName(parentBranchName) + const exists = await github.getBranch(dependentPkgInfo.owner, dependentPkgInfo.name, branch) + if (!exists) { + output.results.push({ + dependent: `${dependentPkgInfo.owner}/${dependentPkgInfo.name}`, + status: pipelineStatusesEnum.MISSING, + runs: [] + }) + allDependentsChecks.push([undefined, pipelineStatusesEnum.MISSING]) + continue + } let resp = await github.getChecks(dependentPkgInfo.owner, dependentPkgInfo.name, branch) if (resp.data.check_runs.length === 0) { resp = await github.getCommitStatusesForRef(dependentPkgInfo.owner, dependentPkgInfo.name, branch) @@ -106,7 +120,8 @@ const getOverallStatusForAllRuns = module.exports.getOverallStatusForAllRuns = f // if includes null or pending or queued - overall status is pending if (statuses.includes(null) || statuses.includes(pipelineStatusesEnum.PENDING) || - statuses.includes(pipelineStatusesEnum.QUEUED) + statuses.includes(pipelineStatusesEnum.QUEUED) || + statuses.includes(pipelineStatusesEnum.MISSING) ) { return pipelineStatusesEnum.PENDING } diff --git a/test/cli/result.js b/test/cli/result.js index 82ad137..cea6b33 100644 --- a/test/cli/result.js +++ b/test/cli/result.js @@ -10,6 +10,8 @@ const gitFixture = require('../fixtures/git') const wibyCommand = path.join(__dirname, '..', '..', 'bin', 'wiby') const fixturesPath = path.resolve(path.join(__dirname, '..', 'fixtures')) +const SUCCESS_RESULT_EXIT_CODE = 0 +const FAIL_RESULT_EXIT_CODE = 1 const PENDING_RESULT_EXIT_CODE = 64 tap.test('result command', async (tap) => { @@ -37,20 +39,64 @@ tap.test('result command', async (tap) => { childProcess.execSync(`${wibyCommand} result --dependent="https://github.com/wiby-test/fakeRepo"`, { env: { ...process.env, - NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive.js` + NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive-pass.js` } }) } catch (e) { const result = e.output[1].toString().trim() tap.equal(result, expected) - tap.equal(e.status, PENDING_RESULT_EXIT_CODE) + tap.equal(e.status, SUCCESS_RESULT_EXIT_CODE) } }) tap.test('result command should call result module with all deps from .wiby.json', async (tap) => { const expected = fs.readFileSync( - path.join(__dirname, '..', 'fixtures', 'expected-outputs', 'result', 'result-output-multiple-dependant.md'), + path.join(__dirname, '..', 'fixtures', 'expected-outputs', 'result', 'result-output-multiple-pass.md'), + 'utf-8' + ) + .trim() + + try { + childProcess.execSync(`${wibyCommand} result`, { + env: { + ...process.env, + NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive-pass.js` + } + }) + } catch (e) { + const result = e.output[1].toString().trim() + + tap.equal(result, expected) + tap.equal(e.status, SUCCESS_RESULT_EXIT_CODE) + } + }) + + tap.test('result command should call result module with all deps from .wiby.json (pending result)', async (tap) => { + const expected = fs.readFileSync( + path.join(__dirname, '..', 'fixtures', 'expected-outputs', 'result', 'result-output-multiple-pending.md'), + 'utf-8' + ) + .trim() + + try { + childProcess.execSync(`${wibyCommand} result`, { + env: { + ...process.env, + NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive-pending.js` + } + }) + } catch (e) { + const result = e.output[1].toString().trim() + + tap.equal(result, expected) + tap.equal(e.status, PENDING_RESULT_EXIT_CODE) + } + }) + + tap.test('result command should call result module with all deps from .wiby.json (missing branch result)', async (tap) => { + const expected = fs.readFileSync( + path.join(__dirname, '..', 'fixtures', 'expected-outputs', 'result', 'result-output-missing-branch.md'), 'utf-8' ) .trim() @@ -59,7 +105,7 @@ tap.test('result command', async (tap) => { childProcess.execSync(`${wibyCommand} result`, { env: { ...process.env, - NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive.js` + NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-missing-branch.js` } }) } catch (e) { @@ -136,7 +182,7 @@ tap.test('result command', async (tap) => { const result = e.output[1].toString().trim() tap.equal(result, expected) - tap.equal(e.status, 1) + tap.equal(e.status, FAIL_RESULT_EXIT_CODE) } }) }) diff --git a/test/fixtures/expected-outputs/result/result-output-missing-branch.md b/test/fixtures/expected-outputs/result/result-output-missing-branch.md new file mode 100644 index 0000000..f7d4e96 --- /dev/null +++ b/test/fixtures/expected-outputs/result/result-output-missing-branch.md @@ -0,0 +1,21 @@ +# wiby result command + +Overall status - pending + +## wiby-test/partial - success + +Checks: + +- partial_run - success +- partial_run_2 - success + +## wiby-test/fail - test branch missing + +Checks: + +## wiby-test/pass - success + +Checks: + +- pass_run - success +- pass_run_2 - success diff --git a/test/fixtures/expected-outputs/result/result-output-multiple-pass.md b/test/fixtures/expected-outputs/result/result-output-multiple-pass.md new file mode 100644 index 0000000..432ad40 --- /dev/null +++ b/test/fixtures/expected-outputs/result/result-output-multiple-pass.md @@ -0,0 +1,24 @@ +# wiby result command + +Overall status - success + +## wiby-test/partial - success + +Checks: + +- partial_run - success +- partial_run_2 - success + +## wiby-test/fail - success + +Checks: + +- fail_run - success +- fail_run_2 - success + +## wiby-test/pass - success + +Checks: + +- pass_run - success +- pass_run_2 - success diff --git a/test/fixtures/expected-outputs/result/result-output-multiple-dependant.md b/test/fixtures/expected-outputs/result/result-output-multiple-pending.md similarity index 100% rename from test/fixtures/expected-outputs/result/result-output-multiple-dependant.md rename to test/fixtures/expected-outputs/result/result-output-multiple-pending.md diff --git a/test/fixtures/http/result-command-empty-branch-checks-flat.js b/test/fixtures/http/result-command-empty-branch-checks-flat.js index 8c2beab..ff74e91 100644 --- a/test/fixtures/http/result-command-empty-branch-checks-flat.js +++ b/test/fixtures/http/result-command-empty-branch-checks-flat.js @@ -23,6 +23,8 @@ nock('https://api.github.com') } } }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) // get check results .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') .reply(200, { diff --git a/test/fixtures/http/result-command-empty-branch-checks.js b/test/fixtures/http/result-command-empty-branch-checks.js index deab11e..ba56256 100644 --- a/test/fixtures/http/result-command-empty-branch-checks.js +++ b/test/fixtures/http/result-command-empty-branch-checks.js @@ -23,6 +23,8 @@ nock('https://api.github.com') } } }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) // get check results .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') .reply(200, { diff --git a/test/fixtures/http/result-command-missing-branch.js b/test/fixtures/http/result-command-missing-branch.js new file mode 100644 index 0000000..6a0bd50 --- /dev/null +++ b/test/fixtures/http/result-command-missing-branch.js @@ -0,0 +1,63 @@ +'use strict' + +/** + * Mocks of HTTP calls for "wiby result" command positive flow + */ +const nock = require('nock') + +nock.disableNetConnect() + +nock('https://api.github.com') + // get package json + .post('/graphql') + .times(3) + .reply(200, { + data: { + repository: { + object: { + text: JSON.stringify({ + dependencies: { + wiby: '*' + } + }) + } + } + } + }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/partial/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/pass/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/fail/branches/wiby-running-unit-tests') + .reply(404, {}) + // get check results + .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'fake_run', conclusion: 'success' }, + { status: 'done', name: 'fake_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/fail/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'fail_run', conclusion: 'success' }, + { status: 'done', name: 'fail_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/pass/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'pass_run', conclusion: 'success' }, + { status: 'done', name: 'pass_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/partial/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'partial_run', conclusion: 'success' }, + { status: 'done', name: 'partial_run_2', conclusion: 'success' } + ] + }) diff --git a/test/fixtures/http/result-command-positive-checks-failed.js b/test/fixtures/http/result-command-positive-checks-failed.js index e252c80..a82d32c 100644 --- a/test/fixtures/http/result-command-positive-checks-failed.js +++ b/test/fixtures/http/result-command-positive-checks-failed.js @@ -25,6 +25,8 @@ nock('https://api.github.com') } } }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) // get check results .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') .reply(200, { diff --git a/test/fixtures/http/result-command-positive-pass.js b/test/fixtures/http/result-command-positive-pass.js new file mode 100644 index 0000000..cfec151 --- /dev/null +++ b/test/fixtures/http/result-command-positive-pass.js @@ -0,0 +1,63 @@ +'use strict' + +/** + * Mocks of HTTP calls for "wiby result" command positive flow + */ +const nock = require('nock') + +nock.disableNetConnect() + +nock('https://api.github.com') + // get package json + .post('/graphql') + .times(3) + .reply(200, { + data: { + repository: { + object: { + text: JSON.stringify({ + dependencies: { + wiby: '*' + } + }) + } + } + } + }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/partial/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/pass/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/fail/branches/wiby-running-unit-tests') + .reply(200, {}) + // get check results + .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'fake_run', conclusion: 'success' }, + { status: 'done', name: 'fake_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/fail/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'fail_run', conclusion: 'success' }, + { status: 'done', name: 'fail_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/pass/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'pass_run', conclusion: 'success' }, + { status: 'done', name: 'pass_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/partial/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'partial_run', conclusion: 'success' }, + { status: 'done', name: 'partial_run_2', conclusion: 'success' } + ] + }) diff --git a/test/fixtures/http/result-command-positive.js b/test/fixtures/http/result-command-positive-pending.js similarity index 80% rename from test/fixtures/http/result-command-positive.js rename to test/fixtures/http/result-command-positive-pending.js index a14b8d9..ed48952 100644 --- a/test/fixtures/http/result-command-positive.js +++ b/test/fixtures/http/result-command-positive-pending.js @@ -24,6 +24,14 @@ nock('https://api.github.com') } } }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/partial/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/pass/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/fail/branches/wiby-running-unit-tests') + .reply(200, {}) // get check results .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') .reply(200, { diff --git a/test/result.js b/test/result.js index 121f416..b601eac 100644 --- a/test/result.js +++ b/test/result.js @@ -53,13 +53,13 @@ tap.test('wiby.result()', async (tap) => { tap.test('result() should return correct data object', async (tap) => { // mock real http requests with positive scenario - require('./fixtures/http/result-command-positive') + require('./fixtures/http/result-command-positive-pass') const output = await wiby.result({ dependents: [{ repository: 'https://github.com/wiby-test/fakeRepo' }] }) - tap.equal(output.status, 'pending') + tap.equal(output.status, 'success') tap.equal(output.results[0].dependent, 'wiby-test/fakeRepo') - tap.equal(output.results[0].status, 'pending') + tap.equal(output.results[0].status, 'success') tap.equal(output.results[0].runs.length, 2) })