import 'package:flutter_test/flutter_test.dart'; import 'package:miler/data/milk_run.dart'; import 'package:miler/data/service_profile.dart'; import 'package:miler/views/Dashboard/pickups/pickups.dart'; import 'package:miler/views/Dashboard/pickups/stop_type.dart'; /// ───────────────────────────────────────────────────────────────────────── /// THE DELIVERY LEG HAS NO ARRIVAL STEP /// /// What the rider reported: pressing **Start delivery** opened the map, and the /// map asked him to press **I've arrived** — which opened a sheet offering /// *Picked up · Skipped · Not picked* for a bag already in his box. /// /// Both halves were wrong. Arrival at a customer's door is not a state anything /// records — no endpoint exists for it — so the button wrote nothing and existed /// only to reveal the next screen; and the screen it revealed was the pickup /// flow's. A stop he is carrying is simply **active**, and the only question /// left is how it ended. /// /// These pin the vocabulary and the routing of the three outcomes. The control /// itself is a widget; what must not drift is which endpoint each outcome means /// and which of them ends the order. /// ───────────────────────────────────────────────────────────────────────── void main() { TestWidgetsFlutterBinding.ensureInitialized(); tearDown(() => ServiceProfile.setActive(ServiceProfile.parcel)); group('the three outcomes', () { test('are exactly delivered, skip and cancelled', () { expect(DeliveryOutcome.values.map((o) => o.label), [ 'Delivered', 'Skip', 'Cancelled', ]); }); test('delivered is the only one that completes the order', () { // Skip is a return visit — it increments `attemptcount` rather than // failing the parcel — and cancelled is a withdrawal. Neither is a // delivery, and Activity must not file them as one. expect(DeliveryOutcome.delivered.pastTense, 'Delivered'); expect(DeliveryOutcome.skipped.pastTense, 'Skipped'); expect(DeliveryOutcome.cancelled.pastTense, 'Cancelled'); }); test('each one is coloured by what it means, not by where it sits', () { expect( DeliveryOutcome.delivered.colour, isNot(DeliveryOutcome.cancelled.colour), ); expect( DeliveryOutcome.skipped.colour, isNot(DeliveryOutcome.cancelled.colour), ); }); }); group('which leg a stop is on decides which control it gets', () { setUp(() => ServiceProfile.setActive(ServiceProfile.milkMan)); Map stop(String status) => { 'orderid': 'A1', // The adapter stamps this on every row whatever leg it is on, which is // why the leg is asked of [MilkRun.workingKind] and never of the payload. 'type': 'pickup', 'orderstatus': status, 'kitchenname': 'Vidhya Kitchen', }; test('a collected order is on the delivery leg', () { expect(MilkRun.workingKind(stop('picked')).isDelivery, isTrue); expect( MilkRun.workingKind(stop('accepted'), collectedIds: {'A1'}).isDelivery, isTrue, ); }); test('an uncollected one is not — it keeps the pickup flow', () { // The arrival step and the confirmation sheet still belong to the pickup // leg on logistics, where the collection *is* the job at the door. expect(MilkRun.workingKind(stop('accepted')).isDelivery, isFalse); expect(MilkRun.workingKind(stop('arrived')).isDelivery, isFalse); }); test('and on logistics nothing is ever the delivery leg', () { // That line's parcel goes to a hub and is delivered by somebody else, so // the rider never drives to its customer and must keep I'VE ARRIVED. ServiceProfile.setActive(ServiceProfile.parcel); for (final status in ['accepted', 'arrived', 'picked']) { expect( MilkRun.workingKind(stop(status)).isDelivery, isFalse, reason: status, ); } }); }); }