test(authentication): update tests
This commit is contained in:
		
							parent
							
								
									918215b5b8
								
							
						
					
					
						commit
						fdd020f103
					
				| @ -1,5 +1,5 @@ | |||||||
| <!-- | <!-- | ||||||
|  * Copyright (C) 2022 WYATT GROUP |  * Copyright (C) 2023 WYATT GROUP | ||||||
|  * Please see the AUTHORS file for details. |  * Please see the AUTHORS file for details. | ||||||
| 
 | 
 | ||||||
|  * This program is free software: you can redistribute it and/or modify |  * This program is free software: you can redistribute it and/or modify | ||||||
| @ -19,9 +19,7 @@ | |||||||
| # Flutter - Authentication BLoC | # Flutter - Authentication BLoC | ||||||
| 
 | 
 | ||||||
| <p align="left"> | <p align="left"> | ||||||
|   <a href="https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis"> |   <a href="https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_analysis"><img src="https://img.shields.io/badge/Style-Wyatt%20Analysis-blue.svg?style=flat-square" alt="Style: Wyatt Analysis" /></a> | ||||||
|     <img src="https://img.shields.io/badge/Style-Wyatt%20Analysis-blue.svg?style=flat-square" alt="Style: Wyatt Analysis" /> |  | ||||||
|   </a> |  | ||||||
|   <img src="https://img.shields.io/badge/SDK-Flutter-blue?style=flat-square" alt="SDK: Flutter" /> |   <img src="https://img.shields.io/badge/SDK-Flutter-blue?style=flat-square" alt="SDK: Flutter" /> | ||||||
| </p> | </p> | ||||||
| 
 | 
 | ||||||
| @ -29,28 +27,22 @@ Authentication Bloc for Flutter. | |||||||
| 
 | 
 | ||||||
| ## Features | ## Features | ||||||
| 
 | 
 | ||||||
| - Wyatt Architecture | * 🧐 Wyatt Architecture | ||||||
| - Entities: | * 🧱 Entities | ||||||
|     - Account : AccountModel -> Contains account information from provider |     - Account -> Contains account information from provider. | ||||||
|     - AccountWrapper : AccountWrapperModel -> Contains account and extra data. |     - Session -> Contains account and associated data retrieved from an external source. | ||||||
| - Data Sources: |     - AuthenticationChangeEvent -> Describes an event in authentication change (sign in, sign up, sign out, etc...) | ||||||
|     - Local: |     - SessionWrapper -> Contains latest authentication change event and session. | ||||||
|         - Cached Authentication Data : AuthenticationCacheDataSourceImpl -> Provides a cache implementation | * 🔑 Powerful and secured authentication repository | ||||||
|     - Remote: | * 🔥 Multiple data sources | ||||||
|         - Remote Authentication Data : AuthenticationFirebaseDataSourceImpl -> Provides a proxy to FirebaseAuth |     - Mock | ||||||
| - Repositories: |     - Firebase | ||||||
|     - AuthenticationRepository : AuthenticationRepositoryImpl -> Provides all authentication methods | * 🧊 Cubits, why make it complicated when you can make it simple? | ||||||
| - Features: |     - Goes to the essential. | ||||||
|     - Authentication: | * 📐 Consistent | ||||||
|         - AuthenticationBuilder : widget to build reactive view from authentication state |     - Every class have same naming convention | ||||||
|         - AuthenticationCubit : tracks every auth changes, have sign out capability. | * 🧪 Tested | ||||||
|     - SignUp: | * 📚 Documented: [available here](./doc/api/index.md) | ||||||
|         - SignUpCubit: implementation of a FormDataCubit from `wyatt_form_bloc` for the sign up |  | ||||||
|     - SignIn: |  | ||||||
|         - SignUpCubit: implementation of a FormDataCubit from `wyatt_form_bloc` for the sign in |  | ||||||
| - Consistent |  | ||||||
|     * Every class have same naming convention |  | ||||||
| - Tested |  | ||||||
| 
 | 
 | ||||||
| ## Getting started | ## Getting started | ||||||
| 
 | 
 | ||||||
| @ -60,6 +52,170 @@ Simply add `wyatt_authentication_bloc` in `pubspec.yaml`, then | |||||||
| import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; | import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Usage | ### Data source | ||||||
| 
 | 
 | ||||||
|  | The first step is to provide a data source. | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | getIt.registerLazySingleton<AuthenticationRemoteDataSource<int>>( | ||||||
|  |     () => AuthenticationFirebaseDataSourceImpl<int>( | ||||||
|  |         firebaseAuth: FirebaseAuth.instance, | ||||||
|  |         googleSignIn: | ||||||
|  |             GoogleSignIn(clientId: DefaultFirebaseOptions.ios.iosClientId)), | ||||||
|  | ); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | > Here we use GetIt (see example project) | ||||||
|  | 
 | ||||||
|  | ### Repository | ||||||
|  | 
 | ||||||
|  | Then you can configure your repository. | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | final AuthenticationRepository<int> authenticationRepository = AuthenticationRepositoryImpl( | ||||||
|  |     authenticationRemoteDataSource: | ||||||
|  |         getIt<AuthenticationRemoteDataSource<int>>(), | ||||||
|  |     customPasswordValidator: const CustomPassword.pure(), | ||||||
|  |     extraSignUpInputs: [ | ||||||
|  |         FormInput( | ||||||
|  |         AuthFormField.confirmPassword, | ||||||
|  |         const ConfirmedPassword.pure(), | ||||||
|  |         metadata: const FormInputMetadata<void>(export: false), | ||||||
|  |         ), | ||||||
|  |     ], | ||||||
|  | ); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | > Here we pass some extra inputs for the sign up, and a custom password validator. | ||||||
|  | 
 | ||||||
|  | ### Cubits | ||||||
|  | 
 | ||||||
|  | It is necessary to implement each cubit. Don't panic, most of the work is already done 😊 you just have to customize the logic of these. | ||||||
|  | 
 | ||||||
|  | In each of these cubits it is necessary to overload the various callbacks. | ||||||
|  | 
 | ||||||
|  | > Here the associated data `Data` is a `int` | ||||||
|  | 
 | ||||||
|  | #### Authentication | ||||||
|  | 
 | ||||||
|  | In the authentication are managed, the refresh, the deletion of account or the disconnection. | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | class ExampleAuthenticationCubit extends AuthenticationCubit<int> { | ||||||
|  |   ExampleAuthenticationCubit({required super.authenticationRepository}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<int?> onReauthenticate(Result<Account, AppException> result) async { | ||||||
|     // TODO |     // TODO | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<int?> onRefresh(Result<Account, AppException> result) { | ||||||
|  |     // TODO | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<int?> onSignInFromCache(SessionWrapper<int> wrapper) { | ||||||
|  |     // TODO | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<void> onSignOut() { | ||||||
|  |     // TODO | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<void> onDelete() { | ||||||
|  |     // TODO | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | #### Sign Up | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | class ExampleSignUpCubit extends SignUpCubit<int> { | ||||||
|  |   ExampleSignUpCubit({ | ||||||
|  |     required super.authenticationRepository, | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<int?> onSignUpWithEmailAndPassword(Result<Account, AppException> result, WyattForm form) async { | ||||||
|  |     // TODO | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | #### Sign In | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | class ExampleSignInCubit extends SignInCubit<int> { | ||||||
|  |   ExampleSignInCubit({ | ||||||
|  |     required super.authenticationRepository, | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<int?> onSignInWithEmailAndPassword(Result<Account, AppException> result, WyattForm form) { | ||||||
|  |     // TODO | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<int?> onSignInAnonymously(Result<Account, AppException> result, WyattForm form) { | ||||||
|  |     // TODO | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<int?> onSignInWithGoogle(Result<Account, AppException> result, WyattForm form) { | ||||||
|  |     // TODO | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | After setting up all these cubits you can provide them in the application. And that's it! | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | BlocProvider<SignUpCubit<int>>( | ||||||
|  |     create: (_) => ExampleSignUpCubit( | ||||||
|  |         authenticationRepository: authenticationRepository, | ||||||
|  |     ), | ||||||
|  | ), | ||||||
|  | BlocProvider<SignInCubit<int>>( | ||||||
|  |     create: (_) => ExampleSignInCubit( | ||||||
|  |         authenticationRepository: authenticationRepository, | ||||||
|  |     ), | ||||||
|  | ), | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Widgets | ||||||
|  | 
 | ||||||
|  | Widgets are provided to make your life easier. Starting with the `AuthenticationBuilder` which allows you to build according to the authentication state. | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | AuthenticationBuilder<int>( | ||||||
|  |     authenticated: (context, sessionWrapper) => Text( | ||||||
|  |         'Logged as ${sessionWrapper.session?.account.email} | GeneratedId is ${sessionWrapper.session?.data}'), | ||||||
|  |     unauthenticated: (context) => | ||||||
|  |         const Text('Not logged (unauthenticated)'), | ||||||
|  |     unknown: (context) => const Text('Not logged (unknown)'), | ||||||
|  | ), | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | A `BuildContext` extension is also available to access certain attributes more quickly. | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | Text('Home | ${context.account<AuthenticationCubit<int>, int>()?.email}'), | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Listeners are used to listen to the status of the sign in and sign up forms. | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | return SignInListener<int>( | ||||||
|  |     onError: (context, status, errorMessage) => ScaffoldMessenger.of(context) | ||||||
|  |     ..hideCurrentSnackBar() | ||||||
|  |     ..showSnackBar( | ||||||
|  |         SnackBar(content: Text(errorMessage ?? 'Sign In Failure')), | ||||||
|  |     ), | ||||||
|  |     child: ... | ||||||
|  | ); | ||||||
|  | ``` | ||||||
| @ -10,7 +10,6 @@ dart pub global run dartdoc --format md \ | |||||||
| 	--no-auto-include-dependencies \ | 	--no-auto-include-dependencies \ | ||||||
| 	--no-validate-links \ | 	--no-validate-links \ | ||||||
| 	--show-progress \ | 	--show-progress \ | ||||||
| 	--output "/Users/hpcl/Work/Wyatt/wyatt-packages/wiki/wyatt_authentication_bloc/" |  | ||||||
| 
 | 
 | ||||||
| sed -i -e "s/\/\/export 'package:firebase_auth\/firebase_auth.dart';/export 'package:firebase_auth\/firebase_auth.dart';/g" lib/wyatt_authentication_bloc.dart | sed -i -e "s/\/\/export 'package:firebase_auth\/firebase_auth.dart';/export 'package:firebase_auth\/firebase_auth.dart';/g" lib/wyatt_authentication_bloc.dart | ||||||
| sed -i -e "s/\/\/export 'package:google_sign_in\/google_sign_in.dart';/export 'package:google_sign_in\/google_sign_in.dart';/g" lib/wyatt_authentication_bloc.dart | sed -i -e "s/\/\/export 'package:google_sign_in\/google_sign_in.dart';/export 'package:google_sign_in\/google_sign_in.dart';/g" lib/wyatt_authentication_bloc.dart | ||||||
|  | |||||||
| @ -26,25 +26,49 @@ class MockAuthenticationRepository extends Mock | |||||||
| 
 | 
 | ||||||
| class MockAccount extends Mock implements Account {} | class MockAccount extends Mock implements Account {} | ||||||
| 
 | 
 | ||||||
|  | class TestAuthenticationCubit extends AuthenticationCubit<int> { | ||||||
|  |   TestAuthenticationCubit({required super.authenticationRepository}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<void> onDelete() async => const Ok(null); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<int?> onReauthenticate( | ||||||
|  |     Result<Account, AppException> result, | ||||||
|  |   ) async => | ||||||
|  |       const Ok(null); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<int?> onRefresh(Result<Account, AppException> result) async => | ||||||
|  |       const Ok(null); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<int?> onSignInFromCache(SessionWrapper<int> wrapper) async => | ||||||
|  |       const Ok(null); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<void> onSignOut() async => const Ok(null); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void main() { | void main() { | ||||||
|   group('AuthenticationCubit<T>', () { |   group('AuthenticationCubit<T>', () { | ||||||
|     final MockAccount account = MockAccount(); |     final MockAccount account = MockAccount(); | ||||||
|     final AccountWrapper<int> wrapper = AccountWrapperModel(account, 10); |     final SessionWrapper<int> wrapper = SessionWrapper( | ||||||
|  |       event: const UnknownAuthenticationEvent(), | ||||||
|  |       session: Session(account: account, data: 10), | ||||||
|  |     ); | ||||||
|     late AuthenticationRepository<int> authenticationRepository; |     late AuthenticationRepository<int> authenticationRepository; | ||||||
| 
 | 
 | ||||||
|     setUp(() { |     setUp(() { | ||||||
|       authenticationRepository = MockAuthenticationRepository(); |       authenticationRepository = MockAuthenticationRepository(); | ||||||
|       when(() => authenticationRepository.streamAccount()).thenAnswer( |       when(() => authenticationRepository.sessionStream()).thenAnswer( | ||||||
|         (_) => const Stream.empty(), |         (_) => const Stream.empty(), | ||||||
|       ); |       ); | ||||||
|       when( |  | ||||||
|         () => authenticationRepository.getAccount(), |  | ||||||
|       ).thenAnswer((_) async => Ok(account)); |  | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     test('initial auth state is `unknown`', () { |     test('initial auth state is `unknown`', () { | ||||||
|       expect( |       expect( | ||||||
|         AuthenticationCubit<int>( |         TestAuthenticationCubit( | ||||||
|           authenticationRepository: authenticationRepository, |           authenticationRepository: authenticationRepository, | ||||||
|         ).state, |         ).state, | ||||||
|         const AuthenticationState<Never>.unknown(), |         const AuthenticationState<Never>.unknown(), | ||||||
| @ -53,17 +77,13 @@ void main() { | |||||||
| 
 | 
 | ||||||
|     group('ListenForAuthenticationChanges', () { |     group('ListenForAuthenticationChanges', () { | ||||||
|       blocTest<AuthenticationCubit<int>, AuthenticationState<int>>( |       blocTest<AuthenticationCubit<int>, AuthenticationState<int>>( | ||||||
|         'emits authenticated when stream contains account', |         'emits authenticated when stream contains session', | ||||||
|         setUp: () { |         setUp: () { | ||||||
|           when(() => authenticationRepository.streamAccount()).thenAnswer( |           when(() => authenticationRepository.sessionStream()).thenAnswer( | ||||||
|             (_) => Stream.fromIterable([ |             (_) => Stream.fromIterable([wrapper]), | ||||||
|               Future.value( |  | ||||||
|                 Ok(wrapper), |  | ||||||
|               ) |  | ||||||
|             ]), |  | ||||||
|           ); |           ); | ||||||
|         }, |         }, | ||||||
|         build: () => AuthenticationCubit( |         build: () => TestAuthenticationCubit( | ||||||
|           authenticationRepository: authenticationRepository, |           authenticationRepository: authenticationRepository, | ||||||
|         ), |         ), | ||||||
|         seed: () => const AuthenticationState.unknown(), |         seed: () => const AuthenticationState.unknown(), | ||||||
| @ -73,39 +93,12 @@ void main() { | |||||||
|       blocTest<AuthenticationCubit<int>, AuthenticationState<int>>( |       blocTest<AuthenticationCubit<int>, AuthenticationState<int>>( | ||||||
|         'emits unauthenticated when account stream is empty', |         'emits unauthenticated when account stream is empty', | ||||||
|         setUp: () { |         setUp: () { | ||||||
|           when( |           when(() => authenticationRepository.sessionStream()).thenAnswer( | ||||||
|             () => authenticationRepository.destroyCache(), |             (_) => Stream.fromIterable( | ||||||
|           ).thenAnswer((_) async => const Ok(null)); |                 [const SessionWrapper(event: SignedOutEvent())],), | ||||||
|           when(() => authenticationRepository.streamAccount()).thenAnswer( |  | ||||||
|             (_) => Stream.fromIterable([ |  | ||||||
|               Future.value( |  | ||||||
|                 Ok(AccountWrapperModel(null, 1)), |  | ||||||
|               ) |  | ||||||
|             ]), |  | ||||||
|           ); |           ); | ||||||
|         }, |         }, | ||||||
|         build: () => AuthenticationCubit( |         build: () => TestAuthenticationCubit( | ||||||
|           authenticationRepository: authenticationRepository, |  | ||||||
|         ), |  | ||||||
|         seed: () => const AuthenticationState.unknown(), |  | ||||||
|         expect: () => [const AuthenticationState<int>.unauthenticated()], |  | ||||||
|       ); |  | ||||||
| 
 |  | ||||||
|       blocTest<AuthenticationCubit<int>, AuthenticationState<int>>( |  | ||||||
|         'emits unauthenticated when there is an error in stream', |  | ||||||
|         setUp: () { |  | ||||||
|           when( |  | ||||||
|             () => authenticationRepository.destroyCache(), |  | ||||||
|           ).thenAnswer((_) async => const Ok(null)); |  | ||||||
|           when(() => authenticationRepository.streamAccount()).thenAnswer( |  | ||||||
|             (_) => Stream.fromIterable([ |  | ||||||
|               Future.value( |  | ||||||
|                 Err(ServerException()), |  | ||||||
|               ) |  | ||||||
|             ]), |  | ||||||
|           ); |  | ||||||
|         }, |  | ||||||
|         build: () => AuthenticationCubit( |  | ||||||
|           authenticationRepository: authenticationRepository, |           authenticationRepository: authenticationRepository, | ||||||
|         ), |         ), | ||||||
|         seed: () => const AuthenticationState.unknown(), |         seed: () => const AuthenticationState.unknown(), | ||||||
| @ -121,7 +114,7 @@ void main() { | |||||||
|             () => authenticationRepository.signOut(), |             () => authenticationRepository.signOut(), | ||||||
|           ).thenAnswer((_) async => const Ok(null)); |           ).thenAnswer((_) async => const Ok(null)); | ||||||
|         }, |         }, | ||||||
|         build: () => AuthenticationCubit( |         build: () => TestAuthenticationCubit( | ||||||
|           authenticationRepository: authenticationRepository, |           authenticationRepository: authenticationRepository, | ||||||
|         ), |         ), | ||||||
|         act: (cubit) => cubit.signOut(), |         act: (cubit) => cubit.signOut(), | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ void main() { | |||||||
|         const AuthenticationState<void> state = |         const AuthenticationState<void> state = | ||||||
|             AuthenticationState.unauthenticated(); |             AuthenticationState.unauthenticated(); | ||||||
|         expect(state.status, AuthenticationStatus.unauthenticated); |         expect(state.status, AuthenticationStatus.unauthenticated); | ||||||
|         expect(state.accountWrapper, null); |         expect(state.wrapper, null); | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
| @ -36,10 +36,13 @@ void main() { | |||||||
|         final MockAccount account = MockAccount(); |         final MockAccount account = MockAccount(); | ||||||
|         final AuthenticationState<void> state = |         final AuthenticationState<void> state = | ||||||
|             AuthenticationState.authenticated( |             AuthenticationState.authenticated( | ||||||
|           AccountWrapperModel<void>(account, null), |           SessionWrapper<void>( | ||||||
|  |             event: SignedInEvent(account: account), | ||||||
|  |             session: Session(account: account), | ||||||
|  |           ), | ||||||
|         ); |         ); | ||||||
|         expect(state.status, AuthenticationStatus.authenticated); |         expect(state.status, AuthenticationStatus.authenticated); | ||||||
|         expect(state.accountWrapper?.account, account); |         expect(state.wrapper?.session?.account, account); | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
| @ -49,11 +52,14 @@ void main() { | |||||||
|         const String extra = 'AwesomeExtraData'; |         const String extra = 'AwesomeExtraData'; | ||||||
|         final AuthenticationState<String> state = |         final AuthenticationState<String> state = | ||||||
|             AuthenticationState.authenticated( |             AuthenticationState.authenticated( | ||||||
|           AccountWrapperModel(account, extra), |           SessionWrapper<String>( | ||||||
|  |             event: SignedInEvent(account: account), | ||||||
|  |             session: Session(account: account, data: extra), | ||||||
|  |           ), | ||||||
|         ); |         ); | ||||||
|         expect(state.status, AuthenticationStatus.authenticated); |         expect(state.status, AuthenticationStatus.authenticated); | ||||||
|         expect(state.accountWrapper?.account, account); |         expect(state.wrapper?.session?.account, account); | ||||||
|         expect(state.accountWrapper?.data, extra); |         expect(state.wrapper?.session?.data, extra); | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|  | |||||||
| @ -25,8 +25,8 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart'; | |||||||
| class MockAuthenticationRepository extends Mock | class MockAuthenticationRepository extends Mock | ||||||
|     implements AuthenticationRepository<int> {} |     implements AuthenticationRepository<int> {} | ||||||
| 
 | 
 | ||||||
| class MockAuthenticationCubit extends Mock implements AuthenticationCubit<int> { | class MockAuthenticationCubit extends Mock | ||||||
| } |     implements AuthenticationCubit<int> {} | ||||||
| 
 | 
 | ||||||
| class MockAccount extends Mock implements Account {} | class MockAccount extends Mock implements Account {} | ||||||
| 
 | 
 | ||||||
| @ -39,15 +39,21 @@ void main() { | |||||||
| 
 | 
 | ||||||
|     setUp(() { |     setUp(() { | ||||||
|       authenticationRepository = MockAuthenticationRepository(); |       authenticationRepository = MockAuthenticationRepository(); | ||||||
|       when( |       account = MockAccount(); | ||||||
|         () => authenticationRepository.getAccount(), | 
 | ||||||
|       ).thenAnswer((_) async => Ok(account)); |       when(() => authenticationRepository.sessionStream()).thenAnswer( | ||||||
|  |         (_) => Stream.fromIterable([ | ||||||
|  |           SessionWrapper<int>( | ||||||
|  |             event: SignedInFromCacheEvent(account: account), | ||||||
|  |             session: Session<int>(account: account, data: 10), | ||||||
|  |           ) | ||||||
|  |         ]), | ||||||
|  |       ); | ||||||
| 
 | 
 | ||||||
|       when( |       when( | ||||||
|         () => authenticationRepository.refresh(), |         () => authenticationRepository.refresh(), | ||||||
|       ).thenAnswer((_) async => const Ok(null)); |       ).thenAnswer((_) async => Ok(account)); | ||||||
| 
 | 
 | ||||||
|       account = MockAccount(); |  | ||||||
|       when( |       when( | ||||||
|         () => account.emailVerified, |         () => account.emailVerified, | ||||||
|       ).thenAnswer((_) => true); |       ).thenAnswer((_) => true); | ||||||
| @ -129,7 +135,7 @@ void main() { | |||||||
|         setUp: () { |         setUp: () { | ||||||
|           when( |           when( | ||||||
|             () => authenticationRepository.refresh(), |             () => authenticationRepository.refresh(), | ||||||
|           ).thenAnswer((_) async => const Ok(null)); |           ).thenAnswer((_) async => Ok(account)); | ||||||
|         }, |         }, | ||||||
|         build: () => EmailVerificationCubit( |         build: () => EmailVerificationCubit( | ||||||
|           authenticationRepository: authenticationRepository, |           authenticationRepository: authenticationRepository, | ||||||
| @ -145,7 +151,7 @@ void main() { | |||||||
|         setUp: () { |         setUp: () { | ||||||
|           when( |           when( | ||||||
|             () => authenticationRepository.refresh(), |             () => authenticationRepository.refresh(), | ||||||
|           ).thenAnswer((_) async => const Ok(null)); |           ).thenAnswer((_) async => Ok(account)); | ||||||
|           when(() => account.emailVerified).thenAnswer((_) => false); |           when(() => account.emailVerified).thenAnswer((_) => false); | ||||||
|         }, |         }, | ||||||
|         build: () => EmailVerificationCubit( |         build: () => EmailVerificationCubit( | ||||||
| @ -161,7 +167,7 @@ void main() { | |||||||
|         'emits success with true if verified', |         'emits success with true if verified', | ||||||
|         setUp: () { |         setUp: () { | ||||||
|           when(() => authenticationRepository.refresh()) |           when(() => authenticationRepository.refresh()) | ||||||
|               .thenAnswer((_) async => const Ok(null)); |               .thenAnswer((_) async => Ok(account)); | ||||||
|         }, |         }, | ||||||
|         build: () => EmailVerificationCubit( |         build: () => EmailVerificationCubit( | ||||||
|           authenticationRepository: authenticationRepository, |           authenticationRepository: authenticationRepository, | ||||||
| @ -183,7 +189,7 @@ void main() { | |||||||
|         'emits success with false if not verified', |         'emits success with false if not verified', | ||||||
|         setUp: () { |         setUp: () { | ||||||
|           when(() => authenticationRepository.refresh()) |           when(() => authenticationRepository.refresh()) | ||||||
|               .thenAnswer((_) async => const Ok(null)); |               .thenAnswer((_) async => Ok(account)); | ||||||
|           when(() => account.emailVerified).thenAnswer((_) => false); |           when(() => account.emailVerified).thenAnswer((_) => false); | ||||||
|         }, |         }, | ||||||
|         build: () => EmailVerificationCubit( |         build: () => EmailVerificationCubit( | ||||||
| @ -222,28 +228,6 @@ void main() { | |||||||
|           ) |           ) | ||||||
|         ], |         ], | ||||||
|       ); |       ); | ||||||
| 
 |  | ||||||
|       blocTest<EmailVerificationCubit<int>, EmailVerificationState>( |  | ||||||
|         'emits failure on get account error', |  | ||||||
|         setUp: () { |  | ||||||
|           when(() => authenticationRepository.getAccount()) |  | ||||||
|               .thenAnswer((_) async => Err(ServerException('erreur'))); |  | ||||||
|         }, |  | ||||||
|         build: () => EmailVerificationCubit( |  | ||||||
|           authenticationRepository: authenticationRepository, |  | ||||||
|         ), |  | ||||||
|         seed: () => const EmailVerificationState(), |  | ||||||
|         act: (cubit) => cubit.checkEmailVerification(), |  | ||||||
|         expect: () => [ |  | ||||||
|           const EmailVerificationState( |  | ||||||
|             status: FormStatus.submissionInProgress, |  | ||||||
|           ), |  | ||||||
|           const EmailVerificationState( |  | ||||||
|             errorMessage: 'erreur', |  | ||||||
|             status: FormStatus.submissionFailure, |  | ||||||
|           ) |  | ||||||
|         ], |  | ||||||
|       ); |  | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
|  | |||||||
| @ -25,8 +25,8 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart'; | |||||||
| class MockAuthenticationRepository extends Mock | class MockAuthenticationRepository extends Mock | ||||||
|     implements AuthenticationRepository<int> {} |     implements AuthenticationRepository<int> {} | ||||||
| 
 | 
 | ||||||
| class MockAuthenticationCubit extends Mock implements AuthenticationCubit<int> { | class MockAuthenticationCubit extends Mock | ||||||
| } |     implements AuthenticationCubit<int> {} | ||||||
| 
 | 
 | ||||||
| class MockAccount extends Mock implements Account {} | class MockAccount extends Mock implements Account {} | ||||||
| 
 | 
 | ||||||
| @ -59,14 +59,7 @@ void main() { | |||||||
|       formRepository = MockFormRepository(); |       formRepository = MockFormRepository(); | ||||||
| 
 | 
 | ||||||
|       when( |       when( | ||||||
|         () => authenticationRepository.signUp( |         () => authenticationRepository.signUpWithEmailAndPassword( | ||||||
|           email: any(named: 'email'), |  | ||||||
|           password: any(named: 'password'), |  | ||||||
|         ), |  | ||||||
|       ).thenAnswer((_) async => Ok(account)); |  | ||||||
| 
 |  | ||||||
|       when( |  | ||||||
|         () => authenticationRepository.signInWithEmailAndPassword( |  | ||||||
|           email: any(named: 'email'), |           email: any(named: 'email'), | ||||||
|           password: any(named: 'password'), |           password: any(named: 'password'), | ||||||
|         ), |         ), | ||||||
| @ -318,7 +311,7 @@ void main() { | |||||||
|         act: (cubit) => cubit.signUpWithEmailPassword(), |         act: (cubit) => cubit.signUpWithEmailPassword(), | ||||||
|         verify: (_) { |         verify: (_) { | ||||||
|           verify( |           verify( | ||||||
|             () => authenticationRepository.signUp( |             () => authenticationRepository.signUpWithEmailAndPassword( | ||||||
|               email: validEmailString, |               email: validEmailString, | ||||||
|               password: validPasswordString, |               password: validPasswordString, | ||||||
|             ), |             ), | ||||||
| @ -409,7 +402,7 @@ void main() { | |||||||
|         'when signUp fails', |         'when signUp fails', | ||||||
|         setUp: () { |         setUp: () { | ||||||
|           when( |           when( | ||||||
|             () => authenticationRepository.signUp( |             () => authenticationRepository.signUpWithEmailAndPassword( | ||||||
|               email: any(named: 'email'), |               email: any(named: 'email'), | ||||||
|               password: any(named: 'password'), |               password: any(named: 'password'), | ||||||
|             ), |             ), | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user