Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lulin/task/add more unit tests #69

Merged
merged 2 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions lib/presentation/settings/viewModels/login_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class LoginViewModel extends ChangeNotifier {
throw Exception('Identity token not available in Apple credentials');
}
// Validate the token with backend and retrieve email if valid
final email = await validateAppleToken(identityToken);
final email = await authUseCase.validateAppleToken(identityToken);

await syncUser(name, email, null);

Expand All @@ -163,7 +163,5 @@ class LoginViewModel extends ChangeNotifier {
}
}

Future<String> validateAppleToken(String identityToken) async {
return await authUseCase.validateAppleToken(identityToken);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ class UpdatePasswordViewModel extends ChangeNotifier {

UpdatePasswordViewModel({required this.authUseCase});

Future<void> updatePassword(String newPassword) async {
Future<String> updatePassword(String newPassword) async {
_setLoadingState(true);
errorMessage = '';
try {
// Call the auth use case to update the password
await authUseCase.updatePassword(newPassword);
final message = await authUseCase.updatePassword(newPassword);
return message;
} catch (error) {
errorMessage = 'Failed to update password.';
return errorMessage;
} finally {
_setLoadingState(false);
}
Expand Down
61 changes: 61 additions & 0 deletions packages/domain/lib/mocks/auth_usecase_mock.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:mockito/mockito.dart';

import '../entities/user.dart';
import '../usecases/auth_usecase.dart';

class MockAuthUseCase extends Mock implements AuthUseCase {
Expand All @@ -21,5 +22,65 @@ class MockAuthUseCase extends Mock implements AuthUseCase {
returnValue: Future.value(''),
returnValueForMissingStub: Future.value(''));

@override
Future<String> validateAppleToken(String identityToken) =>
super.noSuchMethod(Invocation.method(#validateAppleToken, [identityToken]),
returnValue: Future.value(''),
returnValueForMissingStub: Future.value(''));

@override
Future<User> signup(String email, String password, String verificationCode, {String? name}) =>
super.noSuchMethod(
Invocation.method(#signup, [email, password, verificationCode, name]),
returnValue: Future.value(User(name: name, email: email)),
returnValueForMissingStub: Future.value(User(name: 'default', email: email)));

@override
Future<void> sendSignupVerificationCode(String email) =>
super.noSuchMethod(
Invocation.method(#sendSignupVerificationCode, [email]),
returnValue: Future.value(),
returnValueForMissingStub: Future.value(),
);
@override
Future<void> forgetPassword(String email) =>
super.noSuchMethod(
Invocation.method(#forgetPassword, [email]),
returnValue: Future.value(),
returnValueForMissingStub: Future.value(),
);
@override
Future<String> resetPassword(String email, String newPassword, String confirmationCode) =>
super.noSuchMethod(Invocation.method(#resetPassword, [email, newPassword, confirmationCode]),
returnValue: Future.value(''),
returnValueForMissingStub: Future.value(''));

@override
Future<String> updatePassword(String newPassword) =>
super.noSuchMethod(
Invocation.method(#updatePassword, [newPassword]),
returnValue: Future.value(''),
returnValueForMissingStub: Future.value(''));

@override
Future<bool> isLoggedIn() =>
super.noSuchMethod(
Invocation.method(#isLoggedIn, []),
returnValue: Future.value(true), // Corrected to Future<bool>
returnValueForMissingStub: Future.value(false), // Default fallback to false
);

@override
Future<void> logout() =>
super.noSuchMethod(
Invocation.method(#logout, []),
returnValue: Future.value(),
returnValueForMissingStub: Future.value(),
);

}





14 changes: 14 additions & 0 deletions packages/domain/lib/mocks/user_usecase_mock.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'package:mockito/mockito.dart';

import '../entities/user.dart';
import '../usecases/user_usercase.dart';

class MockUserUseCase extends Mock implements UserUseCase {
@override
Future<String> login(String email, String password) =>
super.noSuchMethod(Invocation.method(#login, [email, password]),
returnValue: Future.value(''),
returnValueForMissingStub: Future.value(''));


}
5 changes: 3 additions & 2 deletions packages/domain/lib/usecases/auth_usecase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class AuthUseCaseImpl implements AuthUseCase {
return await repository.forgetPassword(email);
}

Future<String> resetPassword(email, newPassword, confirmationCode) async {
Future<String> resetPassword(String email, String newPassword, String confirmationCode) async {
return await repository.resetPassword(email, newPassword, confirmationCode);
}

Expand All @@ -71,7 +71,8 @@ class AuthUseCaseImpl implements AuthUseCase {
}

Future<String> updatePassword(String newPassword) async {
return await repository.updatePassword(newPassword);
String message = await repository.updatePassword(newPassword);
return message;
}

Future<String> syncUser(String? displayName, String email, String? photoUrl) async {
Expand Down
163 changes: 163 additions & 0 deletions test/forget_passowrd_view_model_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import 'package:domain/entities/user.dart';
import 'package:domain/mocks/auth_usecase_mock.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:swiftcomp/presentation/settings/viewModels/forget_password_view_model.dart';

void main() {
group('ForgetPasswordViewModel Tests', ()
{
group('toggleNewPasswordVisibility', () {
test('should toggle obscureTextNewPassword and notify listeners', () {
final MockAuthUseCase mockAuthUseCase = MockAuthUseCase();
final ForgetPasswordViewModel forgetPasswordViewModel = ForgetPasswordViewModel(authUseCase: mockAuthUseCase);

// Initially true
expect(forgetPasswordViewModel.obscureTextNewPassword, true);

// Toggle
forgetPasswordViewModel.toggleNewPasswordVisibility();
expect(forgetPasswordViewModel.obscureTextNewPassword, false);

// Toggle back
forgetPasswordViewModel.toggleNewPasswordVisibility();
expect(forgetPasswordViewModel.obscureTextNewPassword, true);
});
});

group('toggleConfirmPasswordVisibility', () {
test('should toggle obscureTextConfirmPassword and notify listeners', () {
final MockAuthUseCase mockAuthUseCase = MockAuthUseCase();
final ForgetPasswordViewModel forgetPasswordViewModel = ForgetPasswordViewModel(authUseCase: mockAuthUseCase);

expect(forgetPasswordViewModel.obscureTextConfirmPassword, true);

// Toggle
forgetPasswordViewModel.toggleConfirmPasswordVisibility();
expect(forgetPasswordViewModel.obscureTextConfirmPassword, false);

// Toggle back
forgetPasswordViewModel.toggleConfirmPasswordVisibility();
expect(forgetPasswordViewModel.obscureTextConfirmPassword, true);
});
});

group('forgetPassword', () {
test('should set isLoading to true and back to false during the process', () async {
final MockAuthUseCase mockAuthUseCase = MockAuthUseCase();
final ForgetPasswordViewModel forgetPasswordViewModel = ForgetPasswordViewModel(authUseCase: mockAuthUseCase);

const email = '[email protected]';

when(mockAuthUseCase.forgetPassword(email)).thenAnswer((_) async {});

final future = forgetPasswordViewModel.forgetPassword(email);

// Verify isLoading is true during the process
expect(forgetPasswordViewModel.isLoading, true);

await future;

// Verify isLoading is false after the process
expect(forgetPasswordViewModel.isLoading, false);
});

test('should call forgetPassword with the correct email', () async {
final MockAuthUseCase mockAuthUseCase = MockAuthUseCase();
final ForgetPasswordViewModel forgetPasswordViewModel = ForgetPasswordViewModel(authUseCase: mockAuthUseCase);

const email = '[email protected]';

when(mockAuthUseCase.forgetPassword(email)).thenAnswer((_) async {});

await forgetPasswordViewModel.forgetPassword(email);

verify(mockAuthUseCase.forgetPassword(email)).called(1);
});

test('should set isPasswordResetting to true on successful process', () async {
final MockAuthUseCase mockAuthUseCase = MockAuthUseCase();
final ForgetPasswordViewModel forgetPasswordViewModel = ForgetPasswordViewModel(authUseCase: mockAuthUseCase);

const email = '[email protected]';

when(mockAuthUseCase.forgetPassword(email)).thenAnswer((_) async {});

await forgetPasswordViewModel.forgetPassword(email);

expect(forgetPasswordViewModel.isPasswordResetting, true);
expect(forgetPasswordViewModel.errorMessage, '');
});

test('should set errorMessage on failure and not set isPasswordResetting', () async {
final MockAuthUseCase mockAuthUseCase = MockAuthUseCase();
final ForgetPasswordViewModel forgetPasswordViewModel = ForgetPasswordViewModel(authUseCase: mockAuthUseCase);

const email = '[email protected]';

when(mockAuthUseCase.forgetPassword(email)).thenThrow(Exception('Error'));

await forgetPasswordViewModel.forgetPassword(email);

expect(forgetPasswordViewModel.isPasswordResetting, false);
expect(forgetPasswordViewModel.errorMessage, 'Failed to send confirmation code.');
});

test('should reset isLoading after failure', () async {
final MockAuthUseCase mockAuthUseCase = MockAuthUseCase();
final ForgetPasswordViewModel forgetPasswordViewModel = ForgetPasswordViewModel(authUseCase: mockAuthUseCase);

const email = '[email protected]';

when(mockAuthUseCase.forgetPassword(email)).thenThrow(Exception('Error'));

await forgetPasswordViewModel.forgetPassword(email);

expect(forgetPasswordViewModel.isLoading, false);
});
});
group('resetPassword', () {
test('should call repository with correct parameters', () async {
final MockAuthUseCase mockAuthUseCase = MockAuthUseCase();

const email = '[email protected]';
const newPassword = 'newPassword123';
const confirmationCode = '123456';
const expectedResult = 'Password reset successfully';

// Mock repository behavior
when(mockAuthUseCase.resetPassword(email, newPassword, confirmationCode))
.thenAnswer((_) async => expectedResult);

final result = await mockAuthUseCase.resetPassword(email, newPassword, confirmationCode);

// Verify the method was called with correct parameters
verify(mockAuthUseCase.resetPassword(email, newPassword, confirmationCode)).called(1);

// Verify the result matches the expected value
expect(result, expectedResult);
});

test('should throw an exception if repository throws an error', () async {
final MockAuthUseCase mockAuthUseCase = MockAuthUseCase();

const email = '[email protected]';
const newPassword = 'newPassword123';
const confirmationCode = '123456';

// Mock repository to throw an exception
when(mockAuthUseCase.resetPassword(email, newPassword, confirmationCode))
.thenThrow(Exception('Error resetting password'));

// Verify that the method throws the exception
expect(
() async => await mockAuthUseCase.resetPassword(email, newPassword, confirmationCode),
throwsA(isA<Exception>()),
);

// Verify the method was called with correct parameters
verify(mockAuthUseCase.resetPassword(email, newPassword, confirmationCode)).called(1);
});
});
});
}
Loading