FB-04: fix Route Planner map failing to render on cold navigation

routePlanProvider's AsyncLoading state collapsed with "route doesn't exist"
via .valueOrNull, so a brand-new route's screen briefly rendered "This route
no longer exists." with no FlutterMap in the tree before the DB stream's
first emission arrived. Add a hasValue guard mirroring waypointsAsync's
existing pattern, and replace the route planner's hardcoded initialZoom of
14 with FB-01's ambientZoom constant for street-level parity with the rest
of the app.
This commit is contained in:
2026-08-24 16:12:06 -05:00
parent 9cc1cc779f
commit e491c9ee65
3 changed files with 114 additions and 3 deletions

View File

@@ -9,6 +9,7 @@ import 'package:rippr/src/data/database.dart';
import 'package:rippr/src/data/route_plan_repository.dart';
import 'package:rippr/src/ui/app_shell.dart';
import 'package:rippr/src/ui/components/floating_pill.dart';
import 'package:rippr/src/ui/components/ride_map.dart' show ambientZoom;
import 'package:rippr/src/ui/format.dart';
import 'package:rippr/src/ui/routes/route_planner_screen.dart';
import 'package:rippr/src/ui/routes/routes_list_screen.dart';
@@ -190,6 +191,42 @@ void main() {
expect(find.textContaining('no longer exists'), findsOneWidget);
});
screenTest(
'a brand-new route never flashes "no longer exists" while its stream is '
'still resolving, and shows the real map once it settles (FB-04)',
(tester) async {
// Mirrors the real "+ New route" flow: `repo.createRoutePlan` returns as soon as
// the row is written, but `routePlanProvider`'s DB stream hasn't delivered its
// first emission by the very next frame -- both `routePlanProvider` and
// `routeWaypointsProvider` start out `AsyncLoading` on this fresh navigation.
final id = await repo.createRoutePlan(1000, name: 'Fresh route');
await tester.pumpWidget(host(RoutePlannerScreen(routeId: id)));
// Immediately after the very first frame -- before the stream has had any chance
// to deliver -- the loading spinner must show, never the "no longer exists" text.
// (Pre-fix, `route` collapsed "still loading" and "doesn't exist" into the same
// null via `.valueOrNull`, so this assertion is exactly the FB-04 regression.)
expect(find.textContaining('no longer exists'), findsNothing);
expect(find.byType(CircularProgressIndicator), findsOneWidget);
expect(find.byType(FlutterMap), findsNothing);
// Once both streams deliver their first value, the real map canvas appears.
for (var i = 0; i < 10; i++) {
await tester.pump(const Duration(milliseconds: 50));
}
expect(find.textContaining('no longer exists'), findsNothing);
expect(find.byType(FlutterMap), findsOneWidget);
});
screenTest('a route with no waypoints opens at street-level zoom, not zoomed out '
'(FB-04)', (tester) async {
final id = await repo.createRoutePlan(1000);
await pumpMap(tester, host(RoutePlannerScreen(routeId: id)));
final map = tester.widget<FlutterMap>(find.byType(FlutterMap));
expect(map.options.initialZoom, ambientZoom);
});
screenTest('the offline-tiles download menu item is disabled with no pins '
'(V3-11, UI-06: now a PopupMenuItem behind the overflow menu)',
(tester) async {