import 'package:flutter_test/flutter_test.dart'; import 'package:miler/data/service_profile.dart'; import 'package:miler/views/Dashboard/activity/activity_format.dart'; /// ───────────────────────────────────────────────────────────────────────── /// READING A DOORMILE TIMESTAMP /// /// Doormile timestamps are IST wall-clock in Postgres `timestamp without time /// zone` columns. Some responses come back with a trailing `Z` anyway — a Go + /// pgx footgun where a naive DB timestamp loads into `time.Time` under the UTC /// location and marshals with a zone marker it never had. The console strips it /// the same way; see `src/utils/doormileTimestamp.js`. /// /// `DateTime.tryParse` believes the `Z`, and that broke the tracking rail in the /// one way it cannot survive: on a real phone an event stamped `11:43Z` sorted /// *below* two 11:57 events, because as an absolute instant it is 17:13 IST — /// while its own rung still printed `11:43`, so nothing on screen explained the /// order. /// ───────────────────────────────────────────────────────────────────────── void main() { group('parseStamp', () { test('a false Z is stripped, not believed', () { final withZ = parseStamp('2026-08-20T11:43:00.000Z')!; final naive = parseStamp('2026-08-20T11:43:00.000')!; // Same wall-clock, and therefore the same instant on this device. expect(withZ, naive); expect(withZ.hour, 11); expect(withZ.minute, 43); expect(clockOf(withZ), '11:43 AM'); }); test('an offset marker is stripped too', () { expect( parseStamp('2026-08-20T11:43:00+05:30'), parseStamp('2026-08-20T11:43:00'), ); }); test('it sorts by the clock it prints', () { // The exact shape of the device bug: a backend stamp and two local ones. final placed = parseStamp('2026-08-20T11:43:00.000Z')!; final setOff = parseStamp('2026-08-20T11:57:00.000')!; expect(placed.isBefore(setOff), isTrue); }); test('empty and unparseable are null, never a fabricated moment', () { expect(parseStamp(null), isNull); expect(parseStamp(''), isNull); expect(parseStamp(' '), isNull); expect(parseStamp('not a date'), isNull); }); }); group('happenedAt', () { test('reads through parseStamp, so the list and the record agree', () { final row = {'completedat': '2026-08-20T11:43:00.000Z'}; expect(happenedAt(row), parseStamp('2026-08-20T11:43:00')!); }); test('a record with no usable stamp sinks rather than jumping the day', () { expect(happenedAt(const {}).millisecondsSinceEpoch, 0); }); }); group('routeLineOf', () { test('reads as speech, and carries no arrow character', () { // Poppins has no U+2192, so the app drew the most-read line on the record // as `Vidhya Kitchen ▯ Joe Mathew`. The arrow is a Material glyph on // screen now; this string is for screen readers and logs, where the word // is what a listener needs anyway. const stop = { 'pickupcustomer': 'Joe Mathew', 'sourcename': 'Vidhya Kitchen', }; ServiceProfile.setActive(ServiceProfile.milkMan); addTearDown(() => ServiceProfile.setActive(ServiceProfile.parcel)); expect(routeLineOf(stop), 'Vidhya Kitchen to Joe Mathew'); expect(routeLineOf(stop), isNot(contains('→'))); }); }); }