// 功能描述:验证工作人员端统一请求的鉴权失效通知和上传处理。 // 版本:1.0.0 import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart' as http; import 'package:http/testing.dart'; import 'package:image_picker/image_picker.dart'; import 'package:service_app/data/services/api_client.dart'; /// 覆盖 HTTP 状态、业务码、匿名请求、请求令牌快照和上传场景。 void main() { test('受保护接口返回 HTTP 401 时通知会话并抛出专用异常', () async { final rejectedTokens = []; final client = ApiClient( () => 'JWT expired-token', baseUrl: 'https://api.example.com', onUnauthorized: rejectedTokens.add, client: MockClient((request) async => http.Response('', 401)), ); await expectLater( client.get('/protected'), throwsA(isA()), ); expect(rejectedTokens, ['JWT expired-token']); }); test('受保护接口返回鉴权业务码时通知会话', () async { final rejectedTokens = []; final client = ApiClient( () => 'JWT expired-token', baseUrl: 'https://api.example.com', onUnauthorized: rejectedTokens.add, client: MockClient( (request) async => http.Response( '{"code":1308,"message":"Token Expired","details":null}', 200, ), ), ); await expectLater( client.get('/protected'), throwsA(isA()), ); expect(rejectedTokens, ['JWT expired-token']); }); test('未鉴权接口返回 401 时不得清理已有会话', () async { final rejectedTokens = []; final client = ApiClient( () => 'JWT current-token', baseUrl: 'https://api.example.com', onUnauthorized: rejectedTokens.add, client: MockClient((request) async => http.Response('', 401)), ); await expectLater( client.post('/login', authenticated: false), throwsA( isA() .having((error) => error.code, 'code', 401) .having((error) => error is SessionExpiredException, 'session expired', isFalse), ), ); expect(rejectedTokens, isEmpty); }); test('请求发送后令牌变化时仍上报实际被拒绝的旧令牌', () async { var currentToken = 'JWT old-token'; final rejectedTokens = []; final client = ApiClient( () => currentToken, baseUrl: 'https://api.example.com', onUnauthorized: rejectedTokens.add, client: MockClient((request) async { currentToken = 'JWT new-token'; return http.Response('', 401); }), ); await expectLater( client.get('/protected'), throwsA(isA()), ); expect(rejectedTokens, ['JWT old-token']); }); test('文件上传返回鉴权业务码时同样触发统一会话失效', () async { final rejectedTokens = []; final client = ApiClient( () => 'JWT expired-token', baseUrl: 'https://api.example.com', onUnauthorized: rejectedTokens.add, client: MockClient( (request) async => http.Response( '{"code":1715,"message":"Unauthorized","details":null}', 200, ), ), ); final file = XFile.fromData( Uint8List.fromList(const [1, 2, 3]), name: 'proof.jpg', mimeType: 'image/jpeg', ); await expectLater( client.upload(file), throwsA(isA()), ); expect(rejectedTokens, ['JWT expired-token']); }); }