Files
rasadyar_application/packages/chicken/test/integration/auth_flow_integration_test.dart

235 lines
7.3 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote.dart';
import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart';
import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.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);
});
});
});
}