feat:餐段设置

This commit is contained in:
dzc committed 2026-09-07 12:53:05 +08:00
1 parent 67950343a7
commit 07a3141934
14 files changed
+285 -18

No files matched your search

@@ -236,6 +236,81 @@ void main() {
expect(find.textContaining('当前选择的餐段可能有问题'), findsNothing);
expect(controller.value, {'2'});
});
testWidgets('禁止主动修改餐段时初始化静默切换为配置餐段且不弹框', (tester) async {
final controller = FRadioSelectGroupController<String>(value: '1');
addTearDown(controller.dispose);
await tester.pumpWidget(
_testApp(
Builder(
builder: (context) => appRadioHourTypeDialog(
context,
controller,
checkConfiguredTime: true,
allowManualChange: false,
ready: Future.value(),
currentHourTypeLoader: () async => ProductHourType.NOON,
),
),
),
);
await tester.pumpAndSettle();
expect(find.textContaining('当前选择的餐段可能有问题'), findsNothing);
expect(controller.value, {'2'});
});
testWidgets('禁止主动修改餐段时选择器禁用且无法打开餐段菜单', (tester) async {
final controller = FRadioSelectGroupController<String>(value: '2');
addTearDown(controller.dispose);
await tester.pumpWidget(
_testApp(
Builder(
builder: (context) => appRadioHourTypeDialog(
context,
controller,
checkConfiguredTime: true,
allowManualChange: false,
ready: Future.value(),
currentHourTypeLoader: () async => ProductHourType.NOON,
),
),
),
);
await tester.pumpAndSettle();
await tester.tap(find.byType(FSelectMenuTile<String>));
await tester.pumpAndSettle();
expect(find.byKey(const ValueKey('meal-slot-option-1')), findsNothing);
expect(controller.value, {'2'});
});
testWidgets('禁止主动修改餐段时当前时间未命中餐段配置则保持原选择', (tester) async {
final controller = FRadioSelectGroupController<String>(value: '1');
addTearDown(controller.dispose);
await tester.pumpWidget(
_testApp(
Builder(
builder: (context) => appRadioHourTypeDialog(
context,
controller,
checkConfiguredTime: true,
allowManualChange: false,
ready: Future.value(),
currentHourTypeLoader: () async => null,
),
),
),
);
await tester.pumpAndSettle();
expect(find.textContaining('当前选择的餐段可能有问题'), findsNothing);
expect(controller.value, {'1'});
});
}
Widget _testApp(Widget child) {
@@ -153,6 +153,10 @@ void main() {
await tester.pumpAndSettle();
expect(find.text('库存 2'), findsOneWidget);
// 套餐组成默认收起,点击套餐主行展开后才能看到组成明细。
expect(find.text('时令青菜'), findsNothing);
await tester.tap(find.byKey(const ValueKey('checkout-combo-canteen-1')));
await tester.pumpAndSettle();
expect(find.text('时令青菜'), findsOneWidget);
expect(find.textContaining('可在支付前调整数量'), findsOneWidget);
expect(find.textContaining('确认支付').evaluate().single.widget, isA<Text>());
@@ -348,7 +352,8 @@ void main() {
tester.getTopLeft(cartPane).dy, tester.getTopLeft(paymentPane).dy);
expect(find.textContaining('x9999'), findsOneWidget);
expect(find.text('套餐'), findsOneWidget);
expect(find.text('清炒时蔬'), findsOneWidget);
// 套餐组成默认收起,首次进入不渲染组成行。
expect(find.text('清炒时蔬'), findsNothing);
expect(
find.byKey(
const ValueKey('checkout-product-image-long-name-product'),
@@ -357,7 +362,7 @@ void main() {
);
expect(
find.byKey(const ValueKey('checkout-combo-image-combo-child-1')),
findsOneWidget,
findsNothing,
);
expect(find.text('选择支付方式'), findsOneWidget);
final methodFinders = <Finder>[
@@ -385,10 +390,10 @@ void main() {
await tester.tap(find.text('营养套餐'));
await tester.pumpAndSettle();
expect(find.text('清炒时蔬').hitTestable(), findsNothing);
expect(find.text('清炒时蔬').hitTestable(), findsOneWidget);
await tester.tap(find.text('营养套餐'));
await tester.pumpAndSettle();
expect(find.text('清炒时蔬').hitTestable(), findsOneWidget);
expect(find.text('清炒时蔬').hitTestable(), findsNothing);
final wallet = ServiceWallet(
id: 'wallet-1',
@@ -26,6 +26,7 @@ void main() {
autoRecognitionEnabled: false,
continuousRecognitionEnabled: false,
quickVerificationEnabled: false,
allowManualMealPeriodChange: true,
onSelect: (method) => selectedMethod = method,
onStart: () => startCalls++,
),
@@ -47,6 +48,7 @@ void main() {
autoRecognitionEnabled: true,
continuousRecognitionEnabled: true,
quickVerificationEnabled: false,
allowManualMealPeriodChange: true,
onSelect: (method) => selectedMethod = method,
onStart: () => startCalls++,
),
@@ -78,6 +80,7 @@ void main() {
autoRecognitionEnabled: true,
continuousRecognitionEnabled: true,
quickVerificationEnabled: false,
allowManualMealPeriodChange: true,
onSelect: (_) {},
onStart: () {},
),
@@ -100,6 +103,7 @@ void main() {
autoRecognitionEnabled: true,
continuousRecognitionEnabled: false,
quickVerificationEnabled: true,
allowManualMealPeriodChange: true,
onSelect: (_) {},
onStart: () {},
),
@@ -139,6 +143,7 @@ void main() {
autoRecognitionEnabled: false,
continuousRecognitionEnabled: true,
quickVerificationEnabled: true,
allowManualMealPeriodChange: true,
onSelect: (_) {},
onStart: () {},
),
@@ -180,6 +185,7 @@ void main() {
autoRecognitionEnabled: false,
continuousRecognitionEnabled: true,
quickVerificationEnabled: true,
allowManualMealPeriodChange: true,
onSelect: (_) {},
onStart: () {},
),
@@ -205,6 +211,7 @@ void main() {
autoRecognitionEnabled: false,
continuousRecognitionEnabled: true,
quickVerificationEnabled: true,
allowManualMealPeriodChange: true,
onSelect: (_) {},
onStart: () {},
),
@@ -226,6 +233,42 @@ void main() {
);
expect(tester.takeException(), isNull);
});
testWidgets('禁止主动修改餐段时选择器禁用且无法打开餐段菜单', (tester) async {
await tester.binding.setSurfaceSize(const Size(1920, 1080));
addTearDown(() => tester.binding.setSurfaceSize(null));
final mealSlotController = FRadioSelectGroupController<String>(value: '1');
addTearDown(mealSlotController.dispose);
await tester.pumpWidget(
_testApp(
QueryMethodPanel(
methods: ReservationRecognitionMethod.values,
selected: ReservationRecognitionMethod.card,
status: ReservationMenuQueryStatus.idle,
mealSlotController: mealSlotController,
autoRecognitionEnabled: false,
continuousRecognitionEnabled: true,
quickVerificationEnabled: true,
allowManualMealPeriodChange: false,
onSelect: (_) {},
onStart: () {},
),
),
);
final trigger = find.byKey(
const ValueKey('reservation-meal-slot-trigger'),
);
expect(find.text('早餐'), findsOneWidget);
expect(tester.widget<FSelectMenuTile<String>>(trigger).enabled, isFalse);
await tester.tap(trigger);
await tester.pumpAndSettle();
expect(find.byKey(const ValueKey('meal-slot-option-2')), findsNothing);
expect(mealSlotController.value, {'1'});
expect(tester.takeException(), isNull);
});
}
/// 构建与终端设计基准一致的主题和尺寸环境,只验证本组件的可见状态与点击链路。