// api_client_test.dart — ApiClient 鉴权 + 401 自动刷新重试。 import 'package:flutter_test/flutter_test.dart'; import 'package:http/testing.dart'; import 'package:http/http.dart' as http; import 'package:pangolin_vpn/services/api_client.dart'; import 'package:pangolin_vpn/services/auth_api.dart'; void main() { group('ApiClient', () { test('GET 附带 Bearer 并解析 JSON', () async { late String seenAuth; final c = ApiClient( baseUrl: 'http://x', getToken: () => 'tok1', refresh: () async => false, client: MockClient((req) async { seenAuth = req.headers['Authorization'] ?? ''; return http.Response('{"email":"a@b.c"}', 200); }), ); final body = await c.getJson('/v1/me'); expect(seenAuth, 'Bearer tok1'); expect(body['email'], 'a@b.c'); }); test('401 → refresh 成功 → 用新令牌重试一次', () async { var token = 'old'; var calls = 0; final c = ApiClient( baseUrl: 'http://x', getToken: () => token, refresh: () async { token = 'new'; return true; }, client: MockClient((req) async { calls++; if (req.headers['Authorization'] == 'Bearer old') { return http.Response('{"message_zh":"expired"}', 401); } return http.Response('{"ok":true}', 200); }), ); final body = await c.getJson('/v1/me'); expect(calls, 2); // 首次 401 + 刷新后重试 expect(body['ok'], true); }); test('401 → refresh 失败 → 抛 AuthApiException(401)', () async { final c = ApiClient( baseUrl: 'http://x', getToken: () => 'old', refresh: () async => false, client: MockClient((req) async => http.Response('{"message_zh":"expired"}', 401)), ); expect( () => c.getJson('/v1/me'), throwsA(isA().having((e) => e.statusCode, 'status', 401)), ); }); }); }