diff --git a/packages/gatsby/src/utils/__tests__/get-latest-gatsby-files.ts b/packages/gatsby/src/utils/__tests__/get-latest-gatsby-files.ts index 274d4a0685589..0352115f24507 100644 --- a/packages/gatsby/src/utils/__tests__/get-latest-gatsby-files.ts +++ b/packages/gatsby/src/utils/__tests__/get-latest-gatsby-files.ts @@ -1,9 +1,22 @@ +const mockFiles = new Map() + /* eslint-disable @typescript-eslint/no-var-requires */ jest.mock(`fs-extra`, () => { return { - readJSON: jest.fn(), - writeFile: jest.fn(), - pathExists: jest.fn(), + readJSON: jest.fn().mockImplementation(async filePath => { + const content = mockFiles.get(filePath) + + if (content) { + return JSON.parse(content) + } + throw new Error(`File not found`) + }), + writeFile: jest.fn().mockImplementation(async (filePath, content) => { + mockFiles.set(filePath, content) + }), + pathExists: jest + .fn() + .mockImplementation(async filePath => mockFiles.has(filePath)), } }) jest.mock(`axios`, () => { @@ -13,13 +26,49 @@ jest.mock(`axios`, () => { }) const path = require(`path`) + +const latestAdaptersModulePath = path.join( + __dirname, + `..`, + `..`, + `..`, + `latest-adapters.js` +) + +const latestAdaptersMarker = `` + +const mockAdaptersManifest: Array = [ + { + name: `Mock`, + module: `mock-adapter`, + test: () => !!process.env.MOCK_ADAPTER, + versions: [], + }, +] + +jest.doMock( + latestAdaptersModulePath, + (): Array => { + if (mockFiles.get(latestAdaptersModulePath) === latestAdaptersMarker) { + return mockAdaptersManifest + } + throw new Error(`Module not found`) + }, + { virtual: true } +) + const fs = require(`fs-extra`) const axios = require(`axios`) -import { getLatestAPIs, IAPIResponse } from "../get-latest-gatsby-files" +import { IAdapterManifestEntry } from "../adapter/types" +import { + getLatestAPIs, + getLatestAdapters, + IAPIResponse, +} from "../get-latest-gatsby-files" beforeEach(() => { ;[fs, axios].forEach(mock => - Object.keys(mock).forEach(key => mock[key].mockReset()) + Object.keys(mock).forEach(key => mock[key].mockClear()) ) }) @@ -32,29 +81,53 @@ const getMockAPIFile = (): IAPIResponse => { } describe(`default behavior: has network connectivity`, () => { - beforeEach(() => { - fs.pathExists.mockResolvedValueOnce(false) - axios.get.mockResolvedValueOnce({ data: getMockAPIFile() }) - }) + describe(`getLatestAPIs`, () => { + beforeEach(() => { + axios.get.mockResolvedValueOnce({ data: getMockAPIFile() }) + }) - it(`makes a request to unpkg to request file`, async () => { - const data = await getLatestAPIs() + it(`makes a request to unpkg to request file`, async () => { + const data = await getLatestAPIs() - expect(axios.get).toHaveBeenCalledWith( - expect.stringContaining(`unpkg.com`), - expect.any(Object) - ) - expect(data).toEqual(getMockAPIFile()) + expect(axios.get).toHaveBeenCalledWith( + expect.stringContaining(`unpkg.com`), + expect.any(Object) + ) + expect(data).toEqual(getMockAPIFile()) + }) + + it(`writes apis.json file`, async () => { + const data = await getLatestAPIs() + + expect(fs.writeFile).toHaveBeenCalledWith( + expect.stringContaining(`latest-apis.json`), + JSON.stringify(data, null, 2), + expect.any(String) + ) + }) }) - it(`writes apis.json file`, async () => { - const data = await getLatestAPIs() + describe(`getLatestAdapters`, () => { + beforeEach(() => { + axios.get.mockResolvedValueOnce({ data: latestAdaptersMarker }) + }) - expect(fs.writeFile).toHaveBeenCalledWith( - expect.stringContaining(`latest-apis.json`), - JSON.stringify(data, null, 2), - expect.any(String) - ) + it(`loads .js modules`, async () => { + const data = await getLatestAdapters() + + expect(axios.get).toHaveBeenCalledWith( + expect.stringContaining(`unpkg.com`), + expect.any(Object) + ) + + expect(fs.writeFile).toHaveBeenCalledWith( + expect.stringContaining(`latest-adapters.js`), + latestAdaptersMarker, + expect.any(String) + ) + + expect(data).toEqual(mockAdaptersManifest) + }) }) }) @@ -65,8 +138,6 @@ describe(`downloading APIs failure`, () => { it(`falls back to downloaded cached file, if it exists`, async () => { const apis = getMockAPIFile() - fs.pathExists.mockResolvedValueOnce(true) - fs.readJSON.mockResolvedValueOnce(apis) const data = await getLatestAPIs() @@ -78,9 +149,7 @@ describe(`downloading APIs failure`, () => { }) it(`falls back to local apis.json if latest-apis.json not cached`, async () => { - const apis = getMockAPIFile() - fs.pathExists.mockResolvedValueOnce(false) - fs.readJSON.mockResolvedValueOnce(apis) + mockFiles.clear() await getLatestAPIs() diff --git a/packages/gatsby/src/utils/get-latest-gatsby-files.ts b/packages/gatsby/src/utils/get-latest-gatsby-files.ts index d93eda130635c..a2ff122a00a06 100644 --- a/packages/gatsby/src/utils/get-latest-gatsby-files.ts +++ b/packages/gatsby/src/utils/get-latest-gatsby-files.ts @@ -38,11 +38,18 @@ const _getFile = async ({ timeout: 5000, }) - await fs.writeFile(outputFileName, data, `utf8`) + await fs.writeFile( + outputFileName, + typeof data === `string` ? data : JSON.stringify(data, null, 2), + `utf8` + ) fileToUse = outputFileName } catch (e) { - // no-op + // if file was previously cached, use it + if (await fs.pathExists(outputFileName)) { + fileToUse = outputFileName + } } if (fileToUse.endsWith(`.json`)) {