import 'package:flutter_test/flutter_test.dart'; import 'package:miler/data/meal_run_mock.dart'; import 'package:miler/data/mock_backend.dart'; import 'package:miler/data/service_profile.dart'; import 'package:miler/providers/pickup/pickup_provider.dart'; /// ───────────────────────────────────────────────────────────────────────── /// A MISSING BACKEND IS A STATE, NOT A FIXTURE /// /// The `/miler/*` contract serves bookings and consignments. Kitchens, crates /// and subscribers are not concepts it has — there is no endpoint that returns /// a meal run. That is a backend capability that does not exist yet. /// /// It was being papered over by [MealRunMock], which was on by default in every /// debug build. So the meal line *looked* integrated, and the gap was invisible /// until somebody built a release. /// /// These pin the boundary: the fixture is opt-in only, and with it off the /// provider **refuses** rather than returning an empty list — because "no work /// today" and "your hub has not switched this on" are different answers and the /// rider acts differently on each. /// ───────────────────────────────────────────────────────────────────────── void main() { TestWidgetsFlutterBinding.ensureInitialized(); tearDown(() { MockBackend.enabled = kMockBackend; MealRunMock.reset(); ServiceProfile.setActive(ServiceProfile.parcel); }); group('the capability is named, not implied', () { test('the lines whose work IS bookings are served', () { expect(ServiceProfile.parcel.hasBookingsEndpoint, isTrue); expect(ServiceProfile.delivery.hasBookingsEndpoint, isTrue); }); test('the milk-man line is served too — the hub dispatches it', () { // This asserted `isFalse`, and that is what kept a real rider empty: // tenant 13 resolves to this profile, the hub assigns him bookings in the // console, and the app refused to ask for them. The console reads the // round from /admin/bookings and assigns with // /hub/bookings/:id/auto-assign — the same rows /miler/bookings returns. expect(ServiceProfile.milkMan.hasBookingsEndpoint, isTrue); }); test('the capability does not depend on the fixture', () { // Whichever way it answers, an opt-in dev flag must not be what decides. MockBackend.enabled = true; expect( ServiceProfile.milkMan.hasBookingsEndpoint, isTrue, reason: 'the fixture must never be what answers a backend capability', ); }); }); group('with the fixture off, which is the default', () { setUp(() => MockBackend.enabled = false); test('a milk-man rider is not refused — he is dispatched bookings', () { // Asserted on the capability rather than by calling, for the same reason // as the parcel case below: the path now proceeds to a real request. // // This used to expect a [LineNotServedException]. It was the assertion // that made the bug look intentional: a rider the hub had assigned work // to could not be handed it, because his line was believed to have no // endpoint. The refusal is still reachable — see [LineNotServedException] // and the test below — it is just no longer this line's answer. ServiceProfile.setActive(ServiceProfile.milkMan); expect(ServiceProfile.active.hasBookingsEndpoint, isTrue); }); test('the refusal explains itself', () { expect( const LineNotServedException().toString(), contains('not served by the backend yet'), ); }); test('a parcel rider is never refused — he has an endpoint', () { // Asserted on the capability rather than by calling: the parcel path // proceeds to a real request, and a test that reaches the network is a // test about the network. ServiceProfile.setActive(ServiceProfile.parcel); expect(ServiceProfile.active.hasBookingsEndpoint, isTrue); }); test('the fixture is unreachable while it is off', () { ServiceProfile.setActive(ServiceProfile.milkMan); expect(MealRunMock.active, isFalse); }); }); test( 'the fixture is reachable only when asked for, and only on its line', () { MockBackend.enabled = true; ServiceProfile.setActive(ServiceProfile.milkMan); expect(MealRunMock.active, isTrue); // And still not by a parcel rider, whatever else is true. ServiceProfile.setActive(ServiceProfile.parcel); expect(MealRunMock.active, isFalse); }, ); }