From 8113a19b1f8969319df94ecb476f2efcd61af81c Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@keylocation.sg>
Date: Mon, 17 Apr 2017 08:39:11 +0200
Subject: [PATCH] Fix GitHub branchExists check (#170)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Fix: don’t check for closed PR if groupName is configured

* Fix GitHub branchExists check

* Revert "Fix GitHub branchExists check"

This reverts commit 775b3172f1355d803b01454a007935005e1a86a2.

* Revert "Revert "Fix GitHub branchExists check""

This reverts commit 84e4a5dbbf37cbbf3b417a9c96e372038b651731.

* Update tests
---
 lib/api/github.js                          | 15 +++++-
 test/api/__snapshots__/github.spec.js.snap | 53 +++++++++++++++++++++-
 test/api/github.spec.js                    | 48 +++++++++++++++++++-
 3 files changed, 112 insertions(+), 4 deletions(-)

diff --git a/lib/api/github.js b/lib/api/github.js
index 7853881a80..e90992511a 100644
--- a/lib/api/github.js
+++ b/lib/api/github.js
@@ -75,8 +75,19 @@ async function branchExists(branchName) {
   try {
     const res = await ghGot(`repos/${config.repoName}/git/refs/heads/${branchName}`);
     if (res.statusCode === 200) {
-      logger.debug('Branch exists');
-      return true;
+      logger.debug(JSON.stringify(res.body));
+      if (Array.isArray(res.body)) {
+        // This seems to happen if GitHub has partial matches, so we check ref
+        const matchedBranch = res.body.some(branch => branch.ref === `refs/heads/${branchName}`);
+        if (matchedBranch) {
+          logger.debug('Branch exists');
+        } else {
+          logger.debug('No matching branches');
+        }
+        return matchedBranch;
+      }
+      // This should happen if there's an exact match
+      return res.body.ref === `refs/heads/${branchName}`;
     }
     // This probably shouldn't happen
     logger.debug('Branch doesn\'t exist');
diff --git a/test/api/__snapshots__/github.spec.js.snap b/test/api/__snapshots__/github.spec.js.snap
index 89d1260379..62d554f0b9 100644
--- a/test/api/__snapshots__/github.spec.js.snap
+++ b/test/api/__snapshots__/github.spec.js.snap
@@ -97,7 +97,58 @@ Array [
 ]
 `;
 
-exports[`api/github branchExists(branchName) should return true if the branch exists 1`] = `
+exports[`api/github branchExists(branchName) should return false if the branch does not exist (multiple results) 1`] = `
+Array [
+  Array [
+    "repos/some/repo",
+  ],
+  Array [
+    "repos/some/repo/git/refs/heads/master",
+  ],
+  Array [
+    "repos/some/repo/git/commits/1234",
+  ],
+  Array [
+    "repos/some/repo/git/refs/heads/thebranchname",
+  ],
+]
+`;
+
+exports[`api/github branchExists(branchName) should return false if the branch does not exist (one result) 1`] = `
+Array [
+  Array [
+    "repos/some/repo",
+  ],
+  Array [
+    "repos/some/repo/git/refs/heads/master",
+  ],
+  Array [
+    "repos/some/repo/git/commits/1234",
+  ],
+  Array [
+    "repos/some/repo/git/refs/heads/thebranchname",
+  ],
+]
+`;
+
+exports[`api/github branchExists(branchName) should return true if the branch exists (multiple results) 1`] = `
+Array [
+  Array [
+    "repos/some/repo",
+  ],
+  Array [
+    "repos/some/repo/git/refs/heads/master",
+  ],
+  Array [
+    "repos/some/repo/git/commits/1234",
+  ],
+  Array [
+    "repos/some/repo/git/refs/heads/thebranchname",
+  ],
+]
+`;
+
+exports[`api/github branchExists(branchName) should return true if the branch exists (one result) 1`] = `
 Array [
   Array [
     "repos/some/repo",
diff --git a/test/api/github.spec.js b/test/api/github.spec.js
index 1cf8de88a4..494e585699 100644
--- a/test/api/github.spec.js
+++ b/test/api/github.spec.js
@@ -88,15 +88,58 @@ describe('api/github', () => {
     });
   });
   describe('branchExists(branchName)', () => {
-    it('should return true if the branch exists', async () => {
+    it('should return true if the branch exists (one result)', async () => {
       await initRepo('some/repo', 'token');
       ghGot.mockImplementationOnce(() => ({
         statusCode: 200,
+        body: {
+          ref: 'refs/heads/thebranchname',
+        },
+      }));
+      const exists = await github.branchExists('thebranchname');
+      expect(ghGot.mock.calls).toMatchSnapshot();
+      expect(exists).toBe(true);
+    });
+    it('should return true if the branch exists (multiple results)', async () => {
+      await initRepo('some/repo', 'token');
+      ghGot.mockImplementationOnce(() => ({
+        statusCode: 200,
+        body: [{
+          ref: 'refs/heads/notthebranchname',
+        }, {
+          ref: 'refs/heads/thebranchname',
+        }],
       }));
       const exists = await github.branchExists('thebranchname');
       expect(ghGot.mock.calls).toMatchSnapshot();
       expect(exists).toBe(true);
     });
+    it('should return false if the branch does not exist (one result)', async () => {
+      await initRepo('some/repo', 'token');
+      ghGot.mockImplementationOnce(() => ({
+        statusCode: 200,
+        body: {
+          ref: 'refs/heads/notthebranchname',
+        },
+      }));
+      const exists = await github.branchExists('thebranchname');
+      expect(ghGot.mock.calls).toMatchSnapshot();
+      expect(exists).toBe(false);
+    });
+    it('should return false if the branch does not exist (multiple results)', async () => {
+      await initRepo('some/repo', 'token');
+      ghGot.mockImplementationOnce(() => ({
+        statusCode: 200,
+        body: [{
+          ref: 'refs/heads/notthebranchname',
+        }, {
+          ref: 'refs/heads/alsonotthebranchname',
+        }],
+      }));
+      const exists = await github.branchExists('thebranchname');
+      expect(ghGot.mock.calls).toMatchSnapshot();
+      expect(exists).toBe(false);
+    });
     it('should return false if a non-200 response is returned', async () => {
       await initRepo('some/repo', 'token');
       ghGot.mockImplementationOnce(() => ({
@@ -439,6 +482,9 @@ describe('api/github', () => {
       // branchExists
       ghGot.mockImplementationOnce(() => ({
         statusCode: 200,
+        body: {
+          ref: 'refs/heads/package.json',
+        },
       }));
       const files = [{
         name: 'package.json',
-- 
GitLab