- Static text files are gzipped and the hashed files under assets/ are cached for a year; the 1.6 MB bundle was sent whole on every visit. - A proxy's error page (502 Bad Gateway) is reported as its HTTP status instead of a JSON parse error. - Reads asked at the same time share one upstream request. - After a timeout, reads of that server fail at once for 10 s instead of each waiting the full timeout. Co-Authored-By: Claude Opus 5.5 <[email protected]>
42 lines
1.8 KiB
TypeScript
42 lines
1.8 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { Upstream } from './upstream.ts'
|
|
import type { HubConfig } from './config.ts'
|
|
|
|
const server = { id: 'a', url: 'http://a.test', token: 't' }
|
|
const config = { cacheSeconds: 15, timeoutMs: 20 } as HubConfig
|
|
const ok = () => new Response(JSON.stringify({ status: 'ok', response: { n: 1 } }), { headers: { 'content-type': 'application/json' } })
|
|
|
|
describe('Upstream', () => {
|
|
it('shares one request among reads asked at the same time', async () => {
|
|
let calls = 0
|
|
const up = new Upstream(config, (async () => {
|
|
calls++
|
|
return ok()
|
|
}) as typeof fetch)
|
|
await Promise.all([up.call(server, 'x'), up.call(server, 'x'), up.call(server, 'x')])
|
|
expect(calls).toBe(1)
|
|
})
|
|
|
|
it('names the HTTP status when a proxy answers with a page', async () => {
|
|
const up = new Upstream(config, (async () =>
|
|
new Response('Bad Gateway', { status: 502, statusText: 'Bad Gateway', headers: { 'content-type': 'text/plain' } })) as typeof fetch)
|
|
await expect(up.call(server, 'x')).rejects.toThrow('HTTP 502 Bad Gateway')
|
|
})
|
|
|
|
it('after a timeout, fails reads of that server at once for a while', async () => {
|
|
let now = 0
|
|
let calls = 0
|
|
const hang = ((_url: string, init: RequestInit) => {
|
|
calls++
|
|
return new Promise((_resolve, reject) => init.signal?.addEventListener('abort', () => reject(Object.assign(new Error('aborted'), { name: 'AbortError' }))))
|
|
}) as unknown as typeof fetch
|
|
const up = new Upstream(config, hang, () => now)
|
|
await expect(up.call(server, 'x')).rejects.toThrow('timed out after 20 ms')
|
|
await expect(up.call(server, 'y')).rejects.toThrow('timed out')
|
|
expect(calls).toBe(1)
|
|
now = 11_000
|
|
await expect(up.call(server, 'y')).rejects.toThrow('timed out')
|
|
expect(calls).toBe(2)
|
|
})
|
|
})
|