import 'package:flutter_test/flutter_test.dart'; import 'package:get_it/get_it.dart'; import 'package:superport/models/license_model.dart'; import 'package:superport/services/license_service.dart'; import 'package:superport/services/company_service.dart'; import 'test_helper.dart'; void main() { late LicenseService licenseService; late CompanyService companyService; String? authToken; int? createdLicenseId; int? testCompanyId; setUpAll(() async { await RealApiTestHelper.setupTestEnvironment(); // 로그인하여 인증 토큰 획득 authToken = await RealApiTestHelper.loginAndGetToken(); expect(authToken, isNotNull, reason: '로그인에 실패했습니다'); // 서비스 가져오기 licenseService = GetIt.instance(); companyService = GetIt.instance(); // 테스트용 회사 가져오기 final companies = await companyService.getCompanies(page: 1, perPage: 1); if (companies.isNotEmpty) { testCompanyId = companies.first.id; } }); tearDownAll(() async { await RealApiTestHelper.teardownTestEnvironment(); }); group('License CRUD API 테스트', skip: 'Real API tests - skipping in CI', () { test('라이선스 목록 조회', () async { final licenses = await licenseService.getLicenses( page: 1, perPage: 10, ); expect(licenses, isNotNull); expect(licenses, isA>()); if (licenses.isNotEmpty) { final firstLicense = licenses.first; expect(firstLicense.id, isNotNull); expect(firstLicense.licenseKey, isNotEmpty); expect(firstLicense.productName, isNotNull); } }); test('라이선스 생성', () async { if (testCompanyId == null) { // 라이선스를 생성할 회사가 없습니다 return; } final newLicense = License( licenseKey: 'TEST-KEY-${DateTime.now().millisecondsSinceEpoch}', productName: 'Integration Test License ${DateTime.now().millisecondsSinceEpoch}', vendor: 'Test Vendor', licenseType: 'subscription', userCount: 10, purchaseDate: DateTime.now(), expiryDate: DateTime.now().add(const Duration(days: 365)), purchasePrice: 1000000, companyId: testCompanyId!, isActive: true, ); final createdLicense = await licenseService.createLicense(newLicense); expect(createdLicense, isNotNull); expect(createdLicense.id, isNotNull); expect(createdLicense.licenseKey, equals(newLicense.licenseKey)); expect(createdLicense.productName, equals(newLicense.productName)); expect(createdLicense.companyId, equals(testCompanyId)); expect(createdLicense.userCount, equals(10)); createdLicenseId = createdLicense.id; }); test('라이선스 상세 조회', () async { if (createdLicenseId == null) { // 라이선스 목록에서 첫 번째 라이선스 ID 사용 final licenses = await licenseService.getLicenses(page: 1, perPage: 1); if (licenses.isEmpty) { // 조회할 라이선스가 없습니다 return; } createdLicenseId = licenses.first.id; } final license = await licenseService.getLicenseById(createdLicenseId!); expect(license, isNotNull); expect(license.id, equals(createdLicenseId)); expect(license.licenseKey, isNotEmpty); expect(license.productName, isNotNull); }); test('라이선스 정보 수정', () async { if (createdLicenseId == null) { // 수정할 라이선스가 없습니다 return; } // 먼저 현재 라이선스 정보 조회 final currentLicense = await licenseService.getLicenseById(createdLicenseId!); // 수정할 정보 final updatedLicense = License( id: currentLicense.id, licenseKey: currentLicense.licenseKey, productName: '${currentLicense.productName} - Updated', vendor: currentLicense.vendor, licenseType: currentLicense.licenseType, userCount: 20, // 사용자 수 증가 purchaseDate: currentLicense.purchaseDate, expiryDate: currentLicense.expiryDate, purchasePrice: currentLicense.purchasePrice, companyId: currentLicense.companyId, isActive: currentLicense.isActive, ); final result = await licenseService.updateLicense(updatedLicense); expect(result, isNotNull); expect(result.id, equals(createdLicenseId)); expect(result.productName, contains('Updated')); expect(result.userCount, equals(20)); }); test('라이선스 활성/비활성 토글', () async { if (createdLicenseId == null) { // 토글할 라이선스가 없습니다 return; } // 현재 상태 확인 final currentLicense = await licenseService.getLicenseById(createdLicenseId!); final currentStatus = currentLicense.isActive; // 상태 토글 final toggledLicense = License( id: currentLicense.id, licenseKey: currentLicense.licenseKey, productName: currentLicense.productName, vendor: currentLicense.vendor, licenseType: currentLicense.licenseType, userCount: currentLicense.userCount, purchaseDate: currentLicense.purchaseDate, expiryDate: currentLicense.expiryDate, purchasePrice: currentLicense.purchasePrice, companyId: currentLicense.companyId, isActive: !currentStatus, ); await licenseService.updateLicense(toggledLicense); // 변경된 상태 확인 final updatedLicense = await licenseService.getLicenseById(createdLicenseId!); expect(updatedLicense.isActive, equals(!currentStatus)); }); test('만료 예정 라이선스 조회', () async { final expiringLicenses = await licenseService.getExpiringLicenses(days: 30); expect(expiringLicenses, isNotNull); expect(expiringLicenses, isA>()); if (expiringLicenses.isNotEmpty) { // 모든 라이선스가 30일 이내 만료 예정인지 확인 final now = DateTime.now(); for (final license in expiringLicenses) { if (license.expiryDate != null) { final daysUntilExpiry = license.expiryDate!.difference(now).inDays; expect(daysUntilExpiry, lessThanOrEqualTo(30)); expect(daysUntilExpiry, greaterThan(0)); } } } }); test('라이선스 유형별 필터링', () async { // 구독형 라이선스 조회 final subscriptionLicenses = await licenseService.getLicenses( page: 1, perPage: 10, licenseType: 'subscription', ); expect(subscriptionLicenses, isNotNull); expect(subscriptionLicenses, isA>()); if (subscriptionLicenses.isNotEmpty) { expect(subscriptionLicenses.every((l) => l.licenseType == 'subscription'), isTrue); } // 영구 라이선스 조회 final perpetualLicenses = await licenseService.getLicenses( page: 1, perPage: 10, licenseType: 'perpetual', ); expect(perpetualLicenses, isNotNull); expect(perpetualLicenses, isA>()); if (perpetualLicenses.isNotEmpty) { expect(perpetualLicenses.every((l) => l.licenseType == 'perpetual'), isTrue); } }); test('회사별 라이선스 조회', () async { if (testCompanyId == null) { // 테스트할 회사가 없습니다 return; } final companyLicenses = await licenseService.getLicenses( page: 1, perPage: 10, companyId: testCompanyId, ); expect(companyLicenses, isNotNull); expect(companyLicenses, isA>()); if (companyLicenses.isNotEmpty) { expect(companyLicenses.every((l) => l.companyId == testCompanyId), isTrue); } }); test('활성 라이선스만 조회', () async { final activeLicenses = await licenseService.getLicenses( page: 1, perPage: 10, isActive: true, ); expect(activeLicenses, isNotNull); expect(activeLicenses, isA>()); if (activeLicenses.isNotEmpty) { expect(activeLicenses.every((l) => l.isActive == true), isTrue); } }); test('라이선스 상태별 개수 조회', () async { // getTotalLicenses 메소드가 현재 서비스에 구현되어 있지 않음 // 대신 라이선스 목록을 조회해서 개수 확인 final allLicenses = await licenseService.getLicenses(page: 1, perPage: 100); expect(allLicenses.length, greaterThanOrEqualTo(0)); final activeLicenses = await licenseService.getLicenses(page: 1, perPage: 100, isActive: true); expect(activeLicenses.length, greaterThanOrEqualTo(0)); final inactiveLicenses = await licenseService.getLicenses(page: 1, perPage: 100, isActive: false); expect(inactiveLicenses.length, greaterThanOrEqualTo(0)); // 활성 라이선스만 필터링이 제대로 작동하는지 확인 if (activeLicenses.isNotEmpty) { expect(activeLicenses.every((l) => l.isActive == true), isTrue); } }); test('라이선스 사용자 할당', () async { if (createdLicenseId == null) { // 사용자를 할당할 라이선스가 없습니다 return; } // assignLicenseToUsers 메소드가 현재 서비스에 구현되어 있지 않음 // 이 기능은 향후 구현될 예정 // 현재는 라이선스 조회만 테스트 final license = await licenseService.getLicenseById(createdLicenseId!); expect(license, isNotNull); // 라이선스 사용자 할당 기능은 향후 구현 예정 }); test('라이선스 삭제', () async { if (createdLicenseId == null) { // 삭제할 라이선스가 없습니다 return; } // 삭제 실행 await licenseService.deleteLicense(createdLicenseId!); // 삭제 확인 (404 에러 예상) try { await licenseService.getLicenseById(createdLicenseId!); fail('삭제된 라이선스가 여전히 조회됩니다'); } catch (e) { // 삭제 성공 - 404 에러가 발생해야 함 expect(e.toString(), contains('404')); } }); test('잘못된 ID로 라이선스 조회 시 에러', () async { try { await licenseService.getLicenseById(999999); fail('존재하지 않는 라이선스가 조회되었습니다'); } catch (e) { // 에러가 발생해야 정상 expect(e.toString(), isNotEmpty); } }); test('중복 라이선스 키로 생성 시 에러', () async { if (testCompanyId == null) { // 테스트할 회사가 없습니다 return; } // 기존 라이선스 키 가져오기 final licenses = await licenseService.getLicenses(page: 1, perPage: 1); if (licenses.isEmpty) { // 중복 테스트할 라이선스가 없습니다 return; } try { final duplicateLicense = License( licenseKey: licenses.first.licenseKey, // 중복 키 productName: 'Duplicate License', vendor: 'Test Vendor', licenseType: 'subscription', companyId: testCompanyId!, isActive: true, ); await licenseService.createLicense(duplicateLicense); fail('중복 라이선스 키로 라이선스가 생성되었습니다'); } catch (e) { // 에러가 발생해야 정상 expect(e.toString(), isNotEmpty); } }); test('만료된 라이선스 활성화 시도', () async { if (testCompanyId == null) { // 테스트할 회사가 없습니다 return; } try { // 과거 날짜로 만료된 라이선스 생성 final expiredLicense = License( licenseKey: 'EXPIRED-${DateTime.now().millisecondsSinceEpoch}', productName: 'Expired License', vendor: 'Test Vendor', licenseType: 'subscription', purchaseDate: DateTime.now().subtract(const Duration(days: 400)), expiryDate: DateTime.now().subtract(const Duration(days: 30)), // 30일 전 만료 companyId: testCompanyId!, isActive: true, // 만료되었지만 활성화 시도 ); await licenseService.createLicense(expiredLicense); // 서버가 만료된 라이선스 활성화를 허용할 수도 있음 // 만료된 라이선스가 생성되었습니다 (서버 정책에 따라 허용될 수 있음) } catch (e) { // 에러가 발생하면 정상 (서버 정책에 따라 다름) // 만료된 라이선스 생성 거부: $e } }); }); }