feat(apps): add LoginCubit for login form
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:formz/formz.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import '../../data/auth_repository.dart';
|
||||
import '../../data/models/login_request.dart';
|
||||
import '../../data/models/auth_response.dart';
|
||||
import 'register_cubit.dart' show Email, Password;
|
||||
|
||||
class LoginState extends Equatable {
|
||||
final Email email;
|
||||
final Password password;
|
||||
final FormzSubmissionStatus status;
|
||||
final String? errorMessage;
|
||||
|
||||
const LoginState({
|
||||
this.email = const Email.pure(),
|
||||
this.password = const Password.pure(),
|
||||
this.status = FormzSubmissionStatus.initial,
|
||||
this.errorMessage,
|
||||
});
|
||||
|
||||
bool get isValid => email.isValid && password.isValid;
|
||||
|
||||
LoginState copyWith({
|
||||
Email? email,
|
||||
Password? password,
|
||||
FormzSubmissionStatus? status,
|
||||
String? errorMessage,
|
||||
}) {
|
||||
return LoginState(
|
||||
email: email ?? this.email,
|
||||
password: password ?? this.password,
|
||||
status: status ?? this.status,
|
||||
errorMessage: errorMessage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [email, password, status, errorMessage];
|
||||
}
|
||||
|
||||
class LoginCubit extends Cubit<LoginState> {
|
||||
final AuthRepository _repository;
|
||||
|
||||
LoginCubit(this._repository) : super(const LoginState());
|
||||
|
||||
void emailChanged(String value) {
|
||||
emit(state.copyWith(email: Email.dirty(value)));
|
||||
}
|
||||
|
||||
void passwordChanged(String value) {
|
||||
emit(state.copyWith(password: Password.dirty(value)));
|
||||
}
|
||||
|
||||
Future<AuthResponse?> submit() async {
|
||||
if (!state.isValid) return null;
|
||||
|
||||
emit(state.copyWith(status: FormzSubmissionStatus.inProgress));
|
||||
|
||||
try {
|
||||
final response = await _repository.login(
|
||||
LoginRequest(email: state.email.value, password: state.password.value),
|
||||
);
|
||||
emit(state.copyWith(status: FormzSubmissionStatus.success));
|
||||
return response;
|
||||
} catch (e) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: FormzSubmissionStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:formz/formz.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:social_app/features/auth/data/auth_repository.dart';
|
||||
import 'package:social_app/features/auth/presentation/cubits/login_cubit.dart';
|
||||
|
||||
class MockAuthRepository extends Mock implements AuthRepository {}
|
||||
|
||||
void main() {
|
||||
late LoginCubit cubit;
|
||||
late MockAuthRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockAuthRepository();
|
||||
cubit = LoginCubit(mockRepository);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
cubit.close();
|
||||
});
|
||||
|
||||
group('LoginCubit', () {
|
||||
test('initial state has pure status', () {
|
||||
expect(cubit.state.status, FormzSubmissionStatus.initial);
|
||||
});
|
||||
|
||||
blocTest<LoginCubit, LoginState>(
|
||||
'emailChanged updates email',
|
||||
build: () => cubit,
|
||||
act: (c) => c.emailChanged('test@example.com'),
|
||||
expect: () => [isA<LoginState>()],
|
||||
);
|
||||
|
||||
blocTest<LoginCubit, LoginState>(
|
||||
'passwordChanged updates password',
|
||||
build: () => cubit,
|
||||
act: (c) => c.passwordChanged('password123'),
|
||||
expect: () => [isA<LoginState>()],
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user