diff --git a/lib/api/github.js b/lib/api/github.js index 7c371b95df9cb951477a42dca99dc0b3531222ff..cb0d10d113e8bd4497b8734d98364a167d9a40a4 100644 --- a/lib/api/github.js +++ b/lib/api/github.js @@ -30,6 +30,7 @@ module.exports = { addReviewers, addLabels, // PR + getPrList, findPr, createPr, getPr, @@ -147,6 +148,7 @@ async function initRepo(repoName, token, endpoint, repoLogger) { } config.repoName = repoName; config.fileList = null; + config.prList = null; const platformConfig = {}; try { const res = await get(`repos/${repoName}`, { @@ -464,22 +466,32 @@ async function addLabels(issueNo, labels) { // Pull Request +async function getPrList() { + if (!config.prList) { + const res = await get( + `repos/${config.repoName}/pulls?per_page=100&state=all` + ); + config.prList = res.body.map(pr => ({ + number: pr.number, + branchName: pr.head.ref, + title: pr.title, + state: pr.state, + closed_at: pr.closed_at, + })); + } + return config.prList; +} + async function findPr(branchName, prTitle, state = 'all') { - logger.debug(`findPr(${branchName}, ${state})`); - const urlString = `repos/${config.repoName}/pulls?head=${config.owner}:${branchName}&state=${state}`; - logger.debug(`findPr urlString: ${urlString}`); - const res = await get(urlString); - let pr = null; - res.body.forEach(result => { - if (!prTitle || result.title === prTitle) { - pr = result; - if (pr.state === 'closed') { - pr.isClosed = true; - } - pr.displayNumber = `Pull Request #${pr.number}`; - } - }); - return pr; + logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`); + const prList = await module.exports.getPrList(); + const pr = prList.filter( + p => + p.branchName === branchName && + (!prTitle || p.title === prTitle) && + (state === 'all' || p.state === state) + )[0]; + return pr ? { ...pr, isClosed: pr.state === 'closed' } : undefined; } // Creates PR and returns PR number diff --git a/test/api/__snapshots__/github.spec.js.snap b/test/api/__snapshots__/github.spec.js.snap index 95b1fbba7bce7ef3e4c6eac36b68e131e88c60a2..f4108e4235c4ef773bfe9058bd0f8631d4738252 100644 --- a/test/api/__snapshots__/github.spec.js.snap +++ b/test/api/__snapshots__/github.spec.js.snap @@ -440,106 +440,6 @@ Array [ ] `; -exports[`api/github findPr(branchName, prTitle, state) should return a PR object 1`] = ` -Array [ - Array [ - "repos/some/repo", - Object { - "headers": Object { - "accept": "application/vnd.github.loki-preview+json", - }, - }, - ], - Array [ - "repos/some/repo/git/refs/heads/master", - ], - Array [ - "repos/some/repo/branches/master/protection/required_status_checks", - Object { - "headers": Object { - "accept": "application/vnd.github.loki-preview+json", - }, - }, - ], - Array [ - "repos/some/repo/pulls?head=theowner:master&state=all", - ], -] -`; - -exports[`api/github findPr(branchName, prTitle, state) should return a PR object 2`] = ` -Object { - "displayNumber": "Pull Request #42", - "number": 42, - "state": "open", - "title": "PR Title", -} -`; - -exports[`api/github findPr(branchName, prTitle, state) should return null if no PR's are found 1`] = ` -Array [ - Array [ - "repos/some/repo", - Object { - "headers": Object { - "accept": "application/vnd.github.loki-preview+json", - }, - }, - ], - Array [ - "repos/some/repo/git/refs/heads/master", - ], - Array [ - "repos/some/repo/branches/master/protection/required_status_checks", - Object { - "headers": Object { - "accept": "application/vnd.github.loki-preview+json", - }, - }, - ], - Array [ - "repos/some/repo/pulls?head=theowner:master&state=all", - ], -] -`; - -exports[`api/github findPr(branchName, prTitle, state) should set the isClosed attribute of the PR to true if the PR is closed 1`] = ` -Array [ - Array [ - "repos/some/repo", - Object { - "headers": Object { - "accept": "application/vnd.github.loki-preview+json", - }, - }, - ], - Array [ - "repos/some/repo/git/refs/heads/master", - ], - Array [ - "repos/some/repo/branches/master/protection/required_status_checks", - Object { - "headers": Object { - "accept": "application/vnd.github.loki-preview+json", - }, - }, - ], - Array [ - "repos/some/repo/pulls?head=theowner:master&state=all", - ], -] -`; - -exports[`api/github findPr(branchName, prTitle, state) should set the isClosed attribute of the PR to true if the PR is closed 2`] = ` -Object { - "displayNumber": "Pull Request #42", - "isClosed": true, - "number": 42, - "state": "closed", - "title": "PR Title", -} -`; - exports[`api/github getAllPrs() maps results to simple array 1`] = ` Array [ Object { diff --git a/test/api/github.spec.js b/test/api/github.spec.js index 9f4fbae38644e0263b7971943c445064ca28d3e2..842b7cf6217c9739f588c3e925eeaa998b831fcf 100644 --- a/test/api/github.spec.js +++ b/test/api/github.spec.js @@ -959,32 +959,54 @@ describe('api/github', () => { }); }); describe('findPr(branchName, prTitle, state)', () => { - it('should return a PR object', async () => { - await initRepo('some/repo', 'token'); - get.mockImplementationOnce(() => ({ - body: [{ title: 'PR Title', state: 'open', number: 42 }], - })); - const pr = await github.findPr('master', 'PR Title'); - expect(get.mock.calls).toMatchSnapshot(); - expect(pr).toMatchSnapshot(); + it('returns true if no title and all state', async () => { + get.mockReturnValueOnce({ + body: [ + { + number: 1, + head: { ref: 'branch-a' }, + title: 'branch a pr', + state: 'open', + }, + ], + }); + const res = await github.findPr('branch-a', null); + expect(res).toBeDefined(); }); - it("should return null if no PR's are found", async () => { - await initRepo('some/repo', 'token'); - get.mockImplementationOnce(() => ({ - body: [], - })); - const pr = await github.findPr('master', 'PR Title'); - expect(get.mock.calls).toMatchSnapshot(); - expect(pr).toBe(null); + it('returns isClosed if closed', async () => { + get.mockReturnValueOnce({ + body: [ + { + number: 1, + head: { ref: 'branch-a' }, + title: 'branch a pr', + state: 'closed', + closed_at: '2017-01-01', + }, + ], + }); + const res = await github.findPr('branch-a', null); + expect(res.isClosed).toBe(true); }); - it('should set the isClosed attribute of the PR to true if the PR is closed', async () => { - await initRepo('some/repo', 'token'); - get.mockImplementationOnce(() => ({ - body: [{ title: 'PR Title', state: 'closed', number: 42 }], - })); - const pr = await github.findPr('master'); - expect(get.mock.calls).toMatchSnapshot(); - expect(pr).toMatchSnapshot(); + it('caches pr list', async () => { + get.mockReturnValueOnce({ + body: [ + { + number: 1, + head: { ref: 'branch-a' }, + title: 'branch a pr', + state: 'open', + }, + ], + }); + let res = await github.findPr('branch-a', null); + expect(res).toBeDefined(); + res = await github.findPr('branch-a', 'branch a pr'); + expect(res).toBeDefined(); + res = await github.findPr('branch-a', 'branch a pr', 'open'); + expect(res).toBeDefined(); + res = await github.findPr('branch-b'); + expect(res).not.toBeDefined(); }); }); describe('createPr(branchName, title, body)', () => {