chore: 联网测试密钥改从环境变量读取

live_endpoint_test.dart 里硬编码了一个真实 API key。改为读取
KOUYU_AI_API_KEY(可选 KOUYU_AI_BASE_URL、KOUYU_AI_MODEL),未设置时
整组测试跳过,不再把缺少凭据的联网测试当成通过。

注意:旧 key 仍留在提交历史中,需要在服务端作废并重新签发。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-16 16:40:54 +09:00
co-authored by Claude Opus 5
parent 61abc69037
commit d04a4903e8
+33 -15
View File
@@ -11,56 +11,74 @@ 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。
/// 未设置密钥时整组测试自动跳过,不会误报成功。
String? _env(String name) {
final value = Platform.environment[name];
return (value == null || value.trim().isEmpty) ? null : value.trim();
}
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
HttpOverrides.global = RealHttpOverrides(); HttpOverrides.global = RealHttpOverrides();
const testKey = '***REMOVED***';
AiService.instance.setFallbackApiKey(testKey); 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 { test('Live test: /v1/responses endpoint testConnection', () async {
try { try {
final resResponses = await AiService.instance.testConnection( final resResponses = await AiService.instance.testConnection(
provider: AiProviderType.compatible, provider: AiProviderType.compatible,
endpoint: 'https://codex.slcydia.fun/v1/responses', endpoint: '$baseUrl/v1/responses',
model: 'gemini-3.7-flash-high', model: model,
explicitApiKey: testKey, explicitApiKey: apiKey,
); );
print('Responses API result: ok=${resResponses.ok}, msg=${resResponses.message}'); print('Responses API result: ok=${resResponses.ok}, msg=${resResponses.message}');
} catch (e) { } catch (e) {
print('Network test skipped: $e'); print('Network test skipped: $e');
} }
}); }, skip: skipReason);
test('Live test: /v1 (Chat Completions) endpoint testConnection', () async { test('Live test: /v1 (Chat Completions) endpoint testConnection', () async {
try { try {
final resChat = await AiService.instance.testConnection( final resChat = await AiService.instance.testConnection(
provider: AiProviderType.compatible, provider: AiProviderType.compatible,
endpoint: 'https://codex.slcydia.fun/v1', endpoint: '$baseUrl/v1',
model: 'gemini-3.7-flash-high', model: model,
explicitApiKey: testKey, explicitApiKey: apiKey,
); );
print('Chat Completions API result: ok=${resChat.ok}, msg=${resChat.message}'); print('Chat Completions API result: ok=${resChat.ok}, msg=${resChat.message}');
} catch (e) { } catch (e) {
print('Network test skipped: $e'); print('Network test skipped: $e');
} }
}); }, skip: skipReason);
test('Live test: /v1/responses dialogueReply', timeout: const Timeout(Duration(seconds: 60)), () async { test('Live test: /v1/responses dialogueReply', timeout: const Timeout(Duration(seconds: 60)), () async {
try { try {
final reply = await AiService.instance.dialogueReply( final reply = await AiService.instance.dialogueReply(
provider: AiProviderType.compatible, provider: AiProviderType.compatible,
endpoint: 'https://codex.slcydia.fun/v1/responses', endpoint: '$baseUrl/v1/responses',
model: 'gemini-3.7-flash-high', model: model,
history: [ history: [
{'role': 'user', 'content': 'Hello, my name is Alex.'} {'role': 'user', 'content': 'Hello, my name is Alex.'}
], ],
aiGoal: 'Greet the learner and ask their name', aiGoal: 'Greet the learner and ask their name',
learnerTask: 'say their own name', learnerTask: 'say their own name',
); );
print('Dialogue reply from /v1/responses: reply="${reply?.reply}", slots=${reply?.slots}, suggestsComplete=${reply?.suggestsComplete}'); print('Dialogue reply from /v1/responses: reply="${reply?.reply}", translation="${reply?.translation}", feedback="${reply?.feedback}"');
} catch (e) { } catch (e) {
print('Network test skipped: $e'); print('Network test skipped: $e');
} }
}); }, skip: skipReason);
} }