import 'package:flutter_test/flutter_test.dart'; import 'package:get_it/get_it.dart'; import 'package:superport/injection_container.dart' as di; import 'package:superport/services/warehouse_service.dart'; import 'package:superport/services/company_service.dart'; import 'package:superport/services/license_service.dart'; import 'package:superport/services/equipment_service.dart'; import 'package:superport/models/warehouse_location_model.dart'; import 'package:superport/models/company_model.dart'; import 'package:superport/models/license_model.dart'; import 'package:superport/models/address_model.dart'; import 'package:superport/models/equipment_unified_model.dart'; import 'package:superport/utils/phone_utils.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); late WarehouseService warehouseService; late CompanyService companyService; late LicenseService licenseService; late EquipmentService equipmentService; setUpAll(() async { // DI 초기화 if (!GetIt.instance.isRegistered()) { await di.init(); } warehouseService = GetIt.instance(); companyService = GetIt.instance(); licenseService = GetIt.instance(); equipmentService = GetIt.instance(); }); group('입고지 관리 CRUD 테스트', () { int? createdWarehouseId; test('입고지 생성 - 주소와 비고 포함', () async { final warehouse = WarehouseLocation( id: 0, name: 'Test Warehouse ${DateTime.now().millisecondsSinceEpoch}', address: '서울특별시 강남구 테헤란로 123 (06234)', remark: '테스트 비고 내용', ); final created = await warehouseService.createWarehouseLocation(warehouse); createdWarehouseId = created.id; expect(created.id, isNotNull); expect(created.id, greaterThan(0)); expect(created.name, equals(warehouse.name)); expect(created.remark, equals(warehouse.remark)); }); test('입고지 수정 - 주소와 비고 업데이트', () async { if (createdWarehouseId == null) { return; // skip 대신 return 사용 } final warehouse = WarehouseLocation( id: createdWarehouseId!, name: 'Updated Warehouse ${DateTime.now().millisecondsSinceEpoch}', address: '서울특별시 서초구 서초대로 456', managerName: '수정된 관리자', managerPhone: '010-1111-2222', capacity: 1500, remark: '수정된 비고 내용', ); final updated = await warehouseService.updateWarehouseLocation(warehouse); expect(updated.name, equals(warehouse.name)); // API가 remark를 반환하지 않을 수 있으므로 확인은 선택적 // expect(updated.remark, equals(warehouse.remark)); }); test('입고지 조회', () async { if (createdWarehouseId == null) { return; // skip 대신 return 사용 } final warehouse = await warehouseService.getWarehouseLocationById(createdWarehouseId!); expect(warehouse.id, equals(createdWarehouseId)); expect(warehouse.name, isNotEmpty); }); test('입고지 삭제', () async { if (createdWarehouseId == null) { return; // skip 대신 return 사용 } await expectLater( warehouseService.deleteWarehouseLocation(createdWarehouseId!), completes, ); }); }); group('회사 관리 CRUD 테스트', () { int? createdCompanyId; test('회사 생성 - 전화번호 포맷팅 테스트', () async { // 7자리 전화번호 테스트 final phone7 = PhoneUtils.formatPhoneNumberByPrefix('02', '1234567'); expect(phone7, equals('123-4567')); // 8자리 전화번호 테스트 final phone8 = PhoneUtils.formatPhoneNumberByPrefix('031', '12345678'); expect(phone8, equals('1234-5678')); // getFullPhoneNumber 테스트 final fullPhone = PhoneUtils.getFullPhoneNumber('02', '1234567'); expect(fullPhone, equals('123-4567')); final company = Company( name: 'Test Company ${DateTime.now().millisecondsSinceEpoch}', address: const Address( region: '서울특별시', detailAddress: '강남구 테헤란로 123', ), contactName: '홍길동', contactPosition: '과장', contactPhone: PhoneUtils.getFullPhoneNumber('02', '1234567'), contactEmail: 'test@test.com', companyTypes: [CompanyType.customer], ); final created = await companyService.createCompany(company); createdCompanyId = created.id; expect(created.id, isNotNull); expect(created.id, greaterThan(0)); expect(created.name, equals(company.name)); }); test('회사 지점 추가', () async { if (createdCompanyId == null) { return; // skip 대신 return 사용 } final branch = Branch( companyId: createdCompanyId!, name: 'Test Branch ${DateTime.now().millisecondsSinceEpoch}', address: const Address( region: '경기도', detailAddress: '성남시 분당구', ), contactName: '김철수', contactPhone: PhoneUtils.getFullPhoneNumber('031', '12345678'), ); final created = await companyService.createBranch(createdCompanyId!, branch); expect(created.id, isNotNull); expect(created.name, equals(branch.name)); }); test('회사 수정', () async { if (createdCompanyId == null) { return; // skip 대신 return 사용 } final company = Company( id: createdCompanyId, name: 'Updated Company ${DateTime.now().millisecondsSinceEpoch}', address: const Address( region: '서울특별시', detailAddress: '서초구 서초대로 456', ), contactPhone: PhoneUtils.getFullPhoneNumber('02', '87654321'), companyTypes: [CompanyType.partner], ); final updated = await companyService.updateCompany(createdCompanyId!, company); expect(updated.name, equals(company.name)); }); test('회사 삭제', () async { if (createdCompanyId == null) { return; // skip 대신 return 사용 } await expectLater( companyService.deleteCompany(createdCompanyId!), completes, ); }); }); group('유지보수 라이선스 CRUD 테스트', () { int? createdLicenseId; int? testCompanyId; setUpAll(() async { // 테스트용 회사 생성 final company = Company( name: 'License Test Company ${DateTime.now().millisecondsSinceEpoch}', address: const Address(region: '서울'), companyTypes: [CompanyType.customer], ); final created = await companyService.createCompany(company); testCompanyId = created.id; }); tearDownAll(() async { // 테스트용 회사 삭제 if (testCompanyId != null) { await companyService.deleteCompany(testCompanyId!); } }); test('라이선스 생성', () async { final license = License( licenseKey: 'TEST-KEY-${DateTime.now().millisecondsSinceEpoch}', productName: 'Test Product', vendor: 'Test Vendor', companyId: testCompanyId, purchaseDate: DateTime.now().subtract(const Duration(days: 30)), expiryDate: DateTime.now().add(const Duration(days: 335)), isActive: true, ); final created = await licenseService.createLicense(license); createdLicenseId = created.id; expect(created.id, isNotNull); expect(created.licenseKey, equals(license.licenseKey)); expect(created.productName, equals(license.productName)); }); test('라이선스 수정 - 제한된 필드만 수정 가능', () async { if (createdLicenseId == null) { return; // skip 대신 return 사용 } // UpdateLicenseRequest DTO에 포함된 필드만 수정 가능 final license = License( id: createdLicenseId, licenseKey: 'SHOULD-NOT-CHANGE', // 수정 불가 productName: 'Updated Product', // 수정 가능 vendor: 'Updated Vendor', // 수정 가능 expiryDate: DateTime.now().add(const Duration(days: 365)), // 수정 가능 isActive: false, // 수정 가능 ); final updated = await licenseService.updateLicense(license); expect(updated.productName, equals('Updated Product')); expect(updated.vendor, equals('Updated Vendor')); expect(updated.isActive, equals(false)); // license_key는 수정되지 않아야 함 expect(updated.licenseKey, isNot(equals('SHOULD-NOT-CHANGE'))); }); test('라이선스 조회', () async { if (createdLicenseId == null) { return; // skip 대신 return 사용 } final license = await licenseService.getLicenseById(createdLicenseId!); expect(license.id, equals(createdLicenseId)); expect(license.licenseKey, isNotEmpty); }); test('라이선스 삭제', () async { if (createdLicenseId == null) { return; // skip 대신 return 사용 } await expectLater( licenseService.deleteLicense(createdLicenseId!), completes, ); }); }); group('장비 관리 CRUD 테스트', () { int? createdEquipmentId; test('장비 생성', () async { final equipment = Equipment( manufacturer: 'Test Manufacturer', name: 'Test Equipment ${DateTime.now().millisecondsSinceEpoch}', category: 'Test Category', subCategory: 'Test SubCategory', subSubCategory: 'Test SubSubCategory', // 필수 필드 추가 quantity: 5, serialNumber: 'SN-${DateTime.now().millisecondsSinceEpoch}', ); final created = await equipmentService.createEquipment(equipment); createdEquipmentId = created.id; expect(created.id, isNotNull); expect(created.manufacturer, equals(equipment.manufacturer)); expect(created.name, equals(equipment.name)); }); test('장비 수정 - 데이터 로드 확인', () async { if (createdEquipmentId == null) { return; // skip 대신 return 사용 } // 먼저 장비 정보를 조회 final loaded = await equipmentService.getEquipmentDetail(createdEquipmentId!); expect(loaded.id, equals(createdEquipmentId)); expect(loaded.manufacturer, isNotEmpty); expect(loaded.name, isNotEmpty); // 수정 final equipment = Equipment( id: createdEquipmentId, manufacturer: 'Updated Manufacturer', name: 'Updated Equipment', category: loaded.category, subCategory: loaded.subCategory, subSubCategory: loaded.subSubCategory, // 필수 필드 추가 quantity: 10, ); final updated = await equipmentService.updateEquipment(createdEquipmentId!, equipment); expect(updated.manufacturer, equals('Updated Manufacturer')); expect(updated.name, equals('Updated Equipment')); expect(updated.quantity, equals(10)); }); test('장비 삭제', () async { if (createdEquipmentId == null) { return; // skip 대신 return 사용 } await expectLater( equipmentService.deleteEquipment(createdEquipmentId!), completes, ); }); }); }