profileShare

rasmusjy / roundtable

Read-only snapshot

No repository description.

main default branch 181 files Expires Sep 13, 2026, 9:06 AM
repositories.test.ts 1,457 bytes
1 import { beforeEach, describe, expect, it, vi } from 'vitest';
2
3 const prisma = vi.hoisted(() => ({
4 debate: {
5 updateMany: vi.fn(),
6 findUnique: vi.fn(),
7 },
8 }));
9
10 vi.mock('./client', () => ({ prisma }));
11
12 import { ensureShareToken } from './repositories';
13
14 describe('ensureShareToken', () => {
15 beforeEach(() => {
16 prisma.debate.updateMany.mockReset();
17 prisma.debate.findUnique.mockReset();
18 });
19
20 it('claims an empty share token without a preliminary read', async () => {
21 prisma.debate.updateMany.mockResolvedValue({ count: 1 });
22
23 const token = await ensureShareToken('debate-1');
24
25 expect(token).toMatch(/^[A-Za-z0-9_-]{24}$/);
26 expect(prisma.debate.updateMany).toHaveBeenCalledWith({
27 where: { id: 'debate-1', shareToken: null },
28 data: { shareToken: token },
29 });
30 expect(prisma.debate.findUnique).not.toHaveBeenCalled();
31 });
32
33 it('returns the token claimed by a concurrent request', async () => {
34 prisma.debate.updateMany.mockResolvedValue({ count: 0 });
35 prisma.debate.findUnique.mockResolvedValue({ shareToken: 'existing-token' });
36
37 await expect(ensureShareToken('debate-1')).resolves.toBe('existing-token');
38 });
39
40 it('fails when the debate no longer exists', async () => {
41 prisma.debate.updateMany.mockResolvedValue({ count: 0 });
42 prisma.debate.findUnique.mockResolvedValue(null);
43
44 await expect(ensureShareToken('missing')).rejects.toThrow('Debate not found');
45 });
46 });
47