import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart' as http; import 'package:http/testing.dart'; import 'package:kouyu_english/core/ai_service.dart'; import 'package:kouyu_english/core/models.dart'; void main() { const definition = '{"definition":"苹果"}'; Future> captureBody(String endpoint) async { AiService.instance.setFallbackApiKey('test-key'); Map? body; final result = await http.runWithClient( () => AiService.instance.temporaryDefinition( provider: AiProviderType.compatible, endpoint: endpoint, model: 'deepseek-flash', text: 'apple', ), () => MockClient((request) async { body = jsonDecode(request.body) as Map; return http.Response( jsonEncode({ 'choices': [ { 'message': {'content': definition}, }, ], 'output_text': definition, }), 200, headers: {'content-type': 'application/json; charset=utf-8'}, ); }), ); expect(result, '苹果'); return body!; } test('DeepSeek chat completions request disables thinking', () async { final body = await captureBody('https://api.deepseek.com'); expect(body['thinking'], {'type': 'disabled'}); expect(body['response_format'], {'type': 'json_object'}); expect(body.containsKey('reasoning_effort'), isFalse); expect(body['max_tokens'], 200); }); test('DeepSeek responses request sets reasoning effort to none', () async { final body = await captureBody('https://api.deepseek.com/v1/responses'); expect(body['reasoning'], {'effort': 'none'}); expect(body['text'], { 'format': {'type': 'json_object'}, }); expect(body.containsKey('reasoning_effort'), isFalse); expect(body.containsKey('thinking'), isFalse); }); test('other compatible endpoints keep their original payload', () async { final body = await captureBody('https://example.test/v1'); expect(body.containsKey('thinking'), isFalse); expect(body.containsKey('response_format'), isFalse); expect(body['reasoning_effort'], 'low'); }); test('dialogue history replays earlier AI lines as JSON', () async { AiService.instance.setFallbackApiKey('test-key'); List? messages; final reply = await http.runWithClient( () => AiService.instance.dialogueReply( provider: AiProviderType.compatible, endpoint: 'https://api.deepseek.com', model: 'deepseek-flash', aiGoal: 'Ask where the learner is from.', learnerTask: 'say where they are from', history: const [ {'role': 'assistant', 'content': "Hi! What's your name?"}, {'role': 'user', 'content': 'My name is Alex.'}, ], ), () => MockClient((request) async { final body = jsonDecode(request.body) as Map; messages = body['messages'] as List; return http.Response( jsonEncode({ 'choices': [ { 'message': {'content': '{"reply":"Where are you from?"}'}, }, ], }), 200, headers: {'content-type': 'application/json; charset=utf-8'}, ); }), ); expect(reply?.reply, 'Where are you from?'); expect(messages, hasLength(3)); expect(messages![0]['role'], 'system'); expect(jsonDecode(messages![1]['content'] as String), { 'reply': "Hi! What's your name?", }); expect(messages![2], {'role': 'user', 'content': 'My name is Alex.'}); }); }