// Copyright (C) 2023 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; import 'package:wyatt_architecture/wyatt_architecture.dart'; import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart'; class MockAuthenticationRepository extends Mock implements AuthenticationRepository {} class MockAccount extends Mock implements Account {} class TestAuthenticationCubit extends AuthenticationCubit { TestAuthenticationCubit({required super.authenticationRepository}); @override FutureOrResult onDelete() async => Ok(null); @override FutureOrResult onReauthenticate( Result result, ) async => Ok(null); @override FutureOrResult onRefresh(Result result) async => Ok(null); @override FutureOrResult onSignInFromCache( AuthenticationSession session, ) async => Ok(null); @override FutureOrResult onSignOut() async => Ok(null); } void main() { group('AuthenticationCubit', () { final MockAccount account = MockAccount(); final AuthenticationSession session = AuthenticationSession( latestEvent: const UnknownAuthenticationEvent(), account: account, data: 10, ); late AuthenticationRepository authenticationRepository; setUp(() { authenticationRepository = MockAuthenticationRepository(); when(() => authenticationRepository.sessionStream()).thenAnswer( (_) => const Stream.empty(), ); when(() => authenticationRepository.checkForCachedAccount()).thenAnswer( (_) => Future.value(), ); }); test('initial auth state is `unknown`', () { expect( TestAuthenticationCubit( authenticationRepository: authenticationRepository, ).state, const AuthenticationState.unknown(), ); }); group('ListenForAuthenticationChanges', () { blocTest, AuthenticationState>( 'emits authenticated when stream contains session', setUp: () { when(() => authenticationRepository.sessionStream()).thenAnswer( (_) => Stream.fromIterable([session]), ); }, build: () => TestAuthenticationCubit( authenticationRepository: authenticationRepository, ), seed: AuthenticationState.unknown, expect: () => [AuthenticationState.authenticated(session)], ); blocTest, AuthenticationState>( 'emits unauthenticated when account stream is empty', setUp: () { when(() => authenticationRepository.sessionStream()).thenAnswer( (_) => Stream.fromIterable( [const AuthenticationSession(latestEvent: SignedOutEvent())], ), ); }, build: () => TestAuthenticationCubit( authenticationRepository: authenticationRepository, ), seed: AuthenticationState.unknown, expect: () => [const AuthenticationState.unauthenticated()], ); }); group('SignOut', () { blocTest, AuthenticationState>( 'invokes signOut', setUp: () { when( () => authenticationRepository.signOut(), ).thenAnswer((_) async => Ok(null)); }, build: () => TestAuthenticationCubit( authenticationRepository: authenticationRepository, ), act: (cubit) => cubit.signOut(), verify: (_) { verify(() => authenticationRepository.signOut()).called(1); }, ); }); }); }