refactor: extract boxing logic into dedicated modules with tests
- boxing_models.dart: add BoxingMode, BoxingPhase, BoxingPageArguments - boxing_box_mutations.dart: box item add/replace/remove operations - boxing_calculations.dart: pure calculation helpers (quantities, validation) - boxing_status_presenter.dart: status bar text/dot determination - dialogs/cross_paichan_dialog.dart: cross-paichan confirmation dialog - widgets/boxing_notice_banners.dart: notice banner widgets - Add unit tests for mutations, calculations, and status presenter Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
88
test/pages/boxing/boxing_box_mutations_test.dart
Normal file
88
test/pages/boxing/boxing_box_mutations_test.dart
Normal file
@@ -0,0 +1,88 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pad_scanner/pages/boxing/boxing_box_mutations.dart';
|
||||
import 'package:pad_scanner/pages/boxing/boxing_models.dart';
|
||||
import 'package:pad_scanner/services/api_service.dart';
|
||||
|
||||
void main() {
|
||||
group('boxing box mutations', () {
|
||||
test('adds item to a new sorted box', () {
|
||||
final result = addExistingBoxItem(
|
||||
existingBoxes: [BoxDetailData(boxNo: 3, items: const [])],
|
||||
boxNo: 2,
|
||||
quantity: 5,
|
||||
boxItemId: 22,
|
||||
zongpaiNo: 'ZP022',
|
||||
workOrderNo: 'WO022',
|
||||
totalQuantity: 5,
|
||||
);
|
||||
|
||||
expect(result.boxes.map((box) => box.boxNo), [2, 3]);
|
||||
expect(result.maxBoxNo, 3);
|
||||
expect(result.boxes.first.items.single.zongpaiNo, 'ZP022');
|
||||
});
|
||||
|
||||
test('replaces single code item and removes empty source box', () {
|
||||
final result = replaceExistingBoxItem(
|
||||
existingBoxes: [
|
||||
BoxDetailData(
|
||||
boxNo: 1,
|
||||
items: [BoxItemData(boxItemId: 1, zongpaiNo: 'ZP001', quantity: 2)],
|
||||
),
|
||||
],
|
||||
editing: CurrentZongpaiBoxData(boxItemId: 1, boxNo: 1, quantity: 2),
|
||||
boxNo: 4,
|
||||
quantity: 3,
|
||||
zongpaiNo: 'ZP001',
|
||||
workOrderNo: 'WO001',
|
||||
totalQuantity: 5,
|
||||
);
|
||||
|
||||
expect(result.boxes.map((box) => box.boxNo), [4]);
|
||||
expect(result.boxes.single.items.single.quantity, 3);
|
||||
expect(result.maxBoxNo, 4);
|
||||
});
|
||||
|
||||
test('moves packed item to a different box', () {
|
||||
final result = replaceExistingPackedItem(
|
||||
existingBoxes: [
|
||||
BoxDetailData(
|
||||
boxNo: 2,
|
||||
items: [BoxItemData(boxItemId: 9, zongpaiNo: 'ZP009', quantity: 1)],
|
||||
),
|
||||
],
|
||||
item: const ManyToOnePackedItem(
|
||||
boxItemId: 9,
|
||||
zongpaiNo: 'ZP009',
|
||||
workOrderNo: 'WO009',
|
||||
boxNo: 2,
|
||||
quantity: 1,
|
||||
totalQuantity: 3,
|
||||
),
|
||||
boxNo: 5,
|
||||
quantity: 2,
|
||||
);
|
||||
|
||||
expect(result.boxes.map((box) => box.boxNo), [5]);
|
||||
expect(result.boxes.single.items.single.quantity, 2);
|
||||
});
|
||||
|
||||
test('removes item and drops empty box', () {
|
||||
final result = removeExistingBoxItem(
|
||||
existingBoxes: [
|
||||
BoxDetailData(
|
||||
boxNo: 1,
|
||||
items: [BoxItemData(boxItemId: 1, zongpaiNo: 'ZP001', quantity: 2)],
|
||||
),
|
||||
BoxDetailData(
|
||||
boxNo: 3,
|
||||
items: [BoxItemData(boxItemId: 2, zongpaiNo: 'ZP002', quantity: 1)],
|
||||
),
|
||||
],
|
||||
boxItemId: 1,
|
||||
);
|
||||
|
||||
expect(result.boxes.map((box) => box.boxNo), [3]);
|
||||
expect(result.maxBoxNo, 3);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user