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().having((e) => e.code, 'code', 'invalidRequest')), ); expect( () => provider.resolvePlace('missing_id'), throwsA(isA().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().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')); }); }); }