Location search starts a new mission; shrink and center header bar
Ortssuche verschob bisher nur die Karte - der HTML-Demonstrator beginnt bei einer Suche immer eine neue, nach dem gefundenen Ort benannte Mission (setMissionFromPlace(), aufgerufen aus doSearch()). Vorherige Aenderungen gehen dabei nicht verloren, da flushPendingAutosave() (hier: CurrentMissionMetaNotifier._flushNow()) zuerst noch ausstehende Autosaves schreibt. Die Nominatim-Suche wurde dafuer aus MapSearchControls in einen eigenstaendigen NominatimService extrahiert (analog WindService): injectable http.Client, damit sich die Suche in Tests ohne echten Netzwerkzugriff ueberschreiben laesst. CurrentMissionMetaNotifier bekam dafuer startNewFromPlace() (startNew() intern darauf umgebaut, um Duplikation zu vermeiden). Kopfleiste von 86%/64% (Plan-/Fly-Modus) auf einheitlich 70% Bildschirmbreite verkleinert - zentriert war sie durch Align(topCenter) + FractionallySizedBox bereits strukturell korrekt, wirkte bei der vollen Breite aber unausgewogen. Verifiziert: flutter analyze (0 issues), flutter test (64/64, davon 4 neue NominatimService-Tests und 1 neuer Widget-Test fuer den Missions-Reset bei Ortssuche), manuell auf Pixel_10a-Emulator - Suche nach "Rotterdam" setzt Fusszeile auf "Mission: Rotterdam" mit 0 Wegpunkten trotz zuvor bestehender Mission mit Wegpunkten. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
aaec7f0f72
commit
926d805156
@@ -0,0 +1,71 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/testing.dart';
|
||||
|
||||
import 'package:dmc_app/services/geocoding/nominatim_service.dart';
|
||||
|
||||
http.Response _json(Object body) =>
|
||||
http.Response(jsonEncode(body), 200, headers: {
|
||||
'content-type': 'application/json',
|
||||
});
|
||||
|
||||
void main() {
|
||||
group('NominatimService.search', () {
|
||||
test('bevorzugt city aus address gegenueber display_name', () async {
|
||||
final client = MockClient((request) async {
|
||||
expect(request.url.queryParameters['q'], 'Amsterdam');
|
||||
return _json([
|
||||
{
|
||||
'lat': '52.37403',
|
||||
'lon': '4.88969',
|
||||
'display_name': 'Amsterdam, Noord-Holland, Netherlands',
|
||||
'address': {'city': 'Amsterdam', 'county': 'Noord-Holland'},
|
||||
},
|
||||
]);
|
||||
});
|
||||
final service = NominatimService(client: client);
|
||||
|
||||
final result = await service.search('Amsterdam');
|
||||
|
||||
expect(result, isNotNull);
|
||||
expect(result!.label, 'Amsterdam');
|
||||
expect(result.lat, closeTo(52.37403, 0.00001));
|
||||
expect(result.lon, closeTo(4.88969, 0.00001));
|
||||
});
|
||||
|
||||
test('faellt ohne strukturierte Adresse auf display_name zurueck',
|
||||
() async {
|
||||
final client = MockClient((request) async {
|
||||
return _json([
|
||||
{
|
||||
'lat': '1.0',
|
||||
'lon': '2.0',
|
||||
'display_name': 'Somewhere Remote, Some Region',
|
||||
'address': <String, dynamic>{},
|
||||
},
|
||||
]);
|
||||
});
|
||||
final service = NominatimService(client: client);
|
||||
|
||||
final result = await service.search('remote place');
|
||||
|
||||
expect(result!.label, 'Somewhere Remote');
|
||||
});
|
||||
|
||||
test('liefert null bei leeren Ergebnissen', () async {
|
||||
final client = MockClient((request) async => _json([]));
|
||||
final service = NominatimService(client: client);
|
||||
|
||||
expect(await service.search('nowhere'), isNull);
|
||||
});
|
||||
|
||||
test('liefert null bei fehlgeschlagenem Request', () async {
|
||||
final client = MockClient((request) async => http.Response('', 500));
|
||||
final service = NominatimService(client: client);
|
||||
|
||||
expect(await service.search('anywhere'), isNull);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user