From 7a1d08eaaba546de40d2f94b43bcf6b14ad203e8 Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@keylocation.sg>
Date: Wed, 18 Oct 2017 11:40:48 +0200
Subject: [PATCH] fix: refactor out remaining do-while loops (#978)

* fix: convert prBody trimming from do-while to recursive

* fix: convert gitlab projects do-while to use pagination
---
 lib/api/gitlab.js                          | 18 ++++------------
 lib/workers/pr/index.js                    | 11 +++++++---
 test/api/__snapshots__/gitlab.spec.js.snap | 24 ++++++++--------------
 test/api/gitlab.spec.js                    | 19 -----------------
 test/config/index.spec.js                  |  1 +
 5 files changed, 21 insertions(+), 52 deletions(-)

diff --git a/lib/api/gitlab.js b/lib/api/gitlab.js
index d22716f406..4ff6a291b9 100644
--- a/lib/api/gitlab.js
+++ b/lib/api/gitlab.js
@@ -53,20 +53,10 @@ async function getRepos(token, endpoint) {
     process.env.GITLAB_ENDPOINT = endpoint;
   }
   try {
-    let projects = [];
-    const perPage = 100;
-    let i = 1;
-    let res;
-    do {
-      const url = `projects?membership=true&per_page=100&page=${i}`;
-      res = await get(url);
-      projects = projects.concat(
-        res.body.map(repo => repo.path_with_namespace)
-      );
-      i += 1;
-    } while (res.body.length === perPage);
-    logger.info(`Discovered ${projects.length} project(s)`);
-    return projects;
+    const url = `projects?membership=true&per_page=100`;
+    const res = await get(url, { paginate: true });
+    logger.info(`Discovered ${res.body.length} project(s)`);
+    return res.body.map(repo => repo.path_with_namespace);
   } catch (err) {
     logger.error({ err }, `GitLab getRepos error`);
     throw err;
diff --git a/lib/workers/pr/index.js b/lib/workers/pr/index.js
index 3f9df72d49..6040b29190 100644
--- a/lib/workers/pr/index.js
+++ b/lib/workers/pr/index.js
@@ -127,7 +127,7 @@ async function ensurePr(prConfig) {
 
   const prTitle = handlebars.compile(config.prTitle)(config);
   let prBody;
-  do {
+  async function trimPrBody() {
     let prBodyMarkdown = handlebars.compile(config.prBody)(config);
     const atUserRe = /[^`]@([a-z]+\/[a-z]+)/g;
     prBodyMarkdown = prBodyMarkdown.replace(atUserRe, '@&#8203;$1');
@@ -136,8 +136,13 @@ async function ensurePr(prConfig) {
     prBody = prBody.replace(issueRe, '$1#&#8203;$2$3');
     const backTickRe = /&#x60;([^/]*?)&#x60;/g;
     prBody = prBody.replace(backTickRe, '<code>$1</code>');
-    config.upgrades.pop();
-  } while (prBody.length > 250000);
+    // istanbul ignore if
+    if (prBody.length > 250000) {
+      config.upgrades.pop();
+      trimPrBody();
+    }
+  }
+  trimPrBody();
 
   try {
     // Check if existing PR exists
diff --git a/test/api/__snapshots__/gitlab.spec.js.snap b/test/api/__snapshots__/gitlab.spec.js.snap
index 4b1036017a..b835b7f108 100644
--- a/test/api/__snapshots__/gitlab.spec.js.snap
+++ b/test/api/__snapshots__/gitlab.spec.js.snap
@@ -299,24 +299,13 @@ Object {
 }
 `;
 
-exports[`api/gitlab getRepos should fetch multiple pages 1`] = `
-Array [
-  Array [
-    "projects?membership=true&per_page=100&page=1",
-  ],
-  Array [
-    "projects?membership=true&per_page=100&page=2",
-  ],
-  Array [
-    "projects?membership=true&per_page=100&page=3",
-  ],
-]
-`;
-
 exports[`api/gitlab getRepos should return an array of repos 1`] = `
 Array [
   Array [
-    "projects?membership=true&per_page=100&page=1",
+    "projects?membership=true&per_page=100",
+    Object {
+      "paginate": true,
+    },
   ],
 ]
 `;
@@ -331,7 +320,10 @@ Array [
 exports[`api/gitlab getRepos should support a custom endpoint 1`] = `
 Array [
   Array [
-    "projects?membership=true&per_page=100&page=1",
+    "projects?membership=true&per_page=100",
+    Object {
+      "paginate": true,
+    },
   ],
 ]
 `;
diff --git a/test/api/gitlab.spec.js b/test/api/gitlab.spec.js
index 4ff05f92dc..78f6b5f133 100644
--- a/test/api/gitlab.spec.js
+++ b/test/api/gitlab.spec.js
@@ -61,25 +61,6 @@ describe('api/gitlab', () => {
       expect(get.mock.calls).toMatchSnapshot();
       expect(repos).toMatchSnapshot();
     });
-    it('should fetch multiple pages', async () => {
-      const repoCount = 250;
-      const projects = [];
-      for (let i = 0; i < repoCount; i += 1) {
-        projects.push({ path_with_namespace: `project${i}` });
-      }
-      get.mockImplementationOnce(() => ({
-        body: projects.slice(0, 100),
-      }));
-      get.mockImplementationOnce(() => ({
-        body: projects.slice(100, 200),
-      }));
-      get.mockImplementationOnce(() => ({
-        body: projects.slice(200),
-      }));
-      const repos = await gitlab.getRepos('sometoken');
-      expect(get.mock.calls).toMatchSnapshot();
-      expect(repos.length).toBe(repoCount);
-    });
   });
 
   async function initRepo(...args) {
diff --git a/test/config/index.spec.js b/test/config/index.spec.js
index e6a5a7bdf8..2a4db9718c 100644
--- a/test/config/index.spec.js
+++ b/test/config/index.spec.js
@@ -114,6 +114,7 @@ describe('config/index', () => {
         '--token=abc',
       ]);
       get.mockImplementationOnce(() => ({
+        headers: {},
         body: [
           {
             path_with_namespace: 'a/b',
-- 
GitLab