import 'package:flutter_test/flutter_test.dart'; import 'package:meeyao_qianwen/features/auth/data/models/auth_user.dart'; import 'package:meeyao_qianwen/features/auth/data/repositories/auth_repository.dart'; import 'package:meeyao_qianwen/features/auth/presentation/bloc/auth_bloc.dart'; import 'package:meeyao_qianwen/features/auth/presentation/bloc/auth_state.dart'; class _FakeAuthRepository implements AuthRepository { _FakeAuthRepository({this.recoveredUser, this.throwOnLogout = false}); AuthUser? recoveredUser; bool clearCalled = false; bool logoutCalled = false; bool throwOnLogout; @override Future clearLocalSession() async { clearCalled = true; } @override Future loginWithEmailOtp({ required String email, required String otp, }) async { return AuthUser(id: 'u1', email: email); } @override Future logout() async { logoutCalled = true; if (throwOnLogout) { throw Exception('logout failed'); } } @override Future recoverSession() async { return recoveredUser; } @override Future sendOtp(String email) async {} } void main() { test('start should become authenticated when recover success', () async { final repo = _FakeAuthRepository( recoveredUser: const AuthUser(id: 'u1', email: 'a@b.com'), ); final bloc = AuthBloc(repository: repo); await bloc.start(); expect(bloc.state.status, AuthStatus.authenticated); expect(bloc.state.user?.email, 'a@b.com'); }); test('handleUnauthorized401 should clear local session and unauth', () async { final repo = _FakeAuthRepository( recoveredUser: const AuthUser(id: 'u1', email: 'a@b.com'), ); final bloc = AuthBloc(repository: repo); await bloc.start(); await bloc.handleUnauthorized401(); expect(repo.clearCalled, isTrue); expect(bloc.state.status, AuthStatus.unauthenticated); }); test( 'logout should set unauthenticated even when repository throws', () async { final repo = _FakeAuthRepository( recoveredUser: const AuthUser(id: 'u1', email: 'a@b.com'), throwOnLogout: true, ); final bloc = AuthBloc(repository: repo); await bloc.start(); await expectLater(bloc.logout(), throwsA(isA())); expect(repo.logoutCalled, isTrue); expect(bloc.state.status, AuthStatus.unauthenticated); }, ); }