1// GET /jev/parties and /jev/parties/<id> (party.ts): the live parties, and a 2// listed one's room, given only by the room itself while it is listed. 3import { describe, expect, it } from 'vitest'; 4import { parties } from './party'; 5 6const ORIGIN = 'https://jevstrudel.example'; 7const LISTED = 'a'.repeat(64); 8const UNLISTED = 'b'.repeat(64); 9 10function env({ limited = false } = {}) { 11 const rooms: Record<string, string | null> = { [LISTED]: 'the-listed-room-0123', [UNLISTED]: null }; 12 const asked: string[] = []; 13 return { 14 asked, 15 env: { 16 PARTY_LIMIT: { limit: async () => ({ success: !limited }) }, 17 PARTY_DIRECTORY: { 18 idFromName: () => ({}), 19 get: () => ({ 20 live: async () => [ 21 { people: 2, host: true, song: 'jev/dial-up', since: 1, listed: true, id: LISTED }, 22 { people: 1, host: true, song: null, since: 2, listed: false }, 23 ], 24 }), 25 }, 26 PARTY: { 27 idFromString: (hex: string) => { 28 if (!/^[0-9a-f]{64}$/.test(hex)) throw new Error('bad id'); 29 return { hex }; 30 }, 31 get: ({ hex }: { hex: string }) => ({ 32 listedRoom: async () => { 33 asked.push(hex); 34 return rooms[hex] ?? null; 35 }, 36 }), 37 }, 38 } as never, 39 }; 40} 41const call = async (path: string, e = env()) => { 42 const res = await parties(new Request(`${ORIGIN}${path}`), e.env); 43 return { status: res.status, body: await res.json(), asked: e.asked }; 44}; 45 46describe('/jev/parties', () => { 47 it('lists the live parties, a listed one with its id', async () => { 48 const { status, body } = await call('/jev/parties'); 49 expect(status).toBe(200); 50 expect(body.parties).toHaveLength(2); 51 expect(body.parties[0]).toMatchObject({ listed: true, id: LISTED }); 52 expect(body.parties[1]).not.toHaveProperty('id'); 53 }); 54 55 it("gives a listed party's room, from the room", async () => { 56 const { status, body, asked } = await call(`/jev/parties/${LISTED}`); 57 expect(status).toBe(200); 58 expect(body).toEqual({ room: 'the-listed-room-0123' }); 59 expect(asked).toEqual([LISTED]); 60 }); 61 62 it('gives no room for a party not listed, over, or not an id', async () => { 63 expect((await call(`/jev/parties/${UNLISTED}`)).status).toBe(404); 64 const bad = await call('/jev/parties/the-listed-room-0123'); 65 expect(bad.status).toBe(404); 66 expect(bad.asked).toEqual([]); 67 }); 68 69 it('holds the rate, and reads only', async () => { 70 expect((await call('/jev/parties', env({ limited: true }))).status).toBe(429); 71 const res = await parties(new Request(`${ORIGIN}/jev/parties`, { method: 'POST' }), env().env); 72 expect(res.status).toBe(405); 73 }); 74});