// 功能描述:验证会话失效的幂等清理、旧请求隔离和存储异常降级。 // 版本: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 clear() async { clearCount++; if (clearError != null) throw clearError!; token = null; } @override Future readToken() async => token; @override Future 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.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.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.delayed(Duration.zero); expect(session.token, isEmpty); expect(session.hasExpired, isTrue); expect(store.clearCount, 1); }); }