profileShare

rasmusjy / roundtable

Read-only snapshot

No repository description.

main default branch 181 files Expires Sep 13, 2026, 9:06 AM
model-cache.test.ts 2,022 bytes
1 import { beforeEach, describe, expect, it, vi } from 'vitest';
2 import type { OpenRouterModel } from './openrouter';
3
4 const mocks = vi.hoisted(() => ({
5 fetchOpenRouterModels: vi.fn(),
6 pricingFromModels: vi.fn(),
7 }));
8
9 vi.mock('./env', () => ({ env: { MOCK_LLM: false } }));
10 vi.mock('./openrouter', () => mocks);
11
12 const catalog: OpenRouterModel[] = [
13 {
14 id: 'vendor/model',
15 name: 'Model',
16 context_length: 32_000,
17 pricing: { prompt: '0.000001', completion: '0.000002' },
18 },
19 ];
20
21 describe('getModels', () => {
22 beforeEach(() => {
23 vi.resetModules();
24 mocks.fetchOpenRouterModels.mockReset();
25 mocks.pricingFromModels.mockReset();
26 });
27
28 it('shares one catalog request between concurrent callers', async () => {
29 let resolveCatalog: ((models: OpenRouterModel[]) => void) | undefined;
30 mocks.fetchOpenRouterModels.mockReturnValue(
31 new Promise<OpenRouterModel[]>((resolve) => {
32 resolveCatalog = resolve;
33 }),
34 );
35 const { getModels } = await import('./model-cache');
36
37 const first = getModels();
38 const second = getModels();
39
40 expect(mocks.fetchOpenRouterModels).toHaveBeenCalledTimes(1);
41 resolveCatalog?.(catalog);
42 await expect(Promise.all([first, second])).resolves.toEqual([catalog, catalog]);
43 });
44
45 it('reuses the cached catalog after a request completes', async () => {
46 mocks.fetchOpenRouterModels.mockResolvedValue(catalog);
47 const { getModels } = await import('./model-cache');
48
49 await getModels();
50 await getModels();
51
52 expect(mocks.fetchOpenRouterModels).toHaveBeenCalledTimes(1);
53 });
54
55 it('shares the fallback catalog when a request fails', async () => {
56 mocks.fetchOpenRouterModels.mockRejectedValue(new Error('offline'));
57 const { getModels } = await import('./model-cache');
58
59 const [first, second] = await Promise.all([getModels(), getModels()]);
60
61 expect(mocks.fetchOpenRouterModels).toHaveBeenCalledTimes(1);
62 expect(first).toBe(second);
63 expect(first.length).toBeGreaterThan(0);
64 });
65 });
66