import { expect, test } from "@playwright/test"; import { defaultProductPlanningApiConfig, normalizeProductPlanningApiConfig, PRODUCT_PLANNING_API_CONFIG_KEY, type ProductPlanningApiConfig, } from "@/lib/product-planning/config"; import { defaultProductPlanningAiModelConfig, normalizeProductPlanningAiModelConfig, toProductPlanningOpenAIBaseUrl, type ProductPlanningAiModelConfig, } from "@/lib/product-planning/model-config"; test.describe.serial("/api/admin/settings", () => { test("guest cannot read product planning system config", async ({ request }) => { const response = await request.get( `/api/admin/settings?key=${PRODUCT_PLANNING_API_CONFIG_KEY}` ); expect(response.status()).toBe(401); const payload = await response.json(); expect(payload).toMatchObject({ error: "未授权,请先登录", }); }); test("product planning config normalization trims values and falls back to defaults", () => { const defaults = defaultProductPlanningApiConfig(); const expectedValue: ProductPlanningApiConfig = { oneboundBaseUrl: "https://api.example.com/onebound", taobaoApiKey: "demo-key", taobaoApiSecret: "demo-secret", qaApiUrl: defaults.qaApiUrl, qaToken: "qa-token", saleApiUrl: "http://sales.example.com/api", saleToken: "sale-token", }; const normalized = normalizeProductPlanningApiConfig({ oneboundBaseUrl: " https://api.example.com/onebound/// ", taobaoApiKey: " demo-key ", taobaoApiSecret: " demo-secret ", qaApiUrl: " ", qaToken: " qa-token ", saleApiUrl: " http://sales.example.com/api/// ", saleToken: " sale-token ", }); expect(normalized).toEqual(expectedValue); }); test("product planning config normalization can reuse fallback secrets and urls", () => { const normalized = normalizeProductPlanningApiConfig( { oneboundBaseUrl: " ", taobaoApiKey: "", taobaoApiSecret: " custom-secret ", qaApiUrl: "", qaToken: " ", saleApiUrl: " ", saleToken: "", }, { oneboundBaseUrl: "https://fallback.example.com/root/", taobaoApiKey: "fallback-key", taobaoApiSecret: "fallback-secret", qaApiUrl: "https://fallback.example.com/qa/", qaToken: "fallback-qa-token", saleApiUrl: "https://fallback.example.com/sale/", saleToken: "fallback-sale-token", } ); expect(normalized).toEqual({ oneboundBaseUrl: "https://fallback.example.com/root", taobaoApiKey: "fallback-key", taobaoApiSecret: "custom-secret", qaApiUrl: "https://fallback.example.com/qa", qaToken: "fallback-qa-token", saleApiUrl: "https://fallback.example.com/sale", saleToken: "fallback-sale-token", } satisfies ProductPlanningApiConfig); }); test("product planning dedicated model config normalization trims values and keeps defaults", () => { const defaults = defaultProductPlanningAiModelConfig(); const normalized = normalizeProductPlanningAiModelConfig({ enabled: true, providerName: " Planning Qwen ", baseUrl: " http://103.118.245.6:6081/// ", apiKey: " secret-token ", modelId: " custom-qwen3-vl ", displayName: " 商品策划专用模型 ", }); expect(normalized).toEqual({ enabled: true, providerName: "Planning Qwen", baseUrl: "http://103.118.245.6:6081", apiKey: "secret-token", modelId: "custom-qwen3-vl", displayName: "商品策划专用模型", } satisfies ProductPlanningAiModelConfig); const fallbackNormalized = normalizeProductPlanningAiModelConfig({ enabled: false, providerName: " ", baseUrl: " ", apiKey: " ", modelId: "", displayName: "", }); expect(fallbackNormalized).toEqual(defaults); }); test("product planning dedicated model base url can auto-complete v1 path", () => { expect(toProductPlanningOpenAIBaseUrl("http://103.118.245.6:6081")).toBe( "http://103.118.245.6:6081/v1" ); expect(toProductPlanningOpenAIBaseUrl("http://103.118.245.6:6081/v1/")).toBe( "http://103.118.245.6:6081/v1" ); }); });