Files
superport/test/integration/license_integration_test.dart
JiWoong Sul 162fe08618
Some checks failed
Flutter Test & Quality Check / Test on macos-latest (push) Has been cancelled
Flutter Test & Quality Check / Test on ubuntu-latest (push) Has been cancelled
Flutter Test & Quality Check / Build APK (push) Has been cancelled
refactor: Clean Architecture 적용 및 코드베이스 전면 리팩토링
## 주요 변경사항

### 아키텍처 개선
- Clean Architecture 패턴 적용 (Domain, Data, Presentation 레이어 분리)
- Use Case 패턴 도입으로 비즈니스 로직 캡슐화
- Repository 패턴으로 데이터 접근 추상화
- 의존성 주입 구조 개선

### 상태 관리 최적화
- 모든 Controller에서 불필요한 상태 관리 로직 제거
- 페이지네이션 로직 통일 및 간소화
- 에러 처리 로직 개선 (에러 메시지 한글화)
- 로딩 상태 관리 최적화

### Mock 서비스 제거
- MockDataService 완전 제거
- 모든 화면을 실제 API 전용으로 전환
- 불필요한 Mock 관련 코드 정리

### UI/UX 개선
- Overview 화면 대시보드 기능 강화
- 라이선스 만료 알림 위젯 추가
- 사이드바 네비게이션 개선
- 일관된 UI 컴포넌트 사용

### 코드 품질
- 중복 코드 제거 및 함수 추출
- 파일별 책임 분리 명확화
- 테스트 코드 업데이트

## 영향 범위
- 모든 화면의 Controller 리팩토링
- API 통신 레이어 구조 개선
- 에러 처리 및 로깅 시스템 개선

## 향후 계획
- 단위 테스트 커버리지 확대
- 통합 테스트 시나리오 추가
- 성능 모니터링 도구 통합
2025-08-11 00:04:28 +09:00

297 lines
10 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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/services/auth_service.dart';
import 'package:superport/services/license_service.dart';
import 'package:superport/services/company_service.dart';
import 'package:superport/models/license_model.dart';
import 'package:superport/models/company_model.dart';
import 'package:superport/models/address_model.dart';
import 'package:superport/data/models/auth/login_request.dart';
import 'dart:math';
import 'real_api/test_helper.dart';
void main() {
late GetIt getIt;
late AuthService authService;
late LicenseService licenseService;
late CompanyService companyService;
setUpAll(() async {
// RealApiTestHelper를 사용하여 Mock Storage와 함께 테스트 환경 설정
await RealApiTestHelper.setupTestEnvironment();
// GetIt 인스턴스 가져오기
getIt = GetIt.instance;
// 서비스 초기화
authService = getIt<AuthService>();
licenseService = getIt<LicenseService>();
companyService = getIt<CompanyService>();
// 로그인
print('🔐 로그인 중...');
final loginResult = await authService.login(
LoginRequest(
email: 'admin@superport.kr',
password: 'admin123!',
),
);
loginResult.fold(
(failure) => throw Exception('로그인 실패: $failure'),
(response) => print('✅ 로그인 성공: ${response.user.email}'),
);
});
tearDownAll(() async {
await authService.logout();
await RealApiTestHelper.teardownTestEnvironment();
});
group('라이센스 관리 통합 테스트', () {
late Company testCompany;
final random = Random();
setUpAll(() async {
// 테스트용 회사 조회 또는 생성
print('🏢 테스트용 회사 준비 중...');
final companies = await companyService.getCompanies();
if (companies.isNotEmpty) {
testCompany = companies.first;
print('✅ 기존 회사 사용: ${testCompany.name}');
} else {
// 회사가 없으면 생성
testCompany = await companyService.createCompany(
Company(
name: 'Test Company ${random.nextInt(10000)}',
address: Address(
detailAddress: '서울시 강남구 테헤란로 123',
),
contactName: '테스트 담당자',
contactPhone: '010-1234-5678',
contactEmail: 'test@test.com',
),
);
print('✅ 새 회사 생성: ${testCompany.name}');
}
});
test('1. 라이센스 목록 조회', () async {
print('\n📋 라이센스 목록 조회 테스트...');
final licenses = await licenseService.getLicenses();
print('✅ 라이센스 ${licenses.length}개 조회 성공');
expect(licenses, isA<List<License>>());
});
test('2. 라이센스 생성', () async {
print('\n 라이센스 생성 테스트...');
final newLicense = License(
licenseKey: 'TEST-${DateTime.now().millisecondsSinceEpoch}',
productName: 'Flutter Test Product',
vendor: 'Test Vendor',
licenseType: 'subscription',
userCount: 10,
purchaseDate: DateTime.now(),
expiryDate: DateTime.now().add(Duration(days: 365)),
purchasePrice: 100000.0,
companyId: testCompany.id,
remark: '통합 테스트용 라이센스',
isActive: true,
);
final createdLicense = await licenseService.createLicense(newLicense);
print('✅ 라이센스 생성 성공: ${createdLicense.licenseKey}');
expect(createdLicense.id, isNotNull);
expect(createdLicense.licenseKey, equals(newLicense.licenseKey));
expect(createdLicense.companyId, equals(testCompany.id));
});
test('3. 라이센스 상세 조회', () async {
print('\n🔍 라이센스 상세 조회 테스트...');
// 먼저 목록을 조회하여 ID 획득
final licenses = await licenseService.getLicenses();
if (licenses.isEmpty) {
print('⚠️ 조회할 라이센스가 없습니다.');
return;
}
final targetId = licenses.first.id!;
final license = await licenseService.getLicenseById(targetId);
print('✅ 라이센스 상세 조회 성공: ${license.licenseKey}');
expect(license.id, equals(targetId));
expect(license.licenseKey, isNotEmpty);
});
test('4. 라이센스 수정', () async {
print('\n✏️ 라이센스 수정 테스트...');
// 먼저 라이센스 생성
final newLicense = License(
licenseKey: 'UPDATE-TEST-${DateTime.now().millisecondsSinceEpoch}',
productName: 'Original Product',
vendor: 'Original Vendor',
licenseType: 'perpetual',
userCount: 5,
purchaseDate: DateTime.now(),
expiryDate: DateTime.now().add(Duration(days: 180)),
purchasePrice: 50000.0,
companyId: testCompany.id,
remark: '수정 테스트용',
isActive: true,
);
final createdLicense = await licenseService.createLicense(newLicense);
print('✅ 수정할 라이센스 생성: ${createdLicense.licenseKey}');
// 라이센스 수정
final updatedLicense = License(
id: createdLicense.id,
licenseKey: createdLicense.licenseKey,
productName: 'Updated Product',
vendor: 'Updated Vendor',
licenseType: 'subscription',
userCount: 20,
purchaseDate: createdLicense.purchaseDate,
expiryDate: DateTime.now().add(Duration(days: 730)),
purchasePrice: 200000.0,
companyId: testCompany.id,
remark: '수정됨',
isActive: true,
);
final result = await licenseService.updateLicense(updatedLicense);
print('✅ 라이센스 수정 성공');
expect(result.productName, equals('Updated Product'));
expect(result.vendor, equals('Updated Vendor'));
expect(result.userCount, equals(20));
});
test('5. 라이센스 삭제', () async {
print('\n🗑️ 라이센스 삭제 테스트...');
// 삭제할 라이센스 생성
final newLicense = License(
licenseKey: 'DELETE-TEST-${DateTime.now().millisecondsSinceEpoch}',
productName: 'Delete Test Product',
vendor: 'Delete Test Vendor',
licenseType: 'trial',
userCount: 1,
purchaseDate: DateTime.now(),
expiryDate: DateTime.now().add(Duration(days: 30)),
purchasePrice: 0.0,
companyId: testCompany.id,
remark: '삭제 테스트용',
isActive: true,
);
final createdLicense = await licenseService.createLicense(newLicense);
print('✅ 삭제할 라이센스 생성: ${createdLicense.licenseKey}');
// 라이센스 삭제
await licenseService.deleteLicense(createdLicense.id!);
print('✅ 라이센스 삭제 성공');
// 삭제 확인
try {
await licenseService.getLicenseById(createdLicense.id!);
fail('삭제된 라이센스가 여전히 조회됩니다');
} catch (e) {
print('✅ 삭제 확인: 라이센스가 정상적으로 삭제되었습니다');
}
});
test('6. 만료 예정 라이센스 조회', () async {
print('\n⏰ 만료 예정 라이센스 조회 테스트...');
// 30일 이내 만료 예정 라이센스 생성
final expiringLicense = License(
licenseKey: 'EXPIRING-${DateTime.now().millisecondsSinceEpoch}',
productName: 'Soon Expiring Product',
vendor: 'Test Vendor',
licenseType: 'subscription',
userCount: 5,
purchaseDate: DateTime.now(),
expiryDate: DateTime.now().add(Duration(days: 15)), // 15일 후 만료
purchasePrice: 10000.0,
companyId: testCompany.id,
remark: '만료 예정 테스트',
isActive: true,
);
await licenseService.createLicense(expiringLicense);
print('✅ 만료 예정 라이센스 생성 (15일 후 만료)');
final expiringLicenses = await licenseService.getExpiringLicenses(days: 30);
print('✅ 만료 예정 라이센스 ${expiringLicenses.length}개 조회');
expect(expiringLicenses, isA<List<License>>());
});
test('7. 에러 처리 테스트', () async {
print('\n❌ 에러 처리 테스트...');
// 잘못된 ID로 조회
try {
await licenseService.getLicenseById(999999);
fail('존재하지 않는 라이센스 조회가 성공했습니다');
} catch (e) {
print('✅ 잘못된 ID 에러 처리 성공: $e');
}
// 필수 필드 누락
try {
final invalidLicense = License(
licenseKey: '', // 빈 라이센스 키
productName: 'Invalid Product',
companyId: testCompany.id,
);
await licenseService.createLicense(invalidLicense);
fail('유효하지 않은 라이센스 생성이 성공했습니다');
} catch (e) {
print('✅ 유효성 검증 에러 처리 성공: $e');
}
});
test('8. 페이지네이션 테스트', () async {
print('\n📄 페이지네이션 테스트...');
// 첫 페이지
final page1 = await licenseService.getLicenses(page: 1, perPage: 5);
print('✅ 1페이지: ${page1.length}개 라이센스');
// 두 번째 페이지
final page2 = await licenseService.getLicenses(page: 2, perPage: 5);
print('✅ 2페이지: ${page2.length}개 라이센스');
expect(page1.length, lessThanOrEqualTo(5));
expect(page2.length, lessThanOrEqualTo(5));
});
test('9. 필터링 테스트', () async {
print('\n🔎 필터링 테스트...');
// 활성 라이센스만 조회
final activeLicenses = await licenseService.getLicenses(isActive: true);
print('✅ 활성 라이센스: ${activeLicenses.length}');
// 특정 회사 라이센스만 조회
final companyLicenses = await licenseService.getLicenses(
companyId: testCompany.id,
);
print('${testCompany.name} 라이센스: ${companyLicenses.length}');
expect(activeLicenses, isA<List<License>>());
expect(companyLicenses, isA<List<License>>());
});
});
print('\n🎉 모든 라이센스 통합 테스트 완료!');
}