import 'package:flutter_test/flutter_test.dart'; import 'package:get_it/get_it.dart'; import 'package:superport/data/datasources/remote/api_client.dart'; import 'package:superport/data/datasources/remote/auth_remote_datasource.dart'; import 'package:superport/services/auth_service.dart'; import 'package:superport/data/models/auth/login_request.dart'; import 'package:superport/core/errors/failures.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import '../mock/mock_secure_storage.dart'; void main() { late GetIt getIt; late ApiClient apiClient; late AuthService authService; setUpAll(() async { // GetIt 초기화 getIt = GetIt.instance; await getIt.reset(); // 환경 변수 로드 및 초기화 try { await dotenv.load(fileName: '.env.test'); // 테스트 환경 파일 로드 성공 } catch (e) { // 테스트 환경 파일 없음, 기본값 사용 // 기본값으로 환경 변수 설정 dotenv.testLoad(fileInput: ''' API_BASE_URL=http://43.201.34.104:8080/api/v1 API_TIMEOUT=30000 ENABLE_LOGGING=true USE_API=true '''); } // API 클라이언트 설정 apiClient = ApiClient(); getIt.registerSingleton(apiClient); // SecureStorage 설정 (테스트용 Mock 사용) final secureStorage = MockSecureStorage(); getIt.registerSingleton(secureStorage); // AuthRemoteDataSource 등록 getIt.registerLazySingleton( () => AuthRemoteDataSourceImpl(apiClient), ); // AuthService 등록 getIt.registerLazySingleton( () => AuthServiceImpl( getIt(), getIt(), ), ); authService = getIt(); }); tearDownAll(() async { // 로그아웃 try { await authService.logout(); } catch (e) { // 로그아웃 중 오류: $e } // GetIt 정리 await getIt.reset(); }); group('로그인 화면 통합 테스트', () { test('유효한 계정으로 로그인 성공', () async { // Arrange final loginRequest = LoginRequest( email: 'admin@superport.kr', password: 'admin123!', ); // Act final result = await authService.login(loginRequest); // Assert // 로그인 결과: ${result.isRight() ? "성공" : "실패"} expect(result.isRight(), true); result.fold( (failure) => fail('로그인이 실패했습니다: ${failure.message}'), (response) { expect(response.accessToken, isNotEmpty); expect(response.user, isNotNull); expect(response.user.email, equals('admin@superport.kr')); expect(response.user.role, isNotEmpty); // 로그인 성공 }, ); // 로그인 상태 확인 final isLoggedIn = await authService.isLoggedIn(); expect(isLoggedIn, true); // 현재 사용자 정보 확인 final currentUser = await authService.getCurrentUser(); expect(currentUser, isNotNull); expect(currentUser?.email, equals('admin@superport.kr')); }); test('잘못된 비밀번호로 로그인 실패', () async { // Arrange final loginRequest = LoginRequest( email: 'admin@superport.kr', password: 'wrongpassword', ); // Act final result = await authService.login(loginRequest); // Assert expect(result.isLeft(), true); result.fold( (failure) { expect(failure, isA()); expect(failure.message, contains('자격 증명')); // 예상된 로그인 실패: ${failure.message} }, (_) => fail('잘못된 비밀번호로 로그인이 성공했습니다'), ); }); test('존재하지 않는 이메일로 로그인 실패', () async { // Arrange final timestamp = DateTime.now().millisecondsSinceEpoch; final loginRequest = LoginRequest( email: 'nonexistent$timestamp@test.com', password: 'anypassword', ); // Act final result = await authService.login(loginRequest); // Assert expect(result.isLeft(), true); result.fold( (failure) { expect(failure, isA()); // 예상된 로그인 실패: ${failure.message} }, (_) => fail('존재하지 않는 이메일로 로그인이 성공했습니다'), ); }); test('이메일 형식 검증', () async { // Arrange final loginRequest = LoginRequest( email: 'invalid-email-format', password: 'password123', ); // Act final result = await authService.login(loginRequest); // Assert expect(result.isLeft(), true); result.fold( (failure) { expect(failure, isA()); // 예상된 검증 실패: ${failure.message} }, (_) => fail('잘못된 이메일 형식으로 로그인이 성공했습니다'), ); }); test('빈 필드로 로그인 시도', () async { // 빈 이메일 final emptyEmailRequest = LoginRequest( email: '', password: 'password123', ); final result1 = await authService.login(emptyEmailRequest); expect(result1.isLeft(), true); // 빈 비밀번호 final emptyPasswordRequest = LoginRequest( email: 'admin@superport.kr', password: '', ); final result2 = await authService.login(emptyPasswordRequest); expect(result2.isLeft(), true); }); test('로그아웃 기능 테스트', () async { // 먼저 로그인 final loginRequest = LoginRequest( email: 'admin@superport.kr', password: 'admin123!', ); final loginResult = await authService.login(loginRequest); expect(loginResult.isRight(), true); // 로그인 상태 확인 var isLoggedIn = await authService.isLoggedIn(); expect(isLoggedIn, true); // 로그아웃 await authService.logout(); // 로그아웃 후 상태 확인 isLoggedIn = await authService.isLoggedIn(); expect(isLoggedIn, false); final currentUser = await authService.getCurrentUser(); expect(currentUser, isNull); // 로그아웃 성공 }); test('토큰 갱신 기능 테스트', () async { // 먼저 로그인 final loginRequest = LoginRequest( email: 'admin@superport.kr', password: 'admin123!', ); final loginResult = await authService.login(loginRequest); expect(loginResult.isRight(), true); String? originalToken; loginResult.fold( (_) {}, (response) => originalToken = response.accessToken, ); // 토큰 갱신 final refreshResult = await authService.refreshToken(); expect(refreshResult.isRight(), true); refreshResult.fold( (failure) => fail('토큰 갱신 실패: ${failure.message}'), (newTokenResponse) { expect(newTokenResponse.accessToken, isNotEmpty); expect(newTokenResponse.accessToken, isNot(equals(originalToken))); // 토큰 갱신 성공 }, ); }); }); }