Files
superport/test/domain/usecases/auth/login_usecase_test.dart
JiWoong Sul 1e6da44917
Some checks failed
Flutter Test & Quality Check / Build APK (push) Has been cancelled
Flutter Test & Quality Check / Test on macos-latest (push) Has been cancelled
Flutter Test & Quality Check / Test on ubuntu-latest (push) Has been cancelled
refactor: UI 화면 통합 및 불필요한 파일 정리
- 모든 *_redesign.dart 파일을 기본 화면 파일로 통합
- 백업용 컨트롤러 파일들 제거 (*_controller.backup.dart)
- 사용하지 않는 예제 및 테스트 파일 제거
- Clean Architecture 적용 후 남은 정리 작업 완료
- 테스트 코드 정리 및 구조 개선 준비

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-11 14:00:44 +09:00

231 lines
6.6 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:mockito/annotations.dart';
import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:superport/domain/usecases/auth/login_usecase.dart';
import 'package:superport/domain/usecases/base_usecase.dart';
import 'package:superport/services/auth_service.dart';
import 'package:superport/data/models/auth/login_request.dart';
import 'package:superport/data/models/auth/login_response.dart';
import 'package:superport/data/models/auth/auth_user.dart';
import 'package:superport/core/errors/failures.dart' as failures;
import 'login_usecase_test.mocks.dart';
@GenerateMocks([AuthService])
void main() {
late LoginUseCase loginUseCase;
late MockAuthService mockAuthService;
setUp(() {
mockAuthService = MockAuthService();
loginUseCase = LoginUseCase(mockAuthService);
});
group('LoginUseCase', () {
const tEmail = 'test@example.com';
const tPassword = 'password123!';
const tInvalidEmail = 'invalid-email';
const tEmptyPassword = '';
final tLoginRequest = LoginRequest(
email: tEmail,
password: tPassword,
);
final tLoginResponse = LoginResponse(
accessToken: 'test_access_token',
refreshToken: 'test_refresh_token',
tokenType: 'Bearer',
expiresIn: 3600,
user: AuthUser(
id: 1,
username: 'testuser',
email: tEmail,
name: 'Test User',
role: 'U',
),
);
test('로그인 성공 시 Right(LoginResponse) 반환', () async {
// arrange
when(mockAuthService.login(any))
.thenAnswer((_) async => Right(tLoginResponse));
// act
final result = await loginUseCase(
LoginParams(email: tEmail, password: tPassword),
);
// assert
expect(result, Right(tLoginResponse));
verify(mockAuthService.login(argThat(
predicate<LoginRequest>((req) =>
req.email == tEmail && req.password == tPassword),
))).called(1);
verifyNoMoreInteractions(mockAuthService);
});
test('잘못된 이메일 형식 입력 시 ValidationFailure 반환', () async {
// act
final result = await loginUseCase(
LoginParams(email: tInvalidEmail, password: tPassword),
);
// assert
expect(result.isLeft(), true);
result.fold(
(failure) {
expect(failure, isA<failures.Failure>());
expect(failure.message, '올바른 이메일 형식이 아닙니다.');
},
(_) => fail('Should return failure'),
);
verifyNever(mockAuthService.login(any));
});
test('빈 비밀번호 입력 시 ValidationFailure 반환', () async {
// act
final result = await loginUseCase(
LoginParams(email: tEmail, password: tEmptyPassword),
);
// assert
expect(result.isLeft(), true);
result.fold(
(failure) {
expect(failure, isA<failures.Failure>());
expect(failure.message, '비밀번호를 입력해주세요.');
},
(_) => fail('Should return failure'),
);
verifyNever(mockAuthService.login(any));
});
test('401 에러 시 AuthFailure 반환', () async {
// arrange
final dioError = DioException(
requestOptions: RequestOptions(path: '/login'),
response: Response(
requestOptions: RequestOptions(path: '/login'),
statusCode: 401,
),
type: DioExceptionType.badResponse,
);
when(mockAuthService.login(any)).thenThrow(dioError);
// act
final result = await loginUseCase(
LoginParams(email: tEmail, password: tPassword),
);
// assert
expect(result.isLeft(), true);
result.fold(
(failure) {
expect(failure, isA<failures.Failure>());
expect(failure.message, contains('인증'));
},
(_) => fail('Should return failure'),
);
});
test('네트워크 타임아웃 시 NetworkFailure 반환', () async {
// arrange
final dioError = DioException(
requestOptions: RequestOptions(path: '/login'),
type: DioExceptionType.connectionTimeout,
);
when(mockAuthService.login(any)).thenThrow(dioError);
// act
final result = await loginUseCase(
LoginParams(email: tEmail, password: tPassword),
);
// assert
expect(result.isLeft(), true);
result.fold(
(failure) {
expect(failure, isA<failures.Failure>());
expect(failure.message, contains('네트워크'));
},
(_) => fail('Should return failure'),
);
});
test('서버 에러 시 ServerFailure 반환', () async {
// arrange
final dioError = DioException(
requestOptions: RequestOptions(path: '/login'),
response: Response(
requestOptions: RequestOptions(path: '/login'),
statusCode: 500,
data: {'message': '서버 내부 오류'},
),
type: DioExceptionType.badResponse,
);
when(mockAuthService.login(any)).thenThrow(dioError);
// act
final result = await loginUseCase(
LoginParams(email: tEmail, password: tPassword),
);
// assert
expect(result.isLeft(), true);
result.fold(
(failure) {
expect(failure, isA<failures.Failure>());
expect(failure.message, contains('서버'));
},
(_) => fail('Should return failure'),
);
});
test('예상치 못한 에러 시 UnknownFailure 반환', () async {
// arrange
when(mockAuthService.login(any))
.thenThrow(Exception('Unexpected error'));
// act
final result = await loginUseCase(
LoginParams(email: tEmail, password: tPassword),
);
// assert
expect(result.isLeft(), true);
result.fold(
(failure) {
expect(failure, isA<failures.Failure>());
expect(failure.message, contains('오류'));
},
(_) => fail('Should return failure'),
);
});
test('로그인 실패 시 (null 반환) AuthFailure 반환', () async {
// arrange
when(mockAuthService.login(any)).thenAnswer((_) async => Left(failures.AuthenticationFailure(message: '로그인에 실패했습니다.')));
// act
final result = await loginUseCase(
LoginParams(email: tEmail, password: tPassword),
);
// assert
expect(result.isLeft(), true);
result.fold(
(failure) {
expect(failure, isA<failures.Failure>());
expect(failure.message, contains('로그인'));
},
(_) => fail('Should return failure'),
);
});
});
}