import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:social_app/features/auth/data/auth_repository.dart'; import 'package:social_app/features/auth/data/models/auth_response.dart'; import 'package:social_app/features/auth/presentation/bloc/auth_bloc.dart'; import 'package:social_app/features/auth/presentation/bloc/auth_event.dart'; import 'package:social_app/features/auth/presentation/bloc/auth_state.dart'; class MockAuthRepository extends Mock implements AuthRepository {} void main() { late AuthBloc authBloc; late MockAuthRepository mockRepository; setUp(() { mockRepository = MockAuthRepository(); authBloc = AuthBloc(mockRepository); }); tearDown(() { authBloc.close(); }); group('AuthBloc', () { blocTest( 'emits [AuthLoading, AuthUnauthenticated] when AuthStarted and no refresh token', build: () { when( () => mockRepository.getRefreshToken(), ).thenAnswer((_) async => null); return authBloc; }, act: (bloc) => bloc.add(AuthStarted()), expect: () => [AuthLoading(), AuthUnauthenticated()], ); blocTest( 'emits [AuthLoading, AuthAuthenticated] when AuthStarted with valid refresh token', build: () { when( () => mockRepository.getRefreshToken(), ).thenAnswer((_) async => 'valid_refresh'); when(() => mockRepository.refresh('valid_refresh')).thenAnswer( (_) async => AuthResponse( accessToken: 'new_access', refreshToken: 'new_refresh', expiresIn: 3600, tokenType: 'bearer', user: const AuthUser(id: '123', email: 'test@example.com'), ), ); return authBloc; }, act: (bloc) => bloc.add(AuthStarted()), expect: () => [AuthLoading(), isA()], ); blocTest( 'emits [AuthLoading, AuthUnauthenticated] when refresh token expired', build: () { when( () => mockRepository.getRefreshToken(), ).thenAnswer((_) async => 'expired_refresh'); when( () => mockRepository.refresh('expired_refresh'), ).thenThrow(Exception('Invalid refresh token')); when(() => mockRepository.logout()).thenAnswer((_) async {}); return authBloc; }, act: (bloc) => bloc.add(AuthStarted()), expect: () => [AuthLoading(), AuthUnauthenticated()], ); blocTest( 'emits [AuthAuthenticated] when AuthLoggedIn', build: () => authBloc, act: (bloc) => bloc.add( AuthLoggedIn( user: const AuthUser(id: '1', email: 'test@example.com'), ), ), expect: () => [isA()], ); blocTest( 'emits [AuthUnauthenticated] when AuthLoggedOut', build: () { when(() => mockRepository.logout()).thenAnswer((_) async {}); return authBloc; }, seed: () => AuthAuthenticated( user: const AuthUser(id: '1', email: 'test@example.com'), ), act: (bloc) => bloc.add(AuthLoggedOut()), expect: () => [AuthUnauthenticated()], ); }); }