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(); authService = getIt(); licenseService = getIt(); companyService = getIt(); // 로그인 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>()); }); 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>()); }); 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>()); expect(companyLicenses, isA>()); }); }); print('\n🎉 모든 라이센스 통합 테스트 완료!'); }