import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:slide_to_submit_button/slide_to_submit_button.dart'; import 'package:miler/views/Dashboard/home/duty_sheet.dart'; /// The duty sheet used to say one thing — "You will stop receiving bookings" — /// and leave out the two that actually catch a rider out: tracking stops, and /// the app will refuse to take him off duty while he is still holding work. It /// also carried a wifi glyph, which says "network problem" on a screen about /// whether he is working. void main() { Future pump( WidgetTester tester, { required bool goingOnline, Future Function()? onConfirm, }) async { tester.view.physicalSize = const Size(1170, 2532); tester.view.devicePixelRatio = 3.0; addTearDown(tester.view.resetPhysicalSize); addTearDown(tester.view.resetDevicePixelRatio); await tester.pumpWidget( ScreenUtilInit( designSize: const Size(390, 844), builder: (_, _) => MaterialApp( home: Scaffold( body: Align( alignment: Alignment.bottomCenter, child: DutySheet( goingOnline: goingOnline, onConfirm: onConfirm ?? () async => true, ), ), ), ), ), ); // The hint arrow loops forever, so there is nothing to settle into. await tester.pump(const Duration(milliseconds: 300)); } testWidgets('going on duty names the state it is heading for', ( tester, ) async { await pump(tester, goingOnline: true); expect(find.text('Go on duty?'), findsOneWidget); expect(find.text('Go on duty'), findsOneWidget); expect(find.text('Not yet'), findsOneWidget); // Duty is not connectivity. A rider reading a wifi symbol on a screen that // stops his work is being told the app has a network problem. expect(find.byIcon(Icons.wifi), findsNothing); expect(find.byIcon(Icons.wifi_off), findsNothing); }); // ── The consequence survives; the three rows that carried it do not ── // // The sheet listed what stops as three icon-and-text rows. The facts are the // contract, not the rows — and the one that matters most is the refusal, // which the original sheet sprang on the rider only *after* he had completed // a slide. It is in the sentence now, before he decides. testWidgets('going off duty states what stops, including the refusal', ( tester, ) async { await pump(tester, goingOnline: false); expect(find.text('Go off duty?'), findsOneWidget); final body = tester .widgetList(find.byType(Text)) .map((t) => t.data ?? '') .join(' '); expect(body, contains('stops assigning you trips')); expect(body, contains('live tracking pauses')); expect( body, contains('has to be finished first'), reason: 'the refusal must be stated before the gesture, not after it', ); }); // ── Slides are reserved for money ── // // The confirmation was a slide-to-submit borrowed from the payment flows. // Ending a shift is not a transaction, and asking for a drag made the // commonest action of the rider's day the most laborious one. testWidgets('confirming runs the toggle', (tester) async { var calls = 0; await pump( tester, goingOnline: true, onConfirm: () async { calls++; return true; }, ); await tester.tap(find.widgetWithText(ElevatedButton, 'Go on duty')); await tester.pump(); await tester.pump(); expect(calls, 1); }); testWidgets('dismissing does not', (tester) async { var calls = 0; await pump( tester, goingOnline: false, onConfirm: () async { calls++; return true; }, ); await tester.tap(find.text('Stay on duty')); await tester.pump(); await tester.pump(); expect(calls, 0, reason: 'the way out must not perform the action'); }); }