import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:miler/Models/stop_status.dart'; import 'package:miler/data/accepted_store.dart'; import 'package:miler/data/service_profile.dart'; /// ───────────────────────────────────────────────────────────────────────── /// A SKIPPED DELIVERY IS DONE WITH, NOT PARKED /// /// ── The regression ── /// /// A skip at a customer's door left the tab and came back. The in-memory set /// that holds a just-finished stop off the list is what was doing the work, /// and it dies with the process — so the next cold start put the stop the /// rider had written off an hour earlier back at the top of his queue, while /// its record sat in Activity saying otherwise. /// /// It is specifically a *skip* problem. A delivery closes the consignment, so /// the backend stops calling it delivery work within a poll or two and the row /// drops out on its own. A skip is a failed attempt: the server rightly leaves /// the consignment `Out_for_Delivery`, and it will keep coming back for as long /// as the day lasts unless the device remembers what it did. /// /// These pin the store rules that hold it off the tab and put it on Activity /// under its own word. /// ───────────────────────────────────────────────────────────────────────── void main() { TestWidgetsFlutterBinding.ensureInitialized(); setUp(() { SharedPreferences.setMockInitialValues({'userid': 38}); ServiceProfile.setActive(ServiceProfile.milkMan); }); tearDown(() => ServiceProfile.setActive(ServiceProfile.parcel)); Map stop(String id) => { 'orderid': id, 'pickupid': int.parse(id), 'orderstatus': 'outfordelivery', 'pickupcustomer': 'SEQTEST Ukkadam', }; group('the record', () { test( 'a skip is filed as a skip, not flattened into a cancellation', () async { await addCompletedBookings([stop('1001')], terminalStatus: 'skipped'); final filed = (await getCompletedBookings()).single; expect(stopStatusOf(filed).isSkipped, isTrue); expect( stopStatusOf(filed).isCancelled, isFalse, reason: 'a stop the rider walked away from and one the office called ' 'off are different things, and Activity slices them apart', ); }, ); test('the exact word wins over the cancelled shorthand', () async { // `cancelled: true` is what suppresses the "delivery N of M" toast, so // the skip path passes both — and the precise word has to survive. await addCompletedBookings( [stop('1001')], cancelled: true, terminalStatus: 'skipped', ); expect((await getCompletedBookings()).single['orderstatus'], 'skipped'); }); test('a real cancellation still files as cancelled', () async { await addCompletedBookings([stop('1001')], cancelled: true); expect((await getCompletedBookings()).single['orderstatus'], 'cancelled'); }); test('a delivery still files as delivered', () async { await addCompletedBookings([stop('1001')]); expect( (await getCompletedBookings()).single['orderstatus'], 'delivered', reason: 'the milk run ends at the customer, not at a hub', ); }); }); group('it stays off the deliveries tab', () { test('the closed set survives the process that wrote it', () async { await addCompletedBookings([stop('1001')], terminalStatus: 'skipped'); // What a cold start reads back — the same call the Deliveries tab makes // to rebuild its just-finished set. expect(await getCompletedOrderIds(), contains('1001')); }); test('closing one stop does not close the rest of the load', () async { await addCompletedBookings([stop('1001')], terminalStatus: 'skipped'); expect(await getCompletedOrderIds(), isNot(contains('1002'))); }); test('yesterday’s skip is not today’s work', () async { // Pruned on read, like every other record in this store: a skip the // rider can no longer act on must not hold a stop off tomorrow's tab. await addCompletedBookings([stop('1001')], terminalStatus: 'skipped'); final aged = (await getCompletedBookings()) .map((b) => {...b, 'completedday': '2020-01-01'}) .toList(); await debugSeedStore('completed_bookings', jsonEncode(aged)); expect(await getCompletedOrderIds(), isEmpty); }); test('another rider’s skip is not this one’s', () async { await addCompletedBookings([stop('1001')], terminalStatus: 'skipped'); SharedPreferences.setMockInitialValues({'userid': 99}); expect(await getCompletedOrderIds(), isEmpty); }); }); }