- Introduced tests for `PoultryScienceRepositoryImp` to validate delegated remote calls. - Added comprehensive tests for `SearchableDropdownLogic` covering selection, overlay, and search logic. - Enhanced `SearchableDropdown` widget tests for multi-select, label building, and overlay management.
235 lines
7.3 KiB
Dart
235 lines
7.3 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:mocktail/mocktail.dart';
|
|
import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote.dart';
|
|
import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart';
|
|
import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart';
|
|
import 'package:rasadyar_chicken/data/repositories/auth/auth_repository_imp.dart';
|
|
|
|
class MockAuthRemoteDataSource extends Mock implements AuthRemoteDataSource {}
|
|
|
|
void main() {
|
|
late AuthRepositoryImpl authRepository;
|
|
late MockAuthRemoteDataSource mockAuthRemote;
|
|
|
|
setUp(() {
|
|
mockAuthRemote = MockAuthRemoteDataSource();
|
|
authRepository = AuthRepositoryImpl(mockAuthRemote);
|
|
});
|
|
|
|
group('Authentication Flow Integration Tests', () {
|
|
group('Complete Login Flow', () {
|
|
test('should complete full login flow successfully', () async {
|
|
// Arrange
|
|
const phoneNumber = '09123456789';
|
|
final authRequest = {
|
|
'username': 'test@example.com',
|
|
'password': 'password',
|
|
};
|
|
|
|
final expectedUserInfo = UserInfoModel(
|
|
isUser: true,
|
|
address: 'Test Address',
|
|
backend: 'test-backend',
|
|
apiKey: 'test-api-key',
|
|
);
|
|
|
|
final expectedUserProfile = UserProfileModel(
|
|
accessToken: 'access-token',
|
|
expiresIn: '3600',
|
|
scope: 'read write',
|
|
expireTime: '2024-12-31T23:59:59Z',
|
|
mobile: phoneNumber,
|
|
fullname: 'John Doe',
|
|
firstname: 'John',
|
|
lastname: 'Doe',
|
|
);
|
|
|
|
// Mock the flow
|
|
when(
|
|
() => mockAuthRemote.getUserInfo(phoneNumber),
|
|
).thenAnswer((_) async => expectedUserInfo);
|
|
|
|
when(
|
|
() => mockAuthRemote.login(authRequest: authRequest),
|
|
).thenAnswer((_) async => expectedUserProfile);
|
|
|
|
// Act - Step 1: Get user info
|
|
final userInfo = await authRepository.getUserInfo(phoneNumber);
|
|
expect(userInfo, equals(expectedUserInfo));
|
|
|
|
// Act - Step 2: Login
|
|
final userProfile = await authRepository.login(
|
|
authRequest: authRequest,
|
|
);
|
|
|
|
// Assert
|
|
expect(userProfile, equals(expectedUserProfile));
|
|
verify(() => mockAuthRemote.getUserInfo(phoneNumber)).called(1);
|
|
verify(() => mockAuthRemote.login(authRequest: authRequest)).called(1);
|
|
});
|
|
|
|
test('should handle login flow with authentication check', () async {
|
|
// Arrange
|
|
final authRequest = {
|
|
'username': 'test@example.com',
|
|
'password': 'password',
|
|
};
|
|
final expectedUserProfile = UserProfileModel(
|
|
accessToken: 'access-token',
|
|
expiresIn: '3600',
|
|
scope: 'read write',
|
|
expireTime: '2024-12-31T23:59:59Z',
|
|
mobile: '09123456789',
|
|
fullname: 'John Doe',
|
|
firstname: 'John',
|
|
lastname: 'Doe',
|
|
);
|
|
|
|
// Mock the flow
|
|
when(
|
|
() => mockAuthRemote.hasAuthenticated(),
|
|
).thenAnswer((_) async => false);
|
|
|
|
when(
|
|
() => mockAuthRemote.login(authRequest: authRequest),
|
|
).thenAnswer((_) async => expectedUserProfile);
|
|
|
|
// Act - Step 1: Check authentication status
|
|
final isAuthenticated = await authRepository.hasAuthenticated();
|
|
expect(isAuthenticated, isFalse);
|
|
|
|
// Act - Step 2: Login
|
|
final userProfile = await authRepository.login(
|
|
authRequest: authRequest,
|
|
);
|
|
|
|
// Assert
|
|
expect(userProfile, equals(expectedUserProfile));
|
|
verify(() => mockAuthRemote.hasAuthenticated()).called(1);
|
|
verify(() => mockAuthRemote.login(authRequest: authRequest)).called(1);
|
|
});
|
|
});
|
|
|
|
group('Error Handling in Authentication Flow', () {
|
|
test('should handle user info retrieval failure', () async {
|
|
// Arrange
|
|
const phoneNumber = '09123456789';
|
|
|
|
when(
|
|
() => mockAuthRemote.getUserInfo(phoneNumber),
|
|
).thenAnswer((_) async => null);
|
|
|
|
// Act
|
|
final userInfo = await authRepository.getUserInfo(phoneNumber);
|
|
|
|
// Assert
|
|
expect(userInfo, isNull);
|
|
verify(() => mockAuthRemote.getUserInfo(phoneNumber)).called(1);
|
|
});
|
|
|
|
test('should handle login failure after successful user info', () async {
|
|
// Arrange
|
|
const phoneNumber = '09123456789';
|
|
final authRequest = {
|
|
'username': 'test@example.com',
|
|
'password': 'wrong',
|
|
};
|
|
|
|
final expectedUserInfo = UserInfoModel(
|
|
isUser: true,
|
|
address: 'Test Address',
|
|
backend: 'test-backend',
|
|
apiKey: 'test-api-key',
|
|
);
|
|
|
|
// Mock the flow
|
|
when(
|
|
() => mockAuthRemote.getUserInfo(phoneNumber),
|
|
).thenAnswer((_) async => expectedUserInfo);
|
|
|
|
when(
|
|
() => mockAuthRemote.login(authRequest: authRequest),
|
|
).thenAnswer((_) async => null);
|
|
|
|
// Act - Step 1: Get user info (success)
|
|
final userInfo = await authRepository.getUserInfo(phoneNumber);
|
|
expect(userInfo, equals(expectedUserInfo));
|
|
|
|
// Act - Step 2: Login (failure)
|
|
final userProfile = await authRepository.login(
|
|
authRequest: authRequest,
|
|
);
|
|
|
|
// Assert
|
|
expect(userProfile, isNull);
|
|
verify(() => mockAuthRemote.getUserInfo(phoneNumber)).called(1);
|
|
verify(() => mockAuthRemote.login(authRequest: authRequest)).called(1);
|
|
});
|
|
});
|
|
|
|
group('Logout Flow', () {
|
|
test('should complete logout flow', () async {
|
|
// Arrange
|
|
when(() => mockAuthRemote.logout()).thenAnswer((_) async {});
|
|
|
|
// Act
|
|
await authRepository.logout();
|
|
|
|
// Assert
|
|
verify(() => mockAuthRemote.logout()).called(1);
|
|
});
|
|
});
|
|
|
|
group('Authentication State Management', () {
|
|
test('should track authentication state correctly', () async {
|
|
// Arrange
|
|
when(
|
|
() => mockAuthRemote.hasAuthenticated(),
|
|
).thenAnswer((_) async => true);
|
|
|
|
// Act
|
|
final isAuthenticated = await authRepository.hasAuthenticated();
|
|
|
|
// Assert
|
|
expect(isAuthenticated, isTrue);
|
|
verify(() => mockAuthRemote.hasAuthenticated()).called(1);
|
|
});
|
|
|
|
test('should handle authentication state changes', () async {
|
|
// Arrange
|
|
when(
|
|
() => mockAuthRemote.hasAuthenticated(),
|
|
).thenAnswer((_) async => false);
|
|
|
|
// Act
|
|
final isAuthenticated = await authRepository.hasAuthenticated();
|
|
|
|
// Assert
|
|
expect(isAuthenticated, isFalse);
|
|
verify(() => mockAuthRemote.hasAuthenticated()).called(1);
|
|
});
|
|
});
|
|
|
|
group('User Info Management', () {
|
|
test('should get user info by phone', () async {
|
|
// Arrange
|
|
const phone = '09123456789';
|
|
final expectedUserInfo = UserInfoModel(
|
|
isUser: true,
|
|
address: 'Test Address',
|
|
backend: 'test-backend',
|
|
apiKey: 'test-api-key',
|
|
);
|
|
when(
|
|
() => mockAuthRemote.getUserInfo(phone),
|
|
).thenAnswer((_) async => expectedUserInfo);
|
|
// Act
|
|
final res = await authRepository.getUserInfo(phone);
|
|
// Assert
|
|
expect(res, expectedUserInfo);
|
|
verify(() => mockAuthRemote.getUserInfo(phone)).called(1);
|
|
});
|
|
});
|
|
});
|
|
}
|