import 'package:flutter_test/flutter_test.dart'; import 'package:miler/data/assignment_lookup.dart'; /// Rows shaped like GET /miler/assignments (models.BookingAssignment), which the /// backend returns ordered by assignedat DESC. Map row( int assignmentId, dynamic bookingId, String status, ) => { 'bookingassignmentid': assignmentId, 'bookingid': bookingId, 'mileruserid': 42, 'assignmentstatus': status, }; void main() { group('AssignmentLookup.buildIndex', () { test('maps bookingid to bookingassignmentid, not to itself', () { final index = AssignmentLookup.buildIndex([row(9001, 5, 'Assigned')]); // The whole point: booking 5 must resolve to assignment 9001. Returning // the booking id here is the 404 bug this class exists to prevent. expect(index['5'], 9001); }); test('keeps the newest row when a booking has only terminal history', () { // assignedat DESC — newest first. final index = AssignmentLookup.buildIndex([ row(9003, 7, 'Rejected'), row(9002, 7, 'Cancelled'), ]); expect(index['7'], 9003); }); test('prefers a live assignment over a newer terminal one', () { // Reassignment history: the Rejected row is newer, but the rider must act // on the still-live Assigned row. final index = AssignmentLookup.buildIndex([ row(9010, 8, 'Rejected'), row(9009, 8, 'Assigned'), ]); expect(index['8'], 9009); }); test('does not let a later terminal row displace a live one', () { final index = AssignmentLookup.buildIndex([ row(9020, 9, 'Assigned'), row(9019, 9, 'Rejected'), ]); expect(index['9'], 9020); }); test('treats Accepted as live so re-accept resolves the same assignment', () { final index = AssignmentLookup.buildIndex([ row(9031, 11, 'Cancelled'), row(9030, 11, 'Accepted'), ]); expect(index['11'], 9030); }); test('normalises int and string booking ids to the same key', () { final index = AssignmentLookup.buildIndex([ row(9040, 12, 'Assigned'), row(9041, '13', 'Assigned'), ]); expect(index['12'], 9040); expect(index['13'], 9041); }); test('coerces a string assignment id to int', () { final index = AssignmentLookup.buildIndex([ { 'bookingassignmentid': '9050', 'bookingid': 14, 'assignmentstatus': 'Assigned', } ]); expect(index['14'], 9050); }); test('skips rows missing either id rather than mapping them to garbage', () { final index = AssignmentLookup.buildIndex([ {'bookingid': 15, 'assignmentstatus': 'Assigned'}, { 'bookingassignmentid': 9060, 'assignmentstatus': 'Assigned' }, { 'bookingassignmentid': null, 'bookingid': null, 'assignmentstatus': 'Assigned' }, ]); expect(index, isEmpty); }); test('ignores non-map entries', () { final index = AssignmentLookup.buildIndex([ 'nonsense', 42, null, row(9070, 16, 'Assigned'), ]); expect(index, {'16': 9070}); }); test('handles an empty list', () { expect(AssignmentLookup.buildIndex([]), isEmpty); }); }); }