import { afterAll, beforeAll, describe, expect, it } from 'vitest' import { KVStorageHttp } from '../../src/kv-storage/kv-storage-http.js' import { KVStorageHttpServer } from '../../src/kv-storage/kv-storage-http-server.js' import { KVStorageInMemory } from '../../src/kv-storage/kv-storage-in-memory.js' import { EventStorageKV } from '../../src/event-storage/event-storage-kv.js' import { DocumentStorageKV } from '../../src/document-storage/document-storage-kv.js' import { EventSourcedDocumentStorage } from '../../src/document-storage/event-sourced-document-storage.js' import { runKVStorageConformance } from './kv-storage.conformance.js' import { serve } from './node-server.js' runKVStorageConformance('KVStorageHttp (in-process)', () => { const server = new KVStorageHttpServer(new KVStorageInMemory(), { auth: 'none', basePath: '/kv' }) return new KVStorageHttp({ url: 'http://test/kv', fetch: async (input, init) => server.handle(new Request(input, init)) }) }) describe('over a real socket', () => { let server: Awaited> const stores: KVStorageHttpServer[] = [] beforeAll(async () => { // One socket; each test storage gets its own backend under /. server = await serve((request) => stores[Number(new URL(request.url).pathname.split('/')[1])]!.handle(request)) }) afterAll(() => server.close()) const fresh = () => { stores.push(new KVStorageHttpServer(new KVStorageInMemory(), { auth: 'none', basePath: `/${stores.length}` })) return new KVStorageHttp({ url: `${server.url}/${stores.length - 1}` }) } runKVStorageConformance('KVStorageHttp (node:http)', fresh) it('stops a long scan early', async () => { const db = fresh() await db.writeMany(Array.from({ length: 5000 }, (_, i) => [`k${String(i).padStart(5, '0')}`, i] as [string, number])) const seen: string[] = [] for await (const [key] of db.scan()) if (seen.push(key) === 3) break expect(seen).toEqual(['k00000', 'k00001', 'k00002']) }) it('runs events and event-sourced documents over HTTP', async () => { const kv = fresh() const docs = new EventSourcedDocumentStorage(new EventStorageKV(kv), new DocumentStorageKV(kv.child('projections'))) const id = await docs.child('people').insert({ email: 'a@x', n: 1 }) await docs.child('people').update(id, { $inc: { n: 1 } }) expect(await docs.child('people').findOne({ email: 'a@x' })).toEqual({ key: id, data: { email: 'a@x', n: 2 } }) }) }) describe('server', () => { it('maps errors to 404 / 500', async () => { const server = new KVStorageHttpServer(new KVStorageInMemory(), { auth: 'none' }) expect((await server.handle(new Request('http://x/nope', { method: 'POST', body: '{}' }))).status).toBe(404) expect((await server.handle(new Request('http://x/readMany', { method: 'POST', body: '{"keys": 5}' }))).status).toBe(500) }) })