import 'dart:async'; import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart' as http; import 'package:http/testing.dart'; import 'package:dmc_app/domain/waypoint/flat_waypoint_list.dart'; import 'package:dmc_app/services/terrain/terrain_service.dart'; /// Baut eine 256x256-PNG, deren Pixel alle dieselbe Terrarium-kodierte /// Hoehe tragen - reicht aus, um die komplette Pipeline (HTTP-Fetch, /// PNG-Decodierung, Terrarium-Formel, Relativierung) zu pruefen, ohne dass /// die exakte Pixelposition innerhalb der Kachel eine Rolle spielt. Future _uniformElevationPng(int r, int g, int b) async { const size = 256; final pixels = Uint8List(size * size * 4); for (var i = 0; i < size * size; i++) { pixels[i * 4] = r; pixels[i * 4 + 1] = g; pixels[i * 4 + 2] = b; pixels[i * 4 + 3] = 255; } final completer = Completer(); ui.decodeImageFromPixels( pixels, size, size, ui.PixelFormat.rgba8888, completer.complete, ); final image = await completer.future; final byteData = await image.toByteData(format: ui.ImageByteFormat.png); return byteData!.buffer.asUint8List(); } void main() { TestWidgetsFlutterBinding.ensureInitialized(); const waypoints = [ Waypoint(lat: 48.1351, lon: 11.5820, altitudeM: 60, speedMs: 15, catchRadiusM: 60), Waypoint(lat: 48.1360, lon: 11.5830, altitudeM: 60, speedMs: 15, catchRadiusM: 60), ]; test('fetchProfile decodiert die Terrarium-PNG in relative Hoehen', () async { // R=128, G=100, B=0 -> (128*256 + 100 + 0/256) - 32768 = 100. final pngBytes = await _uniformElevationPng(128, 100, 0); final client = MockClient((request) async => http.Response.bytes(pngBytes, 200)); final service = TerrainService(client: client); final profile = await service.fetchProfile(waypoints); expect(profile, isNotNull); expect(profile!.points, isNotEmpty); // Gleichfoermiges Gelaende: jedes Sample hat dieselbe absolute Hoehe // wie das erste gueltige -> relative Hoehe ueberall 0. for (final p in profile.points) { expect(p.elevationRelM, isNotNull); expect(p.elevationRelM, closeTo(0, 0.01)); } expect(profile.points.first.distanceM, 0); }); test('fetchProfile liefert null, wenn keine Kachel geladen werden kann', () async { final client = MockClient((request) async => http.Response('', 500)); final service = TerrainService(client: client); expect(await service.fetchProfile(waypoints), isNull); }); test('fetchProfile liefert null fuer eine einzelne Wegpunkt-Route', () async { final client = MockClient((request) async => http.Response('', 500)); final service = TerrainService(client: client); expect(await service.fetchProfile([waypoints.first]), isNull); }); }