import 'package:consumer_app/shared/navigation/external_navigation_adapter.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
const target = NavigationTarget(
latitude: 50.9795,
longitude: 11.3235,
address: 'Markt 1, 99423 Weimar',
);
test('iOS tries Google Maps before the local Apple Maps fallback', () {
final adapter = ExternalNavigationAdapter(
platform: ExternalNavigationPlatform.ios,
launch: (_) async => true,
);
final uris = adapter.candidateUris(target);
expect(uris, hasLength(3));
expect(uris[0].scheme, 'comgooglemaps');
expect(uris[0].queryParameters['daddr'], '50.9795,11.3235');
expect(uris[1].scheme, 'maps');
expect(uris[2].host, 'www.google.com');
expect(uris[2].queryParameters['api'], '1');
});
test('Android tries Google Maps, then local geo navigation, then web', () {
final adapter = ExternalNavigationAdapter(
platform: ExternalNavigationPlatform.android,
launch: (_) async => false,
);
final uris = adapter.candidateUris(
target,
webUrlTemplate:
'https://navigate.example/?to={coordinates}&label={address}',
);
expect(uris, hasLength(3));
expect(uris[0].scheme, 'google.navigation');
expect(uris[1].scheme, 'geo');
expect(uris[1].queryParameters['q'], target.address);
expect(uris[2].scheme, 'https');
expect(uris[2].queryParameters['to'], '50.9795,11.3235');
expect(uris[2].queryParameters['label'], target.address);
});
test(
'web opens official Google Maps when no custom template is configured',
() {
final adapter = ExternalNavigationAdapter(
platform: ExternalNavigationPlatform.web,
launch: (_) async => true,
);
final uri = adapter.candidateUris(target).single;
expect(uri.host, 'www.google.com');
expect(uri.path, '/maps/dir/');
expect(uri.queryParameters['destination'], '50.9795,11.3235');
},
);
test('map fallback opens Google Maps centered on the target', () {
final adapter = ExternalNavigationAdapter(
platform: ExternalNavigationPlatform.web,
launch: (_) async => true,
);
final uris = adapter.mapCandidateUris(target, zoom: 15);
expect(uris, hasLength(1));
expect(uris.single.host, 'www.google.com');
expect(uris.single.path, '/maps/search/');
expect(uris.single.queryParameters['api'], '1');
expect(uris.single.queryParameters['query'], '50.9795,11.3235');
});
test('native map fallback tries Google Maps before local maps', () {
final adapter = ExternalNavigationAdapter(
platform: ExternalNavigationPlatform.ios,
launch: (_) async => false,
);
final uris = adapter.mapCandidateUris(target, zoom: 15);
expect(uris.map((uri) => uri.scheme), ['comgooglemaps', 'maps', 'https']);
expect(uris.first.queryParameters['center'], '50.9795,11.3235');
});
test(
'system provider keeps the local platform fallback without inventing web URLs',
() {
final adapter = ExternalNavigationAdapter(
platform: ExternalNavigationPlatform.web,
launch: (_) async => true,
);
expect(
adapter.candidateUris(target, navigationProvider: 'system'),
isEmpty,
);
},
);
test('invalid coordinates never reach an external launcher', () async {
var launched = false;
final adapter = ExternalNavigationAdapter(
platform: ExternalNavigationPlatform.web,
launch: (_) async {
launched = true;
return true;
},
);
final opened = await adapter.open(
const NavigationTarget(latitude: 91, longitude: 11),
webUrlTemplate: 'https://navigate.example/?to={coordinates}',
);
expect(opened, isFalse);
expect(launched, isFalse);
});
test('falls back after a native launcher throws', () async {
final launched = <Uri>[];
final adapter = ExternalNavigationAdapter(
platform: ExternalNavigationPlatform.android,
launch: (uri) async {
launched.add(uri);
if (uri.scheme == 'google.navigation' || uri.scheme == 'geo') {
throw StateError('no maps handler');
}
return true;
},
);
final opened = await adapter.open(
target,
webUrlTemplate: 'https://navigate.example/?to={coordinates}',
);
expect(opened, isTrue);
expect(launched.map((uri) => uri.scheme), [
'google.navigation',
'geo',
'https',
]);
});
}
