import 'package:flutter_test/flutter_test.dart'; import 'package:miler/data/service_profile.dart'; import 'package:miler/views/Dashboard/pickups/stop_type.dart'; /// ───────────────────────────────────────────────────────────────────────── /// ONE APP, TWO VOCABULARIES /// /// The two rider apps this one replaces disagreed about what a job is called: /// the parcel app said **booking**, the meal app said **delivery**. Merging /// them did not make either wrong — a rider collecting a consignment for the /// hub is not delivering it, and a rider handing somebody lunch has not taken a /// booking — so the noun follows the line of work and a rider only ever sees /// the word he already uses. /// /// These tests are the contract every screen reads through. Get them wrong and /// a meal rider is told to "work it from Bookings", a tab he does not have. /// ───────────────────────────────────────────────────────────────────────── void main() { TestWidgetsFlutterBinding.ensureInitialized(); tearDown(() => ServiceProfile.setActive(ServiceProfile.parcel)); group('the noun for a job', () { test('a parcel route takes bookings', () { const p = ServiceProfile.parcel; expect(p.jobNoun, 'booking'); expect(p.jobNounPlural, 'bookings'); expect(p.workTabLabel, 'Bookings'); expect(p.completionVerb, 'Picked up'); }); test('a meal run makes deliveries', () { const p = ServiceProfile.meals; expect(p.jobNoun, 'delivery'); expect(p.jobNounPlural, 'deliveries'); expect(p.workTabLabel, 'Deliveries'); expect(p.completionVerb, 'Delivered'); }); test('the tab label is the plural, title-cased — never hand-written', () { // Two strings for one word is how "Deliveries" ends up on the tab while a // sentence three screens away still says "bookings". for (final p in [ServiceProfile.parcel, ServiceProfile.meals]) { expect(p.workTabLabel.toLowerCase(), p.jobNounPlural); } }); }); group('what the app is called', () { test('both lines are Doormile — the rider has one employer', () { // The crate he is carrying does not change who he works for, and no // screen names a company that no longer exists. expect(ServiceProfile.parcel.label, 'Doormile'); expect(ServiceProfile.meals.label, startsWith('Doormile')); }); }); group('what kind of stop this is', () { test('a meal run drops — it does not collect at a customer door', () { ServiceProfile.setActive(ServiceProfile.meals); // The payload names nothing. Falling through to "pickup" here is what put // the word "Picked up" on the confirm button at a subscriber's flat. expect(stopKindOf({}), StopKind.delivery); expect(stopKindOf({}).isDelivery, isTrue); }); test('an explicit label still wins over the line', () { ServiceProfile.setActive(ServiceProfile.meals); // The kitchen leg is a genuine collection, and the collection gate reads // the real kind underneath whatever the chip says. expect(stopKindOf({'type': 'pickup'}), StopKind.pickup); expect(stopKindOf({'type': 'combined'}), StopKind.combined); }); test('a parcel route is unchanged — an unlabelled stop is a pickup', () { ServiceProfile.setActive(ServiceProfile.parcel); expect(stopKindOf({}), StopKind.pickup); }); }); group('the line of work', () { test('the two lines are told apart by capability, not by name', () { // Every screen asks "does this line collect cash?", never "is this the // meal tenant?" — which is what makes a third kind of client a new // profile rather than a third UI. expect(ServiceProfile.parcel.collectsCash, isTrue); expect(ServiceProfile.meals.collectsCash, isFalse); expect(ServiceProfile.meals.sourceIsKitchen, isTrue); expect(ServiceProfile.meals.handsOffAtCollection, isTrue); expect(ServiceProfile.parcel.handsOffAtCollection, isFalse); }); test('only the meal line photographs a load in one shot', () { expect(ServiceProfile.meals.bulkLoadProof, isTrue); expect(ServiceProfile.parcel.bulkLoadProof, isFalse); }); }); }