Something went wrong. Try again.
Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
Something went wrong. Try again.
6.0 kB · 205 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206import { describe, expect, test } from 'bun:test'
// /health fails closed when Redis invalidation is configured but not attached.// A developer with REDIS_URL in their `.env` would otherwise get a 503 here and// CI would get a 200, for reasons that have nothing to do with the code.process.env.REDIS_URL = ''
const { default: app, getCacheInvalidationHealthResponse, normalizeConfiguredHostname, resolveHostConfig,} = await import('./server')
describe('hosting server', () => { test('serves a compact cache invalidation health payload', async () => { const response = await app.request('https://wisp.place/health') const body = (await response.json()) as { status: string cacheInvalidation: Record<string, unknown> }
expect(response.status).toBe(200) expect(['ok', 'degraded']).toContain(body.status) expect(Object.keys(body.cacheInvalidation).sort()).toEqual([ 'configured', 'gapCount', 'lastGapAt', 'lastGapRecoveryAt', 'replayConnected', 'replayState', 'retrying', 'subscriberConnected', 'subscriberRecreations', ]) expect(typeof body.cacheInvalidation.configured).toBe('boolean') expect(typeof body.cacheInvalidation.replayConnected).toBe('boolean') expect(typeof body.cacheInvalidation.subscriberConnected).toBe('boolean') expect(typeof body.cacheInvalidation.gapCount).toBe('number') })
test('normalizes configured hosts without accepting URL credentials', () => { expect(normalizeConfiguredHostname('WISP.PLACE:443', 'fallback.example')).toBe('wisp.place') expect(normalizeConfiguredHostname('user:secret@wisp.place', 'fallback.example')).toBe('fallback.example') })
test('derives every router host from one environment object', () => { expect(resolveHostConfig({})).toEqual({ baseHost: 'wisp.place', sharedSitesHost: 'sites.wisp.place', privateHost: 'priv.wisp.place', previewHost: null, }) })
test('derives the private and shared hosts from a configured base host', () => { expect(resolveHostConfig({ BASE_HOST: 'wisp.localhost:3001' })).toEqual({ baseHost: 'wisp.localhost', sharedSitesHost: 'sites.wisp.localhost', privateHost: 'priv.wisp.localhost', previewHost: null, }) })
// A local `.env` with a port attached is what silently changed 404 reasons // across machines, so the override has to win over the base host's default. test('lets private and preview hosts be overridden independently', () => { expect( resolveHostConfig({ BASE_HOST: 'wisp.place', PRIVATE_HOST: 'PRIVATE.EXAMPLE', PREVIEW_HOST: 'try.place' }), ).toEqual({ baseHost: 'wisp.place', sharedSitesHost: 'sites.wisp.place', privateHost: 'private.example', previewHost: 'try.place', }) })
test('uses the normalized URL hostname for DNS-hash routing', async () => { const response = await app.request( new Request('https://0123456789ABCDEF.dns.NOT..VALID:8443/assets/app.js', { headers: { host: 'sites.wisp.place' }, }), )
expect(response.status).toBe(400) expect(await response.text()).toBe('Invalid base domain') })
test('reports an unhealthy configured replay without exposing its cursor', () => { const response = getCacheInvalidationHealthResponse( { subscriberConnected: true, replayConnected: false, replayState: 'gap', cursor: 'internal-stream-cursor', lastEventAt: null, lastErrorAt: null, lastGapAt: 123, gapCount: 1, lastGapRecoveryAt: null, retrying: true, subscriberRecreations: 0, }, true, { configured: true, status: 'healthy', breaker: 'closed', consecutiveFailures: 0, totalFailures: 0, totalSuccesses: 1, circuitRejections: 0, lastSuccessAt: 123, lastFailureAt: null, lastErrorKind: null, lastSuccessAgeMs: 0, }, )
expect(response).toEqual({ status: 'degraded', cacheInvalidation: { configured: true, subscriberConnected: true, replayConnected: false, replayState: 'gap', retrying: true, gapCount: 1, lastGapAt: 123, lastGapRecoveryAt: null, subscriberRecreations: 0, }, storage: { configured: true, status: 'healthy', breaker: 'closed', consecutiveFailures: 0, circuitRejections: 0, lastSuccessAgeMs: 0, lastErrorKind: null, }, }) expect(JSON.stringify(response)).not.toContain('internal-stream-cursor') })
test('fails closed when the pub/sub subscriber is down even if replay is healthy', () => { const response = getCacheInvalidationHealthResponse( { subscriberConnected: false, replayConnected: true, replayState: 'healthy', cursor: 'internal-stream-cursor', lastEventAt: 1, lastErrorAt: null, lastGapAt: null, gapCount: 0, lastGapRecoveryAt: null, retrying: false, subscriberRecreations: 2, }, true, { configured: true, status: 'healthy', breaker: 'closed', consecutiveFailures: 0, totalFailures: 0, totalSuccesses: 1, circuitRejections: 0, lastSuccessAt: 1, lastFailureAt: null, lastErrorKind: null, lastSuccessAgeMs: 0, }, )
expect(response.status).toBe('degraded') expect(response.cacheInvalidation.subscriberConnected).toBe(false) expect(response.cacheInvalidation.subscriberRecreations).toBe(2) })
test('serves a liveness-only /live endpoint', async () => { const response = await app.request('https://wisp.place/live') expect(response.status).toBe(200) expect((await response.json()) as { status: string }).toEqual({ status: 'ok' }) })})
test('rejects unsafe decoded paths before routing', async () => { const unsafePaths = [ '/assets%2f..%2fsecret.txt', '/%2e%2e%2fsecret.txt', '/..%5csecret.txt', '/safe%00name.txt', '/C:%2fWindows%2fsystem.ini', '/nested//file.txt', `/${'a'.repeat(4097)}`, ]
for (const path of unsafePaths) { const response = await app.request(`https://wisp.place${path}`) expect(response.status).toBe(400) expect(['Invalid path', 'Invalid URL encoding']).toContain(await response.text()) }})