Files
superport/test/integration/license_integration_test.dart
JiWoong Sul c8dd1ff815
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: 프로젝트 구조 개선 및 테스트 시스템 강화
주요 변경사항:
- CLAUDE.md: 프로젝트 규칙 v2.0으로 업데이트, 아키텍처 명확화
- 불필요한 문서 제거: NEXT_TASKS.md, TEST_PROGRESS.md, test_results 파일들
- 테스트 시스템 개선: 실제 API 테스트 스위트 추가 (15개 새 테스트 파일)
- License 관리: DTO 모델 개선, API 응답 처리 최적화
- 에러 처리: Interceptor 로직 강화, 상세 로깅 추가
- Company/User/Warehouse 테스트: 자동화 테스트 안정성 향상
- Phone Utils: 전화번호 포맷팅 로직 개선
- Overview Controller: 대시보드 데이터 로딩 최적화
- Analysis Options: Flutter 린트 규칙 추가

테스트 개선:
- company_real_api_test.dart: 실제 API 회사 관리 테스트
- equipment_in/out_real_api_test.dart: 장비 입출고 API 테스트
- license_real_api_test.dart: 라이선스 관리 API 테스트
- user_real_api_test.dart: 사용자 관리 API 테스트
- warehouse_location_real_api_test.dart: 창고 위치 API 테스트
- filter_sort_test.dart: 필터링/정렬 기능 테스트
- pagination_test.dart: 페이지네이션 테스트
- interactive_search_test.dart: 검색 기능 테스트
- overview_dashboard_test.dart: 대시보드 통합 테스트

코드 품질:
- 모든 서비스에 에러 처리 강화
- DTO 모델 null safety 개선
- 테스트 커버리지 확대
- 불필요한 로그 파일 제거로 리포지토리 정리

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-07 17:16:30 +09:00

301 lines
11 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:dio/dio.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 'package:dartz/dartz.dart';
import 'dart:math';
import 'real_api/test_helper.dart';
void main() {
late GetIt getIt;
late AuthService authService;
late LicenseService licenseService;
late CompanyService companyService;
late ApiClient apiClient;
setUpAll(() async {
// RealApiTestHelper를 사용하여 Mock Storage와 함께 테스트 환경 설정
await RealApiTestHelper.setupTestEnvironment();
// GetIt 인스턴스 가져오기
getIt = GetIt.instance;
// 서비스 초기화
apiClient = getIt<ApiClient>();
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🎉 모든 라이센스 통합 테스트 완료!');
}