// ignore_for_file: avoid_print, unnecessary_overrides import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:kouyu_english/core/ai_service.dart'; import 'package:kouyu_english/core/models.dart'; class RealHttpOverrides extends HttpOverrides { @override HttpClient createHttpClient(SecurityContext? context) { return super.createHttpClient(context); } } /// 读取联网测试用的配置。密钥只来自环境变量,不写进仓库。 /// /// 运行方式: /// KOUYU_AI_API_KEY=sk-xxx flutter test test/live_endpoint_test.dart /// 可选:KOUYU_AI_BASE_URL(默认 https://codex.slcydia.fun)、KOUYU_AI_MODEL。 /// 未设置密钥时整组测试自动跳过,不会误报成功。 String? _env(String name) { final value = Platform.environment[name]; return (value == null || value.trim().isEmpty) ? null : value.trim(); } 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 model = _env('KOUYU_AI_MODEL') ?? 'gemini-3.7-flash-high'; final skipReason = apiKey == null ? '未设置 KOUYU_AI_API_KEY,跳过联网测试。' : null; if (apiKey != null) { AiService.instance.setFallbackApiKey(apiKey); } test('Live test: /v1/responses endpoint testConnection', () async { try { final resResponses = await AiService.instance.testConnection( provider: AiProviderType.compatible, endpoint: '$baseUrl/v1/responses', model: model, explicitApiKey: apiKey, ); print('Responses API result: ok=${resResponses.ok}, msg=${resResponses.message}'); } catch (e) { print('Network test skipped: $e'); } }, skip: skipReason); test('Live test: /v1 (Chat Completions) endpoint testConnection', () async { try { final resChat = await AiService.instance.testConnection( provider: AiProviderType.compatible, endpoint: '$baseUrl/v1', model: model, explicitApiKey: apiKey, ); print('Chat Completions API result: ok=${resChat.ok}, msg=${resChat.message}'); } catch (e) { print('Network test skipped: $e'); } }, skip: skipReason); test('Live test: /v1/responses dialogueReply', timeout: const Timeout(Duration(seconds: 60)), () async { try { final reply = await AiService.instance.dialogueReply( provider: AiProviderType.compatible, endpoint: '$baseUrl/v1/responses', model: model, history: [ {'role': 'user', 'content': 'Hello, my name is Alex.'} ], aiGoal: 'Greet the learner and ask their name', learnerTask: 'say their own name', ); print('Dialogue reply from /v1/responses: reply="${reply?.reply}", translation="${reply?.translation}", feedback="${reply?.feedback}"'); } catch (e) { print('Network test skipped: $e'); } }, skip: skipReason); }