import 'package:flutter_test/flutter_test.dart'; import 'package:superport/core/migrations/license_to_maintenance_migration.dart'; import 'package:superport/core/migrations/maintenance_data_validator.dart'; void main() { group('License to Maintenance Migration Tests', () { // 테스트용 License 데이터 final testLicenseData = [ { 'id': 1, 'equipment_id': 101, 'license_type': 'O', // Onsite 'period_months': 12, 'cost': 1000000, 'vendor_name': '삼성전자서비스', 'vendor_contact': '1588-3366', 'start_date': '2024-01-01T00:00:00Z', 'expiry_date': '2024-12-31T23:59:59Z', 'created_at': '2024-01-01T00:00:00Z', }, { 'id': 2, 'equipment_id': 102, 'license_type': 'R', // Remote 'period_months': 6, 'cost': 500000, 'vendor_name': 'LG전자서비스', 'vendor_contact': '1544-7777', 'start_date': '2024-06-01T00:00:00Z', 'expiry_date': '2024-11-30T23:59:59Z', 'created_at': '2024-06-01T00:00:00Z', }, { 'id': 3, 'equipment_id': 103, 'license_type': 'O', 'period_months': 24, 'cost': 2000000, 'vendor_name': '델코리아', 'vendor_contact': '1588-1588', 'start_date': '2023-01-01T00:00:00Z', 'expiry_date': '2024-12-31T23:59:59Z', // 곧 만료 'created_at': '2023-01-01T00:00:00Z', }, ]; // 테스트용 Equipment 데이터 final testEquipmentData = [ {'id': 101, 'equipment_number': 'EQ-001', 'name': '서버 #1'}, {'id': 102, 'equipment_number': 'EQ-002', 'name': '서버 #2'}, {'id': 103, 'equipment_number': 'EQ-003', 'name': '서버 #3'}, ]; // 테스트용 Equipment History 데이터 final testEquipmentHistoryData = [ { 'id': 201, 'equipments_id': 101, 'transaction_type': 'IN', 'created_at': '2024-01-01T00:00:00Z', }, { 'id': 202, 'equipments_id': 102, 'transaction_type': 'IN', 'created_at': '2024-06-01T00:00:00Z', }, { 'id': 203, 'equipments_id': 103, 'transaction_type': 'IN', 'created_at': '2023-01-01T00:00:00Z', }, ]; test('Should successfully migrate license data to maintenance', () async { // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: testLicenseData, equipmentData: testEquipmentData, equipmentHistoryData: testEquipmentHistoryData, ); // 검증 expect(result.success, true); expect(result.maintenanceData, isNotNull); expect(result.maintenanceData!.length, 3); expect(result.backup, isNotNull); expect(result.statistics, isNotNull); }); test('Should correctly map equipment history IDs', () async { // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: testLicenseData, equipmentData: testEquipmentData, equipmentHistoryData: testEquipmentHistoryData, ); // 각 Maintenance가 올바른 equipment_history_id를 가지는지 검증 final maintenance1 = result.maintenanceData! .firstWhere((m) => m['id'] == 1); expect(maintenance1['equipment_history_id'], 201); final maintenance2 = result.maintenanceData! .firstWhere((m) => m['id'] == 2); expect(maintenance2['equipment_history_id'], 202); final maintenance3 = result.maintenanceData! .firstWhere((m) => m['id'] == 3); expect(maintenance3['equipment_history_id'], 203); }); test('Should correctly convert license types to maintenance types', () async { // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: testLicenseData, equipmentData: testEquipmentData, equipmentHistoryData: testEquipmentHistoryData, ); // 유형 변환 검증 final maintenance1 = result.maintenanceData! .firstWhere((m) => m['id'] == 1); expect(maintenance1['maintenance_type'], 'O'); // Onsite final maintenance2 = result.maintenanceData! .firstWhere((m) => m['id'] == 2); expect(maintenance2['maintenance_type'], 'R'); // Remote }); test('Should calculate correct maintenance status', () async { // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: testLicenseData, equipmentData: testEquipmentData, equipmentHistoryData: testEquipmentHistoryData, ); // 상태 계산 검증 for (final maintenance in result.maintenanceData!) { final status = maintenance['status']; expect( ['scheduled', 'upcoming', 'overdue'].contains(status), true, reason: 'Status should be one of: scheduled, upcoming, overdue', ); } }); test('Should preserve cost and vendor information', () async { // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: testLicenseData, equipmentData: testEquipmentData, equipmentHistoryData: testEquipmentHistoryData, ); // 비용 및 업체 정보 보존 검증 final maintenance1 = result.maintenanceData! .firstWhere((m) => m['id'] == 1); expect(maintenance1['cost'], 1000000); expect(maintenance1['vendor_name'], '삼성전자서비스'); expect(maintenance1['vendor_contact'], '1588-3366'); }); test('Should generate correct analysis statistics', () async { // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: testLicenseData, equipmentData: testEquipmentData, equipmentHistoryData: testEquipmentHistoryData, ); // 통계 검증 expect(result.statistics, isNotNull); expect(result.statistics!.totalCount, 3); expect(result.statistics!.activeCount, greaterThanOrEqualTo(0)); expect(result.statistics!.expiredCount, greaterThanOrEqualTo(0)); expect(result.statistics!.upcomingCount, greaterThanOrEqualTo(0)); // 총합 검증 final total = result.statistics!.activeCount + result.statistics!.expiredCount + result.statistics!.upcomingCount; expect(total, result.statistics!.totalCount); }); test('Should create valid backup data', () async { // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: testLicenseData, equipmentData: testEquipmentData, equipmentHistoryData: testEquipmentHistoryData, ); // 백업 데이터 검증 expect(result.backup, isNotNull); expect(result.backup!['timestamp'], isNotNull); expect(result.backup!['version'], '1.0.0'); expect(result.backup!['data'], testLicenseData); expect(result.backup!['checksum'], isNotNull); }); test('Should handle missing equipment history gracefully', () async { // Equipment History가 없는 License 데이터 final incompleteData = [ { 'id': 999, 'equipment_id': 999, // 존재하지 않는 Equipment 'license_type': 'O', 'period_months': 12, 'cost': 1000000, 'start_date': '2024-01-01T00:00:00Z', 'expiry_date': '2024-12-31T23:59:59Z', }, ]; // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: incompleteData, equipmentData: testEquipmentData, equipmentHistoryData: testEquipmentHistoryData, ); // 검증 - 마이그레이션은 성공하지만 데이터는 변환되지 않음 expect(result.success, true); expect(result.maintenanceData!.length, 0); // 변환된 데이터 없음 }); test('Should validate migrated data correctly', () async { // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: testLicenseData, equipmentData: testEquipmentData, equipmentHistoryData: testEquipmentHistoryData, ); // 데이터 검증 final validationReport = await MaintenanceDataValidator.validate( maintenanceData: result.maintenanceData!, equipmentHistoryData: testEquipmentHistoryData, ); // 검증 결과 확인 expect(validationReport.isValid, true); expect(validationReport.dataIntegrity, true); expect(validationReport.businessRulesValid, true); }); test('Should support rollback functionality', () async { // 마이그레이션 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: testLicenseData, equipmentData: testEquipmentData, equipmentHistoryData: testEquipmentHistoryData, ); expect(result.success, true); expect(result.backup, isNotNull); // 롤백 테스트 final rollbackSuccess = await LicenseToMaintenanceMigration.rollback( result.backup!, ); expect(rollbackSuccess, true); }); }); group('Edge Cases and Error Handling', () { test('Should handle empty license data', () async { // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: [], equipmentData: [], equipmentHistoryData: [], ); // 검증 expect(result.success, true); expect(result.maintenanceData!.length, 0); expect(result.statistics!.totalCount, 0); }); test('Should handle null dates gracefully', () async { // null 날짜를 가진 License 데이터 final dataWithNullDates = [ { 'id': 1, 'equipment_id': 101, 'license_type': 'O', 'period_months': 12, 'cost': 1000000, 'start_date': null, 'expiry_date': null, }, ]; final equipmentHistory = [ { 'id': 201, 'equipments_id': 101, 'transaction_type': 'IN', }, ]; // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: dataWithNullDates, equipmentData: [], equipmentHistoryData: equipmentHistory, ); // 검증 expect(result.success, true); expect(result.maintenanceData!.length, 1); expect(result.maintenanceData![0]['status'], 'scheduled'); }); test('Should handle duplicate license IDs', () async { // 중복 ID를 가진 License 데이터 final duplicateData = [ { 'id': 1, 'equipment_id': 101, 'license_type': 'O', 'period_months': 12, }, { 'id': 1, // 중복 ID 'equipment_id': 102, 'license_type': 'R', 'period_months': 6, }, ]; final equipmentHistory = [ {'id': 201, 'equipments_id': 101}, {'id': 202, 'equipments_id': 102}, ]; // 실행 final result = await LicenseToMaintenanceMigration.migrate( licenseData: duplicateData, equipmentData: [], equipmentHistoryData: equipmentHistory, ); // 검증 - 중복 ID도 처리되어야 함 expect(result.success, true); expect(result.maintenanceData!.length, 2); }); }); }