| | import fs from 'fs' |
| | import path from 'path' |
| | import os from 'os' |
| |
|
| | import { rimraf } from 'rimraf' |
| | import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest' |
| | import nock from 'nock' |
| |
|
| | import getRemoteJSON, { cache } from '@/frame/lib/get-remote-json' |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | describe('getRemoteJSON', () => { |
| | const envVarValueBefore = process.env.GET_REMOTE_JSON_DISK_CACHE_ROOT |
| | const tempDir = path.join(os.tmpdir(), 'remotejson-test') |
| |
|
| | beforeAll(() => { |
| | process.env.GET_REMOTE_JSON_DISK_CACHE_ROOT = tempDir |
| | }) |
| |
|
| | afterAll(() => { |
| | process.env.GET_REMOTE_JSON_DISK_CACHE_ROOT = envVarValueBefore |
| | rimraf.sync(tempDir) |
| | }) |
| |
|
| | afterEach(() => { |
| | nock.cleanAll() |
| | }) |
| |
|
| | test('simple in-memory caching', async () => { |
| | const url = 'http://example.com/redirects.json' |
| | const { origin, pathname } = new URL(url) |
| | nock(origin).get(pathname).reply(200, { foo: 'bar' }) |
| | const data = await getRemoteJSON(url, {}) |
| | expect(data.foo).toBe('bar') |
| | expect(cache.get(url)).toBeTruthy() |
| | |
| | |
| | const data2 = await getRemoteJSON(url, {}) |
| | expect(data2.foo).toBe('bar') |
| | expect(cache.get(url)).toBeTruthy() |
| | }) |
| |
|
| | test('benefit from disk-based caching', async () => { |
| | const url = 'http://example.com/cool.json' |
| | const { origin, pathname } = new URL(url) |
| | nock(origin).get(pathname).reply(200, { cool: true }) |
| | const data = await getRemoteJSON(url, {}) |
| | expect(data.cool).toBe(true) |
| | expect(cache.get(url)).toBeTruthy() |
| | cache.delete(url) |
| |
|
| | |
| | |
| | |
| | const data2 = await getRemoteJSON(url, {}) |
| | expect(data2.cool).toBe(true) |
| | }) |
| |
|
| | test('recover from disk corruption (empty)', async () => { |
| | const tempTempDir = path.join(tempDir, 'empty-files') |
| | process.env.GET_REMOTE_JSON_DISK_CACHE_ROOT = tempTempDir |
| | const url = 'http://example.com/empty.json' |
| | const { origin, pathname } = new URL(url) |
| | nock(origin).get(pathname).reply(200, { cool: true }) |
| | await getRemoteJSON(url, {}) |
| |
|
| | |
| | for (const file of fs.readdirSync(tempTempDir)) { |
| | fs.writeFileSync(path.join(tempTempDir, file), '') |
| | } |
| |
|
| | cache.delete(url) |
| | |
| | |
| | nock(origin).get(pathname).reply(200, { cool: true }) |
| |
|
| | const data = await getRemoteJSON(url, {}) |
| | expect(data.cool).toBe(true) |
| | }) |
| |
|
| | test('recover from disk corruption (bad JSON)', async () => { |
| | const tempTempDir = path.join(tempDir, 'corrupt-files') |
| | process.env.GET_REMOTE_JSON_DISK_CACHE_ROOT = tempTempDir |
| | const url = 'http://example.com/corrupt.json' |
| | const { origin, pathname } = new URL(url) |
| | nock(origin).get(pathname).reply(200, { cool: true }) |
| | await getRemoteJSON(url, {}) |
| |
|
| | |
| | for (const file of fs.readdirSync(tempTempDir)) { |
| | fs.writeFileSync(path.join(tempTempDir, file), '{"not:JSON{') |
| | } |
| |
|
| | cache.delete(url) |
| | |
| | |
| | nock(origin).get(pathname).reply(200, { cool: true }) |
| |
|
| | const data = await getRemoteJSON(url, {}) |
| | expect(data.cool).toBe(true) |
| | }) |
| |
|
| | test('not-actually JSON despite URL', async () => { |
| | const url = 'http://example.com/might-look-like.json' |
| | const { origin, pathname } = new URL(url) |
| | nock(origin).get(pathname).reply(200, '<html>here</html>', { |
| | 'Content-Type': 'text/html', |
| | }) |
| | await expect(getRemoteJSON(url, {})).rejects.toThrowError(/resulted in a non-JSON response/) |
| | }) |
| | }) |
| |
|