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'; /// A skip is now shown on Activity rather than Home, and Activity reads its own /// endpoints — which do not report a skip for a poll or two, and never on demo /// data. So the store is what makes a skipped stop visible at all, and these /// are the properties the two screens rely on: /// /// • it survives the app being killed mid-shift; /// • it stamps the stop so one `stopStatusOf` test recognises it everywhere; /// • it forgets a resumed stop, or Activity would keep offering Resume for /// something already back on Bookings; /// • it forgets yesterday, or the tab grows without bound. void main() { Map booking(String id) => { 'orderid': id, 'pickupid': '9$id', 'pickupcustomer': 'Sri Balaji Stores', 'orderstatus': 'active', }; setUp(() => SharedPreferences.setMockInitialValues({})); test('a skip is recorded with its reason and reads back as skipped', () async { await addSkippedBooking(booking('A'), reason: 'Customer unreachable'); final stored = await getSkippedBookings(); expect(stored, hasLength(1)); expect(stored.single['skipreason'], 'Customer unreachable'); expect( stopStatusOf(stored.single), StopStatus.skipped, reason: 'the stamp is what lets one status test serve every screen', ); expect(await getSkippedOrderIds(), {'A'}); }); test('the same stop skipped twice is one row, not two', () async { await addSkippedBooking(booking('A'), reason: 'Customer unreachable'); await addSkippedBooking(booking('A'), reason: 'Shutter closed'); final stored = await getSkippedBookings(); expect(stored, hasLength(1)); expect(stored.single['skipreason'], 'Shutter closed'); }); test('resuming forgets the skip', () async { await addSkippedBooking(booking('A'), reason: 'Customer unreachable'); await addSkippedBooking(booking('B'), reason: 'Not at the location'); await removeSkippedBookings(['A']); expect(await getSkippedOrderIds(), {'B'}); }); test('yesterday is dropped on read', () async { // Written the way the store writes, but stamped for another day. final stale = booking('A') ..['orderstatus'] = 'skipped' ..['skipreason'] = 'Customer unreachable' ..['skippedat'] = '2020-01-01T09:00:00.000' ..['skippedday'] = '2020-01-01'; SharedPreferences.setMockInitialValues({ 'skipped_bookings': jsonEncode([stale]), }); expect(await getSkippedBookings(), isEmpty); // And the prune is persisted, so the row cannot come back. final prefs = await SharedPreferences.getInstance(); expect(jsonDecode(prefs.getString('skipped_bookings')!), isEmpty); }); test('newest first — the stop he just put down leads the list', () async { await addSkippedBooking(booking('A'), reason: 'Customer unreachable'); await Future.delayed(const Duration(milliseconds: 5)); await addSkippedBooking(booking('B'), reason: 'Shutter closed'); final stored = await getSkippedBookings(); expect(stored.map((s) => s['orderid']), ['B', 'A']); }); }