Files
platforms/apps/user_app/test/app/user_session_test.dart
2026-09-04 21:54:35 +08:00

79 lines
2.3 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 'package:flutter_test/flutter_test.dart';
import 'package:user_app/app/dependencies.dart';
import 'package:user_app/data/services/secure_session_store.dart';
/// 提供可观测的内存令牌存储,避免测试依赖真实平台插件。
class _MemorySessionStore implements SessionStore {
_MemorySessionStore({this.token, this.clearError});
String? token;
final Object? clearError;
int clearCount = 0;
@override
Future<void> clear() async {
clearCount++;
if (clearError != null) throw clearError!;
token = null;
}
@override
Future<String?> readToken() async => token;
@override
Future<void> writeToken(String token) async {
this.token = token;
}
}
/// 覆盖并发 401、迟到的旧请求和安全存储删除失败场景。
void main() {
test('同一失效令牌只清理并通知一次', () async {
final store = _MemorySessionStore(token: 'JWT expired-token');
final session = UserSession(store);
await session.restore();
var notificationCount = 0;
session.addListener(() => notificationCount++);
session.invalidate('JWT expired-token');
session.invalidate('JWT expired-token');
await Future<void>.delayed(Duration.zero);
expect(session.token, isEmpty);
expect(session.hasExpired, isTrue);
expect(store.clearCount, 1);
expect(notificationCount, 1);
});
test('迟到的旧请求不得使当前令牌失效', () async {
final store = _MemorySessionStore(token: 'JWT current-token');
final session = UserSession(store);
await session.restore();
session.invalidate('JWT old-token');
await Future<void>.delayed(Duration.zero);
expect(session.token, 'JWT current-token');
expect(session.hasExpired, isFalse);
expect(store.clearCount, 0);
});
test('持久化删除失败也立即清空内存登录态', () async {
final store = _MemorySessionStore(
token: 'JWT expired-token',
clearError: StateError('storage unavailable'),
);
final session = UserSession(store);
await session.restore();
session.invalidate('JWT expired-token');
await Future<void>.delayed(Duration.zero);
expect(session.token, isEmpty);
expect(session.hasExpired, isTrue);
expect(store.clearCount, 1);
});
}