MotorSignal-App/test/aws_location_route_provider...

226 lines
7.4 KiB
Dart

import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:motorcycle_dash/services/map/map_provider_interface.dart';
import 'package:motorcycle_dash/services/routes/aws_location_route_provider.dart';
import 'package:motorcycle_dash/services/routes/route_models.dart';
import 'package:motorcycle_dash/services/routes/route_provider.dart';
void main() {
group('AwsLocationRouteProvider Tests', () {
test('instance properties and custom configuration', () {
final provider = AwsLocationRouteProvider(
apiKey: 'test-key',
region: 'us-west-2',
);
expect(provider.name, equals('Amazon AWS Location'));
expect(provider.apiKey, equals('test-key'));
expect(provider.region, equals('us-west-2'));
});
test('searchPlaces returns empty list for queries shorter than 2 characters', () async {
final provider = AwsLocationRouteProvider();
final results = await provider.searchPlaces('a');
expect(results, isEmpty);
});
test('searchPlaces parses combined autocomplete and searchText results', () async {
final mockClient = MockClient((request) async {
if (request.url.path.contains('/v2/autocomplete')) {
expect(request.url.queryParameters['key'], equals('test-key'));
final body = jsonDecode(request.body);
expect(body['QueryText'], equals('Atlanta'));
return http.Response(
jsonEncode({
'ResultItems': [
{
'PlaceId': 'place_auto_1',
'Title': 'Atlanta, GA, USA',
'Address': {'Label': 'Atlanta, Fulton County, Georgia, USA'},
}
]
}),
200,
);
} else if (request.url.path.contains('/v2/search-text')) {
return http.Response(
jsonEncode({
'ResultItems': [
{
'PlaceId': 'place_text_1',
'Title': 'Atlanta City Hall',
'Address': {'Label': '68 Mitchell St SW, Atlanta, GA 30303'},
'Position': [-84.3902, 33.7490],
}
]
}),
200,
);
}
return http.Response('Not Found', 404);
});
final provider = AwsLocationRouteProvider(
apiKey: 'test-key',
client: mockClient,
);
final results = await provider.searchPlaces(
'Atlanta',
nearLocation: const AppLatLng(33.7490, -84.3880),
);
expect(results.length, equals(2));
// First is text search result with coordinates
expect(results[0].providerId, equals('place_text_1'));
expect(results[0].primaryText, equals('Atlanta City Hall'));
expect(results[0].latitude, equals(33.7490));
expect(results[0].longitude, equals(-84.3902));
expect(results[0].hasCoordinates, isTrue);
// Second is autocomplete result
expect(results[1].providerId, equals('place_auto_1'));
expect(results[1].primaryText, equals('Atlanta, GA, USA'));
expect(results[1].hasCoordinates, isFalse);
});
test('resolvePlace fetches place details and returns ResolvedPlace', () async {
final mockClient = MockClient((request) async {
expect(request.url.path, contains('/v2/place/place_123'));
expect(request.url.queryParameters['key'], equals('test-key'));
return http.Response(
jsonEncode({
'PlaceId': 'place_123',
'Title': 'Blue Ridge Parkway North End',
'Address': {'Label': 'Afton, VA 22920'},
'Position': [-78.8608, 38.0315],
}),
200,
);
});
final provider = AwsLocationRouteProvider(
apiKey: 'test-key',
client: mockClient,
);
final place = await provider.resolvePlace('place_123');
expect(place.providerId, equals('place_123'));
expect(place.displayName, equals('Blue Ridge Parkway North End'));
expect(place.formattedAddress, equals('Afton, VA 22920'));
expect(place.latitude, equals(38.0315));
expect(place.longitude, equals(-78.8608));
});
test('resolvePlace throws on empty placeId or 404', () async {
final mockClient = MockClient((request) async {
return http.Response('Not Found', 404);
});
final provider = AwsLocationRouteProvider(
apiKey: 'test-key',
client: mockClient,
);
expect(
() => provider.resolvePlace(' '),
throwsA(isA<RouteProviderException>().having((e) => e.code, 'code', 'invalidRequest')),
);
expect(
() => provider.resolvePlace('missing_id'),
throwsA(isA<RouteProviderException>().having((e) => e.code, 'code', 'placeNotFound')),
);
});
test('calculateRoute requires at least 2 stops', () async {
final provider = AwsLocationRouteProvider();
expect(
() => provider.calculateRoute([
const RouteStop(
id: '1',
order: 0,
displayName: 'Origin',
latitude: 34.0,
longitude: -84.0,
),
]),
throwsA(isA<RouteProviderException>().having((e) => e.code, 'code', 'invalidRequest')),
);
});
test('calculateRoute computes route and returns parsed geometry', () async {
final mockClient = MockClient((request) async {
expect(request.url.path, contains('/v2/routes'));
expect(request.url.queryParameters['key'], equals('test-key'));
final body = jsonDecode(request.body);
expect(body['TravelMode'], equals('Car'));
expect(body['LegGeometryFormat'], equals('Simple'));
expect(body['Origin'], equals([-84.0, 34.0]));
expect(body['Destination'], equals([-84.5, 34.5]));
return http.Response(
jsonEncode({
'Routes': [
{
'Summary': {
'Distance': 65432.1,
'Duration': 2700,
},
'Legs': [
{
'Geometry': {
'LineString': [
[-84.0, 34.0],
[-84.25, 34.25],
[-84.5, 34.5],
],
},
},
],
},
],
}),
200,
);
});
final provider = AwsLocationRouteProvider(
apiKey: 'test-key',
client: mockClient,
);
final stops = [
const RouteStop(
id: '1',
order: 0,
displayName: 'Start',
latitude: 34.0,
longitude: -84.0,
),
const RouteStop(
id: '2',
order: 1,
displayName: 'End',
latitude: 34.5,
longitude: -84.5,
),
];
final result = await provider.calculateRoute(stops);
expect(result.estimatedDistanceMeters, equals(65432.1));
expect(result.estimatedDurationSeconds, equals(2700));
expect(result.geometry.length, equals(3));
expect(result.geometry[0].latitude, equals(34.0));
expect(result.geometry[0].longitude, equals(-84.0));
expect(result.geometry[2].latitude, equals(34.5));
expect(result.geometry[2].longitude, equals(-84.5));
expect(result.isStraightLine, isFalse);
expect(result.providerName, equals('Amazon AWS Location'));
});
});
}