Skip to content

Commit

Permalink
Lulin/task/add more unit tests (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ida631 authored Nov 29, 2024
1 parent 60713c0 commit 015ed97
Show file tree
Hide file tree
Showing 10 changed files with 855 additions and 117 deletions.
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

0 comments on commit 015ed97

Please sign in to comment.