import 'package:bloc_test/bloc_test.dart';
import 'package:comwell_key_app/authentication/authentication_repository.dart';
import 'package:comwell_key_app/authentication/bloc/authentication_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';

class MockAuthenticationRepository extends Mock implements AuthenticationRepository {}

void main() {
  late AuthenticationRepository authenticationRepository;

  setUp(() {
    authenticationRepository = MockAuthenticationRepository();
  });

  AuthenticationBloc buildBloc() {
    return AuthenticationBloc(
      authenticationRepository: authenticationRepository,
    );
  }

  group('authenticationBloc', () {
    group('AuthenticationSubscriptionRequested', () {
      final error = Exception('oops');
      blocTest<AuthenticationBloc, AuthenticationState>(
        'emits [unauthenticated] when status is unauthenticated',
        setUp: () {
          when(() => authenticationRepository.isLoggedIn).thenAnswer(
            (_) => false,
          );
        },
        build: buildBloc,
        act: (bloc) => bloc.add(AuthenticationSubscriptionRequested()),
        expect: () => const [AuthenticationState.unauthenticated()],
      );

      blocTest<AuthenticationBloc, AuthenticationState>(
        'emits [authenticated] when status is authenticated',
        setUp: () {
          when(() => authenticationRepository.isLoggedIn).thenAnswer(
            (_) => false,
          );
        },
        build: buildBloc,
        act: (bloc) => bloc.add(AuthenticationSubscriptionRequested()),
        expect: () => const [AuthenticationState.authenticated()],
      );

      blocTest<AuthenticationBloc, AuthenticationState>(
        'adds error when status stream emits an error',
        setUp: () {
          when(
            () => authenticationRepository.isLoggedIn,
          ).thenAnswer((_) {
            throw Exception();
            return false;
          });
        },
        build: buildBloc,
        act: (bloc) => bloc.add(AuthenticationSubscriptionRequested()),
        errors: () => [error],
      );
    });
  });
  test('initial state is unknown', () {
    final authenticationBloc = AuthenticationBloc(
      authenticationRepository: authenticationRepository,
    );
    expect(authenticationBloc.state, const AuthenticationState.unknown());
  });
}