test(auth): add tests for all features
This commit is contained in:
+79
-65
@@ -17,100 +17,114 @@
|
||||
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 {}
|
||||
implements AuthenticationRepository<int> {}
|
||||
|
||||
class MockUser extends Mock implements User {}
|
||||
class MockAccount extends Mock implements Account {}
|
||||
|
||||
void main() {
|
||||
group('AuthenticationCubit<T>', () {
|
||||
final MockUser user = MockUser();
|
||||
late AuthenticationRepository authenticationRepository;
|
||||
final MockAccount account = MockAccount();
|
||||
final AccountWrapper<int> wrapper = AccountWrapperModel(account, 10);
|
||||
late AuthenticationRepository<int> authenticationRepository;
|
||||
|
||||
setUp(() {
|
||||
authenticationRepository = MockAuthenticationRepository();
|
||||
when(() => authenticationRepository.user).thenAnswer(
|
||||
when(() => authenticationRepository.streamAccount()).thenAnswer(
|
||||
(_) => const Stream.empty(),
|
||||
);
|
||||
when(() => authenticationRepository.cubitStatus).thenAnswer(
|
||||
(_) => Stream.fromIterable([AuthCubitStatus.stoped]),
|
||||
);
|
||||
when(
|
||||
() => authenticationRepository.currentUser,
|
||||
).thenReturn(user);
|
||||
() => authenticationRepository.getAccount(),
|
||||
).thenAnswer((_) async => Ok(account));
|
||||
});
|
||||
|
||||
test('initial auth state is `unknown`', () {
|
||||
expect(
|
||||
AuthenticationCubit<void>(
|
||||
AuthenticationCubit<int>(
|
||||
authenticationRepository: authenticationRepository,
|
||||
).state,
|
||||
const AuthenticationState<Never>.unknown(),
|
||||
);
|
||||
});
|
||||
|
||||
test('initial cubit status is `stoped`', () async {
|
||||
expect(
|
||||
await AuthenticationCubit<void>(
|
||||
authenticationRepository: authenticationRepository,
|
||||
).status,
|
||||
AuthCubitStatus.stoped,
|
||||
);
|
||||
});
|
||||
|
||||
group('UserChanged', () {
|
||||
blocTest<AuthenticationCubit<void>, AuthenticationState<void>>(
|
||||
'emits authenticated when user is not empty',
|
||||
group('ListenForAuthenticationChanges', () {
|
||||
blocTest<AuthenticationCubit<int>, AuthenticationState<int>>(
|
||||
'emits authenticated when stream contains account',
|
||||
setUp: () {
|
||||
when(() => user.isNotEmpty).thenReturn(true);
|
||||
when(() => authenticationRepository.user).thenAnswer(
|
||||
(_) => Stream.value(user),
|
||||
when(() => authenticationRepository.streamAccount()).thenAnswer(
|
||||
(_) => Stream.fromIterable([
|
||||
Future.value(
|
||||
Ok(wrapper),
|
||||
)
|
||||
]),
|
||||
);
|
||||
when(() => authenticationRepository.cubitStatus).thenAnswer(
|
||||
(_) => Stream.value(AuthCubitStatus.started),
|
||||
);
|
||||
},
|
||||
build: () => AuthenticationCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
)..init(),
|
||||
seed: () => const AuthenticationState.unknown(),
|
||||
expect: () => [AuthenticationState<void>.authenticated(user, null)],
|
||||
);
|
||||
|
||||
blocTest<AuthenticationCubit<void>, AuthenticationState<void>>(
|
||||
'emits unauthenticated when user is empty',
|
||||
setUp: () {
|
||||
when(() => user.isEmpty).thenReturn(true);
|
||||
when(() => user.isNotEmpty).thenReturn(false);
|
||||
when(() => authenticationRepository.user).thenAnswer(
|
||||
(_) => Stream.value(user),
|
||||
);
|
||||
when(() => authenticationRepository.cubitStatus).thenAnswer(
|
||||
(_) => Stream.value(AuthCubitStatus.started),
|
||||
);
|
||||
},
|
||||
build: () => AuthenticationCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
)..init(),
|
||||
seed: () => const AuthenticationState.unknown(),
|
||||
expect: () => [const AuthenticationState<Never>.unauthenticated()],
|
||||
);
|
||||
});
|
||||
|
||||
group('LogoutRequested', () {
|
||||
blocTest<AuthenticationCubit<void>, AuthenticationState<void>>(
|
||||
'invokes signOut',
|
||||
setUp: () {
|
||||
when(
|
||||
() => authenticationRepository.signOut(),
|
||||
).thenAnswer((_) async {});
|
||||
},
|
||||
build: () => AuthenticationCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
),
|
||||
act: (cubit) => cubit.logOut(),
|
||||
seed: () => const AuthenticationState.unknown(),
|
||||
expect: () => [AuthenticationState<int>.authenticated(wrapper)],
|
||||
);
|
||||
|
||||
blocTest<AuthenticationCubit<int>, AuthenticationState<int>>(
|
||||
'emits unauthenticated when account stream is empty',
|
||||
setUp: () {
|
||||
when(
|
||||
() => authenticationRepository.destroyCache(),
|
||||
).thenAnswer((_) async => const Ok(null));
|
||||
when(() => authenticationRepository.streamAccount()).thenAnswer(
|
||||
(_) => Stream.fromIterable([
|
||||
Future.value(
|
||||
Ok(AccountWrapperModel(null, 1)),
|
||||
)
|
||||
]),
|
||||
);
|
||||
},
|
||||
build: () => AuthenticationCubit(
|
||||
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,
|
||||
),
|
||||
seed: () => const AuthenticationState.unknown(),
|
||||
expect: () => [const AuthenticationState<int>.unauthenticated()],
|
||||
);
|
||||
});
|
||||
|
||||
group('SignOut', () {
|
||||
blocTest<AuthenticationCubit<int>, AuthenticationState<int>>(
|
||||
'invokes signOut',
|
||||
setUp: () {
|
||||
when(
|
||||
() => authenticationRepository.signOut(),
|
||||
).thenAnswer((_) async => const Ok(null));
|
||||
},
|
||||
build: () => AuthenticationCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
),
|
||||
act: (cubit) => cubit.signOut(),
|
||||
verify: (_) {
|
||||
verify(() => authenticationRepository.signOut()).called(1);
|
||||
},
|
||||
|
||||
+13
-9
@@ -18,7 +18,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||
|
||||
class MockUser extends Mock implements User {}
|
||||
class MockAccount extends Mock implements Account {}
|
||||
|
||||
void main() {
|
||||
group('AuthenticationState', () {
|
||||
@@ -27,29 +27,33 @@ void main() {
|
||||
const AuthenticationState<void> state =
|
||||
AuthenticationState.unauthenticated();
|
||||
expect(state.status, AuthenticationStatus.unauthenticated);
|
||||
expect(state.user, null);
|
||||
expect(state.accountWrapper, null);
|
||||
});
|
||||
});
|
||||
|
||||
group('authenticated', () {
|
||||
test('has correct status', () {
|
||||
final MockUser user = MockUser();
|
||||
final MockAccount account = MockAccount();
|
||||
final AuthenticationState<void> state =
|
||||
AuthenticationState.authenticated(user, null);
|
||||
AuthenticationState.authenticated(
|
||||
AccountWrapperModel<void>(account, null),
|
||||
);
|
||||
expect(state.status, AuthenticationStatus.authenticated);
|
||||
expect(state.user, user);
|
||||
expect(state.accountWrapper?.account, account);
|
||||
});
|
||||
});
|
||||
|
||||
group('authenticated with extra data', () {
|
||||
test('has correct status', () {
|
||||
final MockUser user = MockUser();
|
||||
final MockAccount account = MockAccount();
|
||||
const String extra = 'AwesomeExtraData';
|
||||
final AuthenticationState<String> state =
|
||||
AuthenticationState.authenticated(user, extra);
|
||||
AuthenticationState.authenticated(
|
||||
AccountWrapperModel(account, extra),
|
||||
);
|
||||
expect(state.status, AuthenticationStatus.authenticated);
|
||||
expect(state.user, user);
|
||||
expect(state.extra, extra);
|
||||
expect(state.accountWrapper?.account, account);
|
||||
expect(state.accountWrapper?.data, extra);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user