{"repo": "3280382/pi-gateway-standalone", "files": {"packages/llm-proxy/src/__tests__/models.test.ts": {"bd7229602801cf103e2355837d3c55e2c30a39ab": {"t": 1786068366.245791, "n": 3690, "h": "397a3021b0954033", "c": "/**\n * @file models.test.ts — Models endpoint tests.\n *\n * GET /v1/models returns OpenAI-compatible model list:\n * { object: \"list\", data: [{ id, object, created, owned_by }] }\n */\nimport { afterAll, beforeAll, describe, expect, it } from \"vitest\";\nimport { cleanupFixtures, createModelsJson, json, request } from \"./fixtures.js\";\n\ndescribe(\"GET /v1/models\", () => {\n beforeAll(() => {\n createModelsJson({\n openai: {\n baseUrl: \"https://api.openai.com\",\n apiKey: \"sk-openai\",\n models: [\n { id: \"gpt-4o\", name: \"GPT-4o\", contextWindow: 128000, maxTokens: 4096 },\n { id: \"gpt-4o-mini\", name: \"GPT-4o Mini\", contextWindow: 128000, maxTokens: 4096 },\n ],\n },\n deepseek: {\n baseUrl: \"https://api.deepseek.com\",\n apiKey: \"sk-deepseek\",\n models: [{ id: \"deepseek-v4-pro\", name: \"DeepSeek V4 Pro\" }],\n },\n });\n });\n\n afterAll(() => {\n cleanupFixtures();\n });\n\n it(\"returns 200 status\", async () => {\n const res = await request(\"GET\", \"/v1/models\");\n expect(res.status).toBe(200);\n });\n\n it(\"returns JSON\", async () => {\n const res = await request(\"GET\", \"/v1/models\");\n expect(res.headers[\"content-type\"]).toMatch(/application\\/json/);\n });\n\n it(\"has object: list\", async () => {\n const res = await request(\"GET\", \"/v1/models\");\n const body = json<{ object: string }>(res);\n expect(body.object).toBe(\"list\");\n });\n\n it(\"returns all models across providers\", async () => {\n const res = await request(\"GET\", \"/v1/models\");\n const body = json<{ data: unknown[] }>(res);\n expect(body.data).toHaveLength(3);\n });\n\n it(\"each model has required fields\", async () => {\n const res = await request(\"GET\", \"/v1/models\");\n const body = json<{\n data: Array<{ id: string; object: string; created: number; owned_by: string }>;\n }>(res);\n for (const m of body.data) {\n expect(m).toHaveProperty(\"id\");\n expect(m).toHaveProperty(\"object\", \"model\");\n expect(m).toHaveProperty(\"created\");\n expect(m).toHaveProperty(\"owned_by\");\n }\n });\n\n it(\"includes model IDs from both providers\", async () => {\n const res = await request(\"GET\", \"/v1/models\");\n const body = json<{ data: Array<{ id: string }> }>(res);\n const ids = body.data.map((m) => m.id).sort();\n expect(ids).toEqual([\"deepseek-v4-pro\", \"gpt-4o\", \"gpt-4o-mini\"]);\n });\n\n it(\"owned_by reflects provider baseUrl\", async () => {\n const res = await request(\"GET\", \"/v1/models\");\n const body = json<{ data: Array<{ owned_by: string }> }>(res);\n const openaiModels = body.data.filter((m) => m.owned_by === \"https://api.openai.com\");\n expect(openaiModels).toHaveLength(2);\n });\n});\n\ndescribe(\"GET /models (short alias)\", () => {\n beforeAll(() => {\n createModelsJson({\n test: {\n baseUrl: \"https://api.test.com\",\n apiKey: \"sk-test\",\n models: [{ id: \"test-model\", name: \"Test Model\" }],\n },\n });\n });\n\n afterAll(() => {\n cleanupFixtures();\n });\n\n it(\"GET /models also works\", async () => {\n const res = await request(\"GET\", \"/models\");\n expect(res.status).toBe(200);\n const body = json<{ object: string; data: unknown[] }>(res);\n expect(body.object).toBe(\"list\");\n expect(body.data).toHaveLength(1);\n });\n});\n\ndescribe(\"GET /v1/models — empty config\", () => {\n beforeAll(() => {\n createModelsJson({});\n });\n\n afterAll(() => {\n cleanupFixtures();\n });\n\n it(\"returns empty data array with no models\", async () => {\n const res = await request(\"GET\", \"/v1/models\");\n expect(res.status).toBe(200);\n const body = json<{ data: unknown[] }>(res);\n expect(body.data).toEqual([]);\n });\n});\n"}}}}