- 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>
124 lines
3.3 KiB
Dart
124 lines
3.3 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:pad_scanner/pages/boxing/boxing_calculations.dart';
|
|
import 'package:pad_scanner/pages/boxing/boxing_models.dart';
|
|
import 'package:pad_scanner/services/api_service.dart';
|
|
|
|
void main() {
|
|
group('boxing calculations', () {
|
|
final currentBoxes = [
|
|
CurrentZongpaiBoxData(boxItemId: 1, boxNo: 1, quantity: 4),
|
|
CurrentZongpaiBoxData(boxItemId: 2, boxNo: 2, quantity: 3),
|
|
];
|
|
|
|
test('calculates packed and remaining quantity', () {
|
|
expect(packedQuantity(currentBoxes), 7);
|
|
expect(
|
|
remainingQuantity(totalQuantity: 10, currentBoxes: currentBoxes),
|
|
3,
|
|
);
|
|
});
|
|
|
|
test('detects quantity too high only when remaining is positive', () {
|
|
expect(quantityTooHigh(remainingQuantity: 3, quantityText: '4'), isTrue);
|
|
expect(quantityTooHigh(remainingQuantity: 3, quantityText: '3'), isFalse);
|
|
expect(quantityTooHigh(remainingQuantity: 0, quantityText: '1'), isFalse);
|
|
});
|
|
|
|
test('validates submit conditions', () {
|
|
expect(
|
|
canSubmitBoxing(
|
|
isSubmitting: false,
|
|
phase: BoxingPhase.scanned,
|
|
zongpaiNo: 'ZP001',
|
|
boxNoText: '1',
|
|
quantityText: '2',
|
|
remainingQuantity: 3,
|
|
quantityTooHigh: false,
|
|
isDuplicateBoxNo: false,
|
|
),
|
|
isTrue,
|
|
);
|
|
|
|
expect(
|
|
canSubmitBoxing(
|
|
isSubmitting: true,
|
|
phase: BoxingPhase.scanned,
|
|
zongpaiNo: 'ZP001',
|
|
boxNoText: '1',
|
|
quantityText: '2',
|
|
remainingQuantity: 3,
|
|
quantityTooHigh: false,
|
|
isDuplicateBoxNo: false,
|
|
),
|
|
isFalse,
|
|
);
|
|
});
|
|
|
|
test('detects duplicate box number in single code mode', () {
|
|
expect(
|
|
singleCodeBoxNoIsDuplicate(
|
|
boxNoText: '1',
|
|
currentBoxes: currentBoxes,
|
|
editingBoxItemId: null,
|
|
),
|
|
isTrue,
|
|
);
|
|
expect(
|
|
singleCodeBoxNoIsDuplicate(
|
|
boxNoText: '1',
|
|
currentBoxes: currentBoxes,
|
|
editingBoxItemId: 1,
|
|
),
|
|
isFalse,
|
|
);
|
|
});
|
|
|
|
test('merges visible many-to-one items by box item id', () {
|
|
final existingBoxes = [
|
|
BoxDetailData(
|
|
boxNo: 8,
|
|
items: [
|
|
BoxItemData(
|
|
boxItemId: 11,
|
|
zongpaiNo: 'ZP011',
|
|
workOrderNo: 'WO011',
|
|
quantity: 2,
|
|
totalQuantity: 6,
|
|
),
|
|
],
|
|
),
|
|
];
|
|
final packedItems = [
|
|
const ManyToOnePackedItem(
|
|
boxItemId: 11,
|
|
zongpaiNo: 'ZP011',
|
|
paichanNo: 'PC001',
|
|
workOrderNo: 'WO011',
|
|
boxNo: 8,
|
|
quantity: 3,
|
|
totalQuantity: 6,
|
|
),
|
|
const ManyToOnePackedItem(
|
|
boxItemId: 12,
|
|
zongpaiNo: 'ZP012',
|
|
paichanNo: 'PC001',
|
|
workOrderNo: 'WO012',
|
|
boxNo: 8,
|
|
quantity: 1,
|
|
totalQuantity: 4,
|
|
),
|
|
];
|
|
|
|
final visible = visibleManyToOnePackedItems(
|
|
boxNo: 8,
|
|
existingBoxes: existingBoxes,
|
|
packedItems: packedItems,
|
|
paichanNo: 'PC001',
|
|
);
|
|
|
|
expect(visible.map((item) => item.boxItemId), [11, 12]);
|
|
expect(visible.first.quantity, 3);
|
|
});
|
|
});
|
|
}
|