From c2361c5c3af404a27d38512e1ed5e1f2ab2121bf Mon Sep 17 00:00:00 2001 From: shenlei Date: Wed, 16 Sep 2026 16:42:58 +0900 Subject: [PATCH] =?UTF-8?q?chore:=20=E8=81=94=E7=BD=91=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=AB=AF=E7=82=B9=E5=8F=98=E9=87=8F=E6=8E=A5=E5=8F=97=E5=AE=8C?= =?UTF-8?q?=E6=95=B4=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 应用里配置的地址本身就带 /v1/responses,直接当基址拼接会变成 .../v1/responses/v1/responses。改用 KOUYU_AI_ENDPOINT,填完整端点或 基址都可以,内部归一化后再拼出待测的两个端点,并补一条不联网的归一化测试。 Co-Authored-By: Claude Opus 5 --- kouyu_english/test/live_endpoint_test.dart | 33 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/kouyu_english/test/live_endpoint_test.dart b/kouyu_english/test/live_endpoint_test.dart index f838fb6..9c80514 100644 --- a/kouyu_english/test/live_endpoint_test.dart +++ b/kouyu_english/test/live_endpoint_test.dart @@ -15,19 +15,40 @@ class RealHttpOverrides extends HttpOverrides { /// /// 运行方式: /// KOUYU_AI_API_KEY=sk-xxx flutter test test/live_endpoint_test.dart -/// 可选:KOUYU_AI_BASE_URL(默认 https://codex.slcydia.fun)、KOUYU_AI_MODEL。 +/// 可选:KOUYU_AI_ENDPOINT、KOUYU_AI_MODEL。 /// 未设置密钥时整组测试自动跳过,不会误报成功。 String? _env(String name) { final value = Platform.environment[name]; return (value == null || value.trim().isEmpty) ? null : value.trim(); } +/// KOUYU_AI_ENDPOINT 可以直接填应用里配置的那个完整地址(通常带 +/// /v1/responses)。这里把它归一化成服务基址,再拼出要测的两个端点, +/// 避免出现 .../v1/responses/v1/responses。 +String _serviceBase(String endpoint) { + var value = endpoint.trim().replaceFirst(RegExp(r'/+$'), ''); + for (final suffix in const [ + '/v1/responses', + '/v1/chat/completions', + '/responses', + '/chat/completions', + '/v1', + ]) { + if (value.endsWith(suffix)) { + return value.substring(0, value.length - suffix.length); + } + } + return value; +} + void main() { TestWidgetsFlutterBinding.ensureInitialized(); HttpOverrides.global = RealHttpOverrides(); final apiKey = _env('KOUYU_AI_API_KEY'); - final baseUrl = _env('KOUYU_AI_BASE_URL') ?? 'https://codex.slcydia.fun'; + final baseUrl = _serviceBase( + _env('KOUYU_AI_ENDPOINT') ?? 'https://codex.slcydia.fun/v1/responses', + ); final model = _env('KOUYU_AI_MODEL') ?? 'gemini-3.7-flash-high'; final skipReason = apiKey == null ? '未设置 KOUYU_AI_API_KEY,跳过联网测试。' @@ -36,6 +57,14 @@ void main() { AiService.instance.setFallbackApiKey(apiKey); } + // 这条不联网,只保证端点归一化不会拼出重复路径。 + test('KOUYU_AI_ENDPOINT 可以直接填完整端点', () { + expect(_serviceBase('https://host/v1/responses'), 'https://host'); + expect(_serviceBase('https://host/v1/chat/completions'), 'https://host'); + expect(_serviceBase('https://host/v1/'), 'https://host'); + expect(_serviceBase('https://host'), 'https://host'); + }); + test('Live test: /v1/responses endpoint testConnection', () async { try { final resResponses = await AiService.instance.testConnection(