import 'package:flutter/material.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:miler/views/Dashboard/pickups/stop_verify.dart'; /// The verification page is the only place the app records what actually /// happened at a door, so the thing worth testing is the gate: which legs it /// runs for each stop kind, and that it refuses to advance until the proof for /// the current leg exists. void main() { /// Pumps the page on a phone-shaped surface. The default 800×600 test window /// makes ScreenUtil scale width up and height down at once, which is not a /// shape any phone has — layouts that are fine on device fail there for the /// wrong reason. Future pumpStop(WidgetTester tester, Map stop) async { tester.view.physicalSize = const Size(1170, 2532); // iPhone 13, @3x 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: StopVerificationPage(pickup: stop)), ), ); await tester.pumpAndSettle(); } Map stopOf({ required String type, int deliveryQty = 0, int pickupQty = 0, double cash = 0, }) => { 'orderid': 'T-1', 'type': type, 'pickupcustomer': 'Priya Sharma', 'pickupaddress': '45, Lake View Apartments, Coimbatore', if (deliveryQty > 0) 'deliveryqty': '$deliveryQty', if (pickupQty > 0) 'pickupqty': '$pickupQty', 'Quantity': '${pickupQty > 0 ? pickupQty : deliveryQty}', if (cash > 0) 'collectionamt': '$cash', }; testWidgets('a pickup stop runs one collect leg', (tester) async { await pumpStop(tester, stopOf(type: 'pickup', pickupQty: 3)); expect(find.text('Verify pickup'), findsOneWidget); expect(find.text('Collect'), findsOneWidget); // stepper expect(find.text('Confirm'), findsOneWidget); expect(find.text('Hand over'), findsNothing); // The collect leg's own controls. expect(find.text('Parcels collected'), findsOneWidget); expect(find.text('of 3 booked'), findsOneWidget); expect(find.text('Pickup code'), findsOneWidget); }); testWidgets( 'a delivery stop runs one hand-over leg with a parcel checklist', (tester) async { await pumpStop(tester, stopOf(type: 'delivery', deliveryQty: 2)); expect(find.text('Verify delivery'), findsOneWidget); expect(find.text('Hand over'), findsOneWidget); expect(find.text('Collect'), findsNothing); // One tile per parcel — this is what stops a 2-parcel drop closing on 1. expect(find.text('Parcel 1 of 2'), findsOneWidget); expect(find.text('Parcel 2 of 2'), findsOneWidget); expect(find.text('Who received it?'), findsOneWidget); expect(find.text('Delivery OTP'), findsOneWidget); // Nothing about weight or condition on a delivery. expect(find.text('Condition'), findsNothing); }, ); testWidgets('a combined stop runs hand over, then collect', (tester) async { await pumpStop( tester, stopOf(type: 'combined', deliveryQty: 1, pickupQty: 2), ); expect(find.text('Verify stop'), findsOneWidget); // Three steps, delivery first — the rider walks up holding the outbound // parcel, so he hands it over before taking anything back. expect(find.text('Hand over'), findsOneWidget); expect(find.text('Collect'), findsOneWidget); expect(find.text('Confirm'), findsOneWidget); // Both loads are on the summary. expect(find.text('Hand over 1'), findsOneWidget); expect(find.text('Collect 2'), findsOneWidget); // Step 1 is the delivery leg. expect(find.text('Hand over the parcels'), findsOneWidget); expect(find.text('Parcels collected'), findsNothing); }); testWidgets('the delivery leg will not advance without its proof', ( tester, ) async { await pumpStop(tester, stopOf(type: 'delivery', deliveryQty: 1)); // Blocked from the start, and the bar says what is missing next. expect(find.text('1 parcel still to hand over'), findsOneWidget); await tester.tap(find.text('Parcel 1 of 1')); await tester.pumpAndSettle(); expect(find.text('Enter the OTP from the customer'), findsOneWidget); await tester.enterText(find.byType(TextField).first, '482156'); await tester.pumpAndSettle(); expect(find.text('Take a proof photo'), findsOneWidget); // Still on step 1 — the camera is the last gate and cannot be faked here. expect(find.text('Hand over the parcels'), findsOneWidget); }); testWidgets('handing over to a third party demands their name', ( tester, ) async { await pumpStop(tester, stopOf(type: 'delivery', deliveryQty: 1)); await tester.tap(find.text('Parcel 1 of 1')); await tester.pumpAndSettle(); expect(find.text("Person's name"), findsNothing); await tester.tap(find.text('Security')); await tester.pumpAndSettle(); expect(find.text("Person's name"), findsOneWidget); expect( find.text('Enter the name of the person who took it'), findsOneWidget, ); }); testWidgets('a short count forces a written reason', (tester) async { await pumpStop(tester, stopOf(type: 'pickup', pickupQty: 3)); // Pre-set to the booked count, so the common case needs no explanation. expect(find.text('3'), findsOneWidget); expect(find.text('What happened?'), findsNothing); await tester.tap(find.byIcon(LucideIcons.minus)); await tester.pumpAndSettle(); expect(find.text('1 fewer than the parcels booked'), findsOneWidget); expect(find.text('What happened?'), findsOneWidget); }); testWidgets('damaged goods force a written reason too', (tester) async { await pumpStop(tester, stopOf(type: 'pickup', pickupQty: 1)); expect(find.text('What happened?'), findsNothing); await tester.tap(find.text('Damaged')); await tester.pumpAndSettle(); expect(find.text('What happened?'), findsOneWidget); }); testWidgets('COD is surfaced on the stop summary', (tester) async { await pumpStop(tester, stopOf(type: 'pickup', pickupQty: 1, cash: 720)); expect(find.text('₹720 to collect'), findsOneWidget); }); }