using System.Net.Http.Json; using System.Text.Json; namespace SatelliteProvider.IntegrationTests; public static class RegionTests { private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true }; public static async Task RunRegionProcessingTest_200m_Zoom18(HttpClient httpClient) { Console.WriteLine(); Console.WriteLine("Test: Region Processing 200m at Zoom 18"); Console.WriteLine("------------------------------------------------------------------"); const double latitude = 47.461747; const double longitude = 37.647063; const double sizeMeters = 200; const int zoomLevel = 18; const bool stitchTiles = false; await RunRegionProcessingTest(httpClient, latitude, longitude, sizeMeters, zoomLevel, stitchTiles); Console.WriteLine(); Console.WriteLine("Region Processing Test (200m, Zoom 18): PASSED"); } public static async Task RunRegionProcessingTest_400m_Zoom17(HttpClient httpClient) { Console.WriteLine(); Console.WriteLine("Test: Region Processing 400m at Zoom 17"); Console.WriteLine("------------------------------------------------------------------"); const double latitude = 47.461747; const double longitude = 37.647063; const double sizeMeters = 400; const int zoomLevel = 17; const bool stitchTiles = false; await RunRegionProcessingTest(httpClient, latitude, longitude, sizeMeters, zoomLevel, stitchTiles); Console.WriteLine(); Console.WriteLine("Region Processing Test (400m, Zoom 17): PASSED"); } public static async Task RunRegionProcessingTest_500m_Zoom18(HttpClient httpClient) { Console.WriteLine(); Console.WriteLine("Test: Region Processing 500m at Zoom 18 with Stitching"); Console.WriteLine("------------------------------------------------------------------"); const double latitude = 47.461747; const double longitude = 37.647063; const double sizeMeters = 500; const int zoomLevel = 18; const bool stitchTiles = true; await RunRegionProcessingTest(httpClient, latitude, longitude, sizeMeters, zoomLevel, stitchTiles); Console.WriteLine(); Console.WriteLine("Region Processing Test (500m, Zoom 18 with Stitching): PASSED"); } private static async Task RunRegionProcessingTest( HttpClient httpClient, double latitude, double longitude, double sizeMeters, int zoomLevel, bool stitchTiles) { var regionId = Guid.NewGuid(); Console.WriteLine($"Requesting region: ID={regionId}"); Console.WriteLine($" Coordinates: ({latitude}, {longitude})"); Console.WriteLine($" Size: {sizeMeters}m"); Console.WriteLine($" Zoom Level: {zoomLevel}"); Console.WriteLine($" Stitch Tiles: {stitchTiles}"); Console.WriteLine(); var requestRegion = new RequestRegionRequest { Id = regionId, Latitude = latitude, Longitude = longitude, SizeMeters = sizeMeters, ZoomLevel = zoomLevel, StitchTiles = stitchTiles }; var requestResponse = await httpClient.PostAsJsonAsync("/api/satellite/request", requestRegion); if (!requestResponse.IsSuccessStatusCode) { var errorContent = await requestResponse.Content.ReadAsStringAsync(); throw new Exception($"Region request failed with status {requestResponse.StatusCode}: {errorContent}"); } var initialStatus = await requestResponse.Content.ReadFromJsonAsync(JsonOptions); if (initialStatus == null) { throw new Exception("No status returned from region request"); } Console.WriteLine($"✓ Region queued successfully"); Console.WriteLine($" Initial Status: {initialStatus.Status}"); Console.WriteLine(); Console.WriteLine("Polling for region status updates..."); RegionStatusResponse? finalStatus = null; int maxAttempts = 120; for (int i = 0; i < maxAttempts; i++) { await Task.Delay(2000); var statusResponse = await httpClient.GetAsync($"/api/satellite/region/{regionId}"); if (!statusResponse.IsSuccessStatusCode) { var errorContent = await statusResponse.Content.ReadAsStringAsync(); throw new Exception($"Status check failed with status {statusResponse.StatusCode}: {errorContent}"); } var status = await statusResponse.Content.ReadFromJsonAsync(JsonOptions); if (status == null) { throw new Exception("No status returned"); } Console.WriteLine($" Attempt {i + 1}/{maxAttempts}: Status = {status.Status}"); if (status.Status == "completed" || status.Status == "failed") { finalStatus = status; break; } } if (finalStatus == null) { throw new Exception($"Region processing did not complete in time (waited {maxAttempts * 2} seconds)"); } Console.WriteLine(); Console.WriteLine("Region Processing Results:"); Console.WriteLine($" Status: {finalStatus.Status}"); Console.WriteLine($" Tiles Downloaded: {finalStatus.TilesDownloaded}"); Console.WriteLine($" Tiles Reused: {finalStatus.TilesReused}"); Console.WriteLine($" CSV File: {finalStatus.CsvFilePath}"); Console.WriteLine($" Summary File: {finalStatus.SummaryFilePath}"); Console.WriteLine($" Created At: {finalStatus.CreatedAt:yyyy-MM-dd HH:mm:ss}"); Console.WriteLine($" Updated At: {finalStatus.UpdatedAt:yyyy-MM-dd HH:mm:ss}"); if (finalStatus.Status != "completed") { throw new Exception($"Expected status 'completed', got '{finalStatus.Status}'"); } if (string.IsNullOrEmpty(finalStatus.CsvFilePath)) { throw new Exception("CSV file path is empty"); } if (string.IsNullOrEmpty(finalStatus.SummaryFilePath)) { throw new Exception("Summary file path is empty"); } Console.WriteLine(); Console.WriteLine("✓ Region processed successfully"); Console.WriteLine("✓ CSV and summary files created"); } }