diff --git a/config/quality/eslint-suppressions.json b/config/quality/eslint-suppressions.json index 7db2e6b531..539b1017e4 100644 --- a/config/quality/eslint-suppressions.json +++ b/config/quality/eslint-suppressions.json @@ -4087,11 +4087,6 @@ "count": 9 } }, - "tests/integration/qdrant-routes.test.ts": { - "@typescript-eslint/no-explicit-any": { - "count": 19 - } - }, "tests/integration/quota-pools-usage.test.ts": { "@typescript-eslint/no-unused-vars": { "count": 1 diff --git a/tests/integration/qdrant-routes.test.ts b/tests/integration/qdrant-routes.test.ts index 252c6e505f..41ffd00e79 100644 --- a/tests/integration/qdrant-routes.test.ts +++ b/tests/integration/qdrant-routes.test.ts @@ -16,6 +16,7 @@ import assert from "node:assert/strict"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; +import { NextRequest } from "next/server"; import { makeManagementSessionRequest, createManagementSessionHeaders, @@ -60,6 +61,10 @@ function makeUnauthRequest(method: "GET" | "POST" | "PUT", url: string, body?: u }); } +function toNextRequest(request: Request): NextRequest { + return new NextRequest(request); +} + async function setRequireLogin(enabled: boolean) { if (enabled) { await localDb.updateSettings({ requireLogin: true, password: "hashed-pw" }); @@ -91,7 +96,7 @@ test.after(async () => { test("GET /api/settings/qdrant — returns settings with masked API key shape", async () => { const req = await makeAuthRequest("GET", "http://localhost/api/settings/qdrant"); - const res = await qdrantSettingsRoute.GET(req as any); + const res = await qdrantSettingsRoute.GET(toNextRequest(req)); assert.strictEqual(res.status, 200); const body = await res.json(); @@ -110,7 +115,7 @@ test("GET /api/settings/qdrant — returns settings with masked API key shape", test("GET /api/settings/qdrant — 401 without auth", async () => { await setRequireLogin(true); const req = makeUnauthRequest("GET", "http://localhost/api/settings/qdrant"); - const res = await qdrantSettingsRoute.GET(req as any); + const res = await qdrantSettingsRoute.GET(toNextRequest(req)); assert.strictEqual(res.status, 401); await setRequireLogin(false); }); @@ -126,7 +131,7 @@ test("PUT /api/settings/qdrant — updates settings and returns new masked shape embeddingModel: "openai/text-embedding-3-small", }); - const res = await qdrantSettingsRoute.PUT(req as any); + const res = await qdrantSettingsRoute.PUT(toNextRequest(req)); assert.strictEqual(res.status, 200); const body = await res.json(); @@ -148,7 +153,7 @@ test("PUT enabled=true also activates Qdrant as the engine (memoryVectorStore=qd host: "qdrant-server", collection: "c", }); - const res = await qdrantSettingsRoute.PUT(req as any); + const res = await qdrantSettingsRoute.PUT(toNextRequest(req)); assert.strictEqual(res.status, 200); const s = (await localDb.getSettings()) as Record; @@ -161,16 +166,20 @@ test("PUT enabled=true also activates Qdrant as the engine (memoryVectorStore=qd test("PUT enabled=false resets the engine back to auto (sqlite-vec)", async () => { await qdrantSettingsRoute.PUT( - (await makeAuthRequest("PUT", "http://localhost/api/settings/qdrant", { - enabled: true, - host: "qdrant-server", - collection: "c", - })) as any + toNextRequest( + await makeAuthRequest("PUT", "http://localhost/api/settings/qdrant", { + enabled: true, + host: "qdrant-server", + collection: "c", + }) + ) ); await qdrantSettingsRoute.PUT( - (await makeAuthRequest("PUT", "http://localhost/api/settings/qdrant", { - enabled: false, - })) as any + toNextRequest( + await makeAuthRequest("PUT", "http://localhost/api/settings/qdrant", { + enabled: false, + }) + ) ); const s = (await localDb.getSettings()) as Record; @@ -185,9 +194,11 @@ test("PUT without the enabled field must not change memoryVectorStore", async () // User already on qdrant; editing only the collection must not reset the engine. await localDb.updateSettings({ memoryVectorStore: "qdrant", qdrantEnabled: true }); await qdrantSettingsRoute.PUT( - (await makeAuthRequest("PUT", "http://localhost/api/settings/qdrant", { - collection: "renamed", - })) as any + toNextRequest( + await makeAuthRequest("PUT", "http://localhost/api/settings/qdrant", { + collection: "renamed", + }) + ) ); const s = (await localDb.getSettings()) as Record; @@ -211,11 +222,13 @@ test("PUT enabled=true invalidates the memory-settings cache (retrieval sees qdr ); const res = await qdrantSettingsRoute.PUT( - (await makeAuthRequest("PUT", "http://localhost/api/settings/qdrant", { - enabled: true, - host: "qdrant-server", - collection: "c", - })) as any + toNextRequest( + await makeAuthRequest("PUT", "http://localhost/api/settings/qdrant", { + enabled: true, + host: "qdrant-server", + collection: "c", + }) + ) ); assert.strictEqual(res.status, 200); @@ -234,7 +247,7 @@ test("PUT /api/settings/qdrant — 400 invalid settings (invalid port type in st port: "not-a-number", }); - const res = await qdrantSettingsRoute.PUT(req as any); + const res = await qdrantSettingsRoute.PUT(toNextRequest(req)); assert.strictEqual(res.status, 400); const body = await res.json(); assert.ok(body.message || body.error, "should return error"); @@ -243,7 +256,7 @@ test("PUT /api/settings/qdrant — 400 invalid settings (invalid port type in st test("PUT /api/settings/qdrant — 401 without auth", async () => { await setRequireLogin(true); const req = makeUnauthRequest("PUT", "http://localhost/api/settings/qdrant", { enabled: true }); - const res = await qdrantSettingsRoute.PUT(req as any); + const res = await qdrantSettingsRoute.PUT(toNextRequest(req)); assert.strictEqual(res.status, 401); await setRequireLogin(false); }); @@ -257,7 +270,7 @@ test("GET /api/settings/qdrant/health — returns health result shape (qdrant di headers: Object.fromEntries(headers.entries()), }); - const res = await qdrantHealthRoute.GET(req as any); + const res = await qdrantHealthRoute.GET(toNextRequest(req)); assert.strictEqual(res.status, 200); const body = await res.json(); @@ -292,7 +305,7 @@ test("GET /api/settings/qdrant/health — reports named collection vector metada try { const req = await makeAuthRequest("GET", "http://localhost/api/settings/qdrant/health"); - const res = await qdrantHealthRoute.GET(req as any); + const res = await qdrantHealthRoute.GET(toNextRequest(req)); const body = await res.json(); assert.strictEqual(res.status, 200); @@ -309,7 +322,7 @@ test("GET /api/settings/qdrant/health — reports named collection vector metada test("GET /api/settings/qdrant/health — 401 without auth", async () => { await setRequireLogin(true); const req = makeUnauthRequest("GET", "http://localhost/api/settings/qdrant/health"); - const res = await qdrantHealthRoute.GET(req as any); + const res = await qdrantHealthRoute.GET(toNextRequest(req)); assert.strictEqual(res.status, 401); await setRequireLogin(false); }); @@ -322,7 +335,7 @@ test("POST /api/settings/qdrant/search — returns ok + results array", async () topK: 5, }); - const res = await qdrantSearchRoute.POST(req as any); + const res = await qdrantSearchRoute.POST(toNextRequest(req)); assert.strictEqual(res.status, 200); const body = await res.json(); @@ -336,7 +349,7 @@ test("POST /api/settings/qdrant/search — 400 invalid body (empty query)", asyn topK: 5, }); - const res = await qdrantSearchRoute.POST(req as any); + const res = await qdrantSearchRoute.POST(toNextRequest(req)); assert.strictEqual(res.status, 400); const body = await res.json(); assert.ok(body.message || body.error, "should return error"); @@ -346,7 +359,7 @@ test("POST /api/settings/qdrant/search — 400 invalid body (empty query)", asyn test("POST /api/settings/qdrant/cleanup — returns ok + deletedCount + retentionDays", async () => { const req = await makeAuthRequest("POST", "http://localhost/api/settings/qdrant/cleanup"); - const res = await qdrantCleanupRoute.POST(req as any); + const res = await qdrantCleanupRoute.POST(toNextRequest(req)); assert.strictEqual(res.status, 200); const body = await res.json(); @@ -365,7 +378,7 @@ test("GET /api/settings/qdrant/embedding-models — returns models array", async headers: Object.fromEntries(headers.entries()), }); - const res = await qdrantEmbeddingModelsRoute.GET(req as any); + const res = await qdrantEmbeddingModelsRoute.GET(toNextRequest(req)); // 200 expected; verify shape assert.strictEqual(res.status, 200); const body = await res.json(); @@ -387,20 +400,22 @@ test("GET /api/settings/qdrant/embedding-models — lists only configured provid headers: Object.fromEntries(headers.entries()), }); - const res = await qdrantEmbeddingModelsRoute.GET(req as any); + const res = await qdrantEmbeddingModelsRoute.GET(toNextRequest(req)); assert.strictEqual(res.status, 200); const body = await res.json(); - assert.ok(body.models.length > 0, "should list models for configured provider"); - assert.ok(body.models.every((model: any) => model.value.startsWith("openai/"))); - assert.ok(body.models.some((model: any) => model.value === "openai/text-embedding-3-small")); - const defaultModel = body.models.find((m: any) => m.value === "openai/text-embedding-3-small"); + const models: Array<{ value: string; label: string }> = body.models; + assert.ok(models.length > 0, "should list models for configured provider"); + assert.ok(models.every((model) => model.value.startsWith("openai/"))); + assert.ok(models.some((model) => model.value === "openai/text-embedding-3-small")); + const defaultModel = models.find((model) => model.value === "openai/text-embedding-3-small"); + assert.ok(defaultModel, "should include openai/text-embedding-3-small"); assert.match(defaultModel.label, /1536d/); }); test("GET /api/settings/qdrant/embedding-models — 401 without auth", async () => { await setRequireLogin(true); const req = makeUnauthRequest("GET", "http://localhost/api/settings/qdrant/embedding-models"); - const res = await qdrantEmbeddingModelsRoute.GET(req as any); + const res = await qdrantEmbeddingModelsRoute.GET(toNextRequest(req)); assert.strictEqual(res.status, 401); await setRequireLogin(false); }); @@ -416,7 +431,7 @@ test("Qdrant routes — error response has no stack trace in body", async () => body: "not-valid-json{{{", }); - const res = await qdrantSettingsRoute.PUT(req as any); + const res = await qdrantSettingsRoute.PUT(toNextRequest(req)); assert.ok(res.status >= 400, "should return error status"); const body = await res.json();