MotorSignal-App/test/navigation_session_service_...

161 lines
5.7 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:motorcycle_dash/services/map/map_provider_interface.dart';
import 'package:motorcycle_dash/services/navigation/navigation_session_service.dart';
import 'package:motorcycle_dash/services/routes/route_models.dart';
import 'package:motorcycle_dash/services/routes/route_provider.dart';
void main() {
group('NavigationSessionNotifier Tests', () {
test('initial state is idle and empty', () {
final notifier = NavigationSessionNotifier();
expect(notifier.state.status, equals(NavigationStatus.idle));
expect(notifier.state.isNavigating, isFalse);
expect(notifier.state.hasActiveRoute, isFalse);
expect(notifier.state.maneuvers, isEmpty);
});
test('startNavigation initiates turn-by-turn guidance', () async {
final notifier = NavigationSessionNotifier();
final maneuvers = [
const RouteManeuver(
index: 0,
instruction: 'Head north on Peachtree St',
type: ManeuverType.depart,
distanceMeters: 500.0,
durationSeconds: 60,
streetName: 'Peachtree St',
location: AppLatLng(33.750, -84.388),
),
const RouteManeuver(
index: 1,
instruction: 'Turn right on 10th St',
type: ManeuverType.turnRight,
distanceMeters: 1000.0,
durationSeconds: 120,
streetName: '10th St',
location: AppLatLng(33.780, -84.385),
),
const RouteManeuver(
index: 2,
instruction: 'Arrive at Piedmont Park',
type: ManeuverType.arrive,
distanceMeters: 0.0,
durationSeconds: 0,
streetName: 'Piedmont Park',
location: AppLatLng(33.790, -84.370),
),
];
final calcResult = RouteCalculationResult(
straightLineDistanceMeters: 1500.0,
estimatedDistanceMeters: 1500.0,
estimatedDurationSeconds: 180,
geometry: const [
AppLatLng(33.750, -84.388),
AppLatLng(33.780, -84.385),
AppLatLng(33.790, -84.370),
],
isStraightLine: false,
providerName: 'AWS Location',
maneuvers: maneuvers,
);
await notifier.startNavigation(
calculationResult: calcResult,
destination: const ResolvedPlace(
providerId: 'dest_1',
displayName: 'Piedmont Park',
latitude: 33.790,
longitude: -84.370,
),
);
expect(notifier.state.isNavigating, isTrue);
expect(notifier.state.status, equals(NavigationStatus.navigating));
expect(notifier.state.maneuvers.length, equals(3));
expect(notifier.state.currentManeuverIndex, equals(0));
expect(notifier.state.currentManeuver?.instruction, equals('Head north on Peachtree St'));
expect(notifier.state.nextManeuver?.instruction, equals('Turn right on 10th St'));
expect(notifier.state.remainingDistanceMeters, equals(1500.0));
expect(notifier.state.remainingDurationSeconds, equals(180));
});
test('updateLocation advances maneuvers when rider approaches waypoint', () async {
final notifier = NavigationSessionNotifier();
final maneuvers = [
const RouteManeuver(
index: 0,
instruction: 'Head north on Main',
type: ManeuverType.depart,
distanceMeters: 200.0,
durationSeconds: 30,
location: AppLatLng(33.7500, -84.3880),
),
const RouteManeuver(
index: 1,
instruction: 'Turn left on Elm',
type: ManeuverType.turnLeft,
distanceMeters: 800.0,
durationSeconds: 90,
location: AppLatLng(33.7518, -84.3880), // ~200m north
),
const RouteManeuver(
index: 2,
instruction: 'Arrive at destination',
type: ManeuverType.arrive,
distanceMeters: 0.0,
durationSeconds: 0,
location: AppLatLng(33.7518, -84.3960),
),
];
final calcResult = RouteCalculationResult(
straightLineDistanceMeters: 1000.0,
estimatedDistanceMeters: 1000.0,
estimatedDurationSeconds: 120,
geometry: const [
AppLatLng(33.7500, -84.3880),
AppLatLng(33.7518, -84.3880),
AppLatLng(33.7518, -84.3960),
],
isStraightLine: false,
providerName: 'AWS Location',
maneuvers: maneuvers,
);
await notifier.startNavigation(calculationResult: calcResult);
// Rider is approaching starting waypoint (approx 100m south)
notifier.updateLocation(const AppLatLng(33.7490, -84.3880), speedMph: 25.0);
expect(notifier.state.currentManeuverIndex, equals(0));
// Rider reaches within 10 meters of maneuver 0 point
notifier.updateLocation(const AppLatLng(33.7500, -84.3880), speedMph: 25.0);
expect(notifier.state.currentManeuverIndex, equals(1));
expect(notifier.state.currentManeuver?.instruction, equals('Turn left on Elm'));
// Pause and resume
notifier.pauseNavigation();
expect(notifier.state.status, equals(NavigationStatus.paused));
expect(notifier.state.isNavigating, isFalse);
notifier.resumeNavigation();
expect(notifier.state.status, equals(NavigationStatus.navigating));
// Stop navigation
await notifier.stopNavigation();
expect(notifier.state.status, equals(NavigationStatus.idle));
expect(notifier.state.hasActiveRoute, isFalse);
});
test('toggleTts toggles voice guidance', () {
final notifier = NavigationSessionNotifier();
expect(notifier.state.ttsEnabled, isTrue);
notifier.toggleTts();
expect(notifier.state.ttsEnabled, isFalse);
notifier.toggleTts();
expect(notifier.state.ttsEnabled, isTrue);
});
});
}