From 537e911e39bfdcd9bfc6df6a4ad36377eb1d4fb8 Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@arkins.net>
Date: Wed, 29 Apr 2020 07:00:53 +0200
Subject: [PATCH] fix: fetch internal presets over www not api (#6078)

---
 .../presets/__snapshots__/github.spec.ts.snap | 13 +++++
 lib/config/presets/github.spec.ts             | 48 +++++++++++++++++++
 lib/config/presets/github.ts                  | 30 +++++++++++-
 3 files changed, 90 insertions(+), 1 deletion(-)
 create mode 100644 lib/config/presets/__snapshots__/github.spec.ts.snap

diff --git a/lib/config/presets/__snapshots__/github.spec.ts.snap b/lib/config/presets/__snapshots__/github.spec.ts.snap
new file mode 100644
index 0000000000..9274f8368d
--- /dev/null
+++ b/lib/config/presets/__snapshots__/github.spec.ts.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`config/presets/github fetchJSONFile() returns JSON 1`] = `
+Object {
+  "from": "api",
+}
+`;
+
+exports[`config/presets/github fetchJSONFile() returns renovate internal 1`] = `
+Object {
+  "from": "www",
+}
+`;
diff --git a/lib/config/presets/github.spec.ts b/lib/config/presets/github.spec.ts
index 3b3628251f..3fd6c664ec 100644
--- a/lib/config/presets/github.spec.ts
+++ b/lib/config/presets/github.spec.ts
@@ -18,6 +18,54 @@ describe('config/presets/github', () => {
     got.mockReset();
     return global.renovateCache.rmAll();
   });
+  describe('setInternalPreset()', () => {
+    it('allows override', () => {
+      github.setInternalPreset({ body: {} });
+    });
+  });
+  describe('fetchJSONFile()', () => {
+    beforeEach(() => {
+      delete global.repoCache.internalPresets;
+    });
+    it('returns JSON', async () => {
+      hostRules.find.mockReturnValueOnce({ token: 'abc' });
+      got.mockImplementationOnce(() => ({
+        body: {
+          content: Buffer.from('{"from":"api"}').toString('base64'),
+        },
+      }));
+      const res = await github.fetchJSONFile(
+        'some/repo',
+        'some-filename',
+        'https://api.github.com'
+      );
+      expect(res).toMatchSnapshot();
+    });
+    it('returns renovate internal', async () => {
+      hostRules.find.mockReturnValueOnce({ token: 'abc' });
+      got.mockImplementationOnce(() => ({
+        body: { from: 'www' },
+      }));
+      const res = await github.fetchJSONFile(
+        'renovatebot/presets',
+        'presets.json',
+        'https://api.github.com/'
+      );
+      expect(res).toMatchSnapshot();
+    });
+    it('throws platform error', async () => {
+      got.mockImplementationOnce(() => {
+        throw new Error();
+      });
+      await expect(
+        github.fetchJSONFile(
+          'renovatebot/presets',
+          'presets.json',
+          'https://api.github.com/'
+        )
+      ).rejects.toThrow(PLATFORM_FAILURE);
+    });
+  });
   describe('getPreset()', () => {
     it('passes up platform-failure', async () => {
       got.mockImplementationOnce(() => {
diff --git a/lib/config/presets/github.ts b/lib/config/presets/github.ts
index 11849e764a..8bf562be16 100644
--- a/lib/config/presets/github.ts
+++ b/lib/config/presets/github.ts
@@ -7,12 +7,40 @@ import { PLATFORM_TYPE_GITHUB } from '../../constants/platforms';
 
 const http = new Http(PLATFORM_TYPE_GITHUB);
 
-async function fetchJSONFile(
+export function setInternalPreset(content: { body: Preset }): void {
+  global.repoCache.internalPresets = Promise.resolve(content);
+}
+
+async function fetchInternalPreset(): Promise<Preset> {
+  const res = await http.getJson<Preset>(
+    'https://raw.githubusercontent.com/renovatebot/presets/master/presets.json'
+  );
+  return res.body;
+}
+
+function getInternalPreset(): Promise<Preset> {
+  global.repoCache.internalPresets =
+    global.repoCache.internalPresets || fetchInternalPreset();
+  return global.repoCache.internalPresets;
+}
+
+export async function fetchJSONFile(
   repo: string,
   fileName: string,
   endpoint: string
 ): Promise<Preset> {
   const url = `${endpoint}repos/${repo}/contents/${fileName}`;
+  if (
+    url ===
+    'https://api.github.com/repos/renovatebot/presets/contents/presets.json'
+  ) {
+    try {
+      const res = await getInternalPreset();
+      return res;
+    } catch (err) {
+      throw new Error(PLATFORM_FAILURE);
+    }
+  }
   const opts: HttpOptions = {
     headers: {
       accept: global.appMode
-- 
GitLab