- ShadTable: ensure full-width via LayoutBuilder+ConstrainedBox minWidth - BaseListScreen: default data area padding = 0 for table edge-to-edge - Vendor/Model/User/Company/Inventory/Zipcode: set columnSpanExtent per column and add final filler column to absorb remaining width; pin date/status/actions widths; ensure date text is single-line - Equipment: unify card/border style; define fixed column widths + filler; increase checkbox column to 56px to avoid overflow - Rent list: migrate to ShadTable.list with fixed widths + filler column - Rent form dialog: prevent infinite width by bounding ShadProgress with SizedBox and remove Expanded from option rows; add safe selectedOptionBuilder - Admin list: fix const with non-const argument in table column extents - Services/Controller: remove hardcoded perPage=10; use BaseListController perPage; trust server meta (total/totalPages) in equipment pagination - widgets/shad_table: ConstrainedBox(minWidth=viewport) so table stretches Run: flutter analyze → 0 errors (warnings remain).
261 lines
9.1 KiB
Dart
261 lines
9.1 KiB
Dart
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'; // License 시스템 제거
|
|
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'; // License 시스템 제거
|
|
import 'package:superport/models/address_model.dart';
|
|
import 'package:superport/models/equipment_unified_model.dart';
|
|
import 'package:superport/utils/phone_utils.dart';
|
|
|
|
const bool RUN_EXTERNAL_TESTS = bool.fromEnvironment('RUN_EXTERNAL_TESTS');
|
|
void main() {
|
|
if (!RUN_EXTERNAL_TESTS) {
|
|
test('External tests disabled', () {}, skip: 'Enable with --dart-define=RUN_EXTERNAL_TESTS=true');
|
|
return;
|
|
}
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
late WarehouseService warehouseService;
|
|
late CompanyService companyService;
|
|
// late LicenseService licenseService; // License 시스템 제거
|
|
late EquipmentService equipmentService;
|
|
|
|
setUpAll(() async {
|
|
// DI 초기화
|
|
if (!GetIt.instance.isRegistered<WarehouseService>()) {
|
|
await di.init();
|
|
}
|
|
|
|
warehouseService = GetIt.instance<WarehouseService>();
|
|
companyService = GetIt.instance<CompanyService>();
|
|
// licenseService = GetIt.instance<LicenseService>(); // License 시스템 제거
|
|
equipmentService = GetIt.instance<EquipmentService>();
|
|
});
|
|
|
|
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 사용
|
|
}
|
|
|
|
// Branch 대신 Company로 자회사 생성
|
|
final childCompany = Company(
|
|
name: 'Test Child Company ${DateTime.now().millisecondsSinceEpoch}',
|
|
address: const Address(
|
|
region: '경기도',
|
|
detailAddress: '성남시 분당구',
|
|
),
|
|
contactName: '김철수',
|
|
contactPhone: PhoneUtils.getFullPhoneNumber('031', '12345678'),
|
|
companyTypes: [CompanyType.customer],
|
|
parentCompanyId: createdCompanyId, // 상위 회사 ID 설정
|
|
);
|
|
|
|
final created = await companyService.createBranch(createdCompanyId!, childCompany);
|
|
|
|
expect(created.id, isNotNull);
|
|
expect(created.name, equals(childCompany.name));
|
|
expect(created.parentCompanyId, equals(createdCompanyId));
|
|
});
|
|
|
|
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,
|
|
);
|
|
});
|
|
});
|
|
|
|
// License 시스템이 Maintenance 시스템으로 대체되었습니다.
|
|
// 이전 License 관련 테스트는 제거되었습니다.
|
|
// Maintenance 테스트는 별도 파일에서 관리합니다.
|
|
|
|
group('장비 관리 CRUD 테스트', () {
|
|
int? createdEquipmentId;
|
|
|
|
test('장비 생성', () async {
|
|
final equipment = Equipment(
|
|
equipmentNumber: 'Test Equipment ${DateTime.now().millisecondsSinceEpoch}',
|
|
modelsId: 1, // Vendor→Model 관계로 변경됨
|
|
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)); // manufacturer 필드 제거됨
|
|
expect(created.equipmentNumber, equals(equipment.equipmentNumber)); // name → equipmentNumber
|
|
});
|
|
|
|
test('장비 수정 - 데이터 로드 확인', () async {
|
|
if (createdEquipmentId == null) {
|
|
return; // skip 대신 return 사용
|
|
}
|
|
|
|
// 먼저 장비 정보를 조회
|
|
final loaded = await equipmentService.getEquipmentDetail(createdEquipmentId!);
|
|
|
|
expect(loaded.id, equals(createdEquipmentId));
|
|
// expect(loaded.manufacturer, isNotEmpty); // manufacturer 필드 제거됨
|
|
expect(loaded.equipmentNumber, isNotEmpty); // name → equipmentNumber
|
|
|
|
// 수정
|
|
final equipment = Equipment(
|
|
id: createdEquipmentId,
|
|
equipmentNumber: 'Updated Equipment',
|
|
modelsId: loaded.modelsId, // Vendor→Model 관계 유지
|
|
quantity: 10,
|
|
);
|
|
|
|
final updated = await equipmentService.updateEquipment(createdEquipmentId!, equipment);
|
|
|
|
// expect(updated.manufacturer, equals('Updated Manufacturer')); // 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,
|
|
);
|
|
});
|
|
});
|
|
}
|