Files
platforms/apps/service_app/test/data/api_client_test.dart

116 lines
3.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 功能描述:验证工作人员端统一请求的鉴权失效通知和上传处理。
// 版本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 = <String>[];
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<SessionExpiredException>()),
);
expect(rejectedTokens, ['JWT expired-token']);
});
test('受保护接口返回鉴权业务码时通知会话', () async {
final rejectedTokens = <String>[];
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<SessionExpiredException>()),
);
expect(rejectedTokens, ['JWT expired-token']);
});
test('未鉴权接口返回 401 时不得清理已有会话', () async {
final rejectedTokens = <String>[];
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<ApiException>()
.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 = <String>[];
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<SessionExpiredException>()),
);
expect(rejectedTokens, ['JWT old-token']);
});
test('文件上传返回鉴权业务码时同样触发统一会话失效', () async {
final rejectedTokens = <String>[];
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<SessionExpiredException>()),
);
expect(rejectedTokens, ['JWT expired-token']);
});
}