using System.Net.Http.Json; using System.Text.Json; namespace SatelliteProvider.IntegrationTests; class Program { private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true }; static async Task Main(string[] args) { var apiUrl = Environment.GetEnvironmentVariable("API_URL") ?? "http://api:8080"; Console.WriteLine("Starting Integration Tests"); Console.WriteLine("========================="); Console.WriteLine($"API URL: {apiUrl}"); Console.WriteLine(); using var httpClient = new HttpClient { BaseAddress = new Uri(apiUrl), Timeout = TimeSpan.FromSeconds(60) }; try { Console.WriteLine("Waiting for API to be ready..."); await WaitForApiReady(httpClient); Console.WriteLine("✓ API is ready"); Console.WriteLine(); await RunSingleTileDownloadTest(httpClient); Console.WriteLine(); Console.WriteLine("========================="); Console.WriteLine("All tests completed successfully!"); return 0; } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("❌ Integration tests failed"); Console.WriteLine($"Error: {ex.Message}"); Console.WriteLine($"Stack trace: {ex.StackTrace}"); return 1; } } static async Task WaitForApiReady(HttpClient httpClient, int maxRetries = 30) { for (int i = 0; i < maxRetries; i++) { try { var response = await httpClient.GetAsync("/"); if (response.IsSuccessStatusCode || response.StatusCode == System.Net.HttpStatusCode.NotFound) { return; } } catch { } Console.WriteLine($" Attempt {i + 1}/{maxRetries} - waiting 2 seconds..."); await Task.Delay(2000); } throw new Exception("API did not become ready in time"); } static async Task RunSingleTileDownloadTest(HttpClient httpClient) { Console.WriteLine("Test: Download Single Tile at Coordinates 47.461747, 37.647063"); Console.WriteLine("------------------------------------------------------------------"); const double latitude = 47.461747; const double longitude = 37.647063; const int zoomLevel = 18; Console.WriteLine($"Downloading tile at coordinates ({latitude}, {longitude}) with zoom level {zoomLevel}"); var request = new DownloadTileRequest { Latitude = latitude, Longitude = longitude, ZoomLevel = zoomLevel }; var response = await httpClient.PostAsJsonAsync("/api/satellite/tiles/download", request); if (!response.IsSuccessStatusCode) { var errorContent = await response.Content.ReadAsStringAsync(); throw new Exception($"API returned error status {response.StatusCode}: {errorContent}"); } var tile = await response.Content.ReadFromJsonAsync(JsonOptions); if (tile == null) { throw new Exception("No tile data returned from API"); } Console.WriteLine(); Console.WriteLine("Tile Details:"); Console.WriteLine($" ID: {tile.Id}"); Console.WriteLine($" Zoom Level: {tile.ZoomLevel}"); Console.WriteLine($" Latitude: {tile.Latitude}"); Console.WriteLine($" Longitude: {tile.Longitude}"); Console.WriteLine($" Tile Size (meters): {tile.TileSizeMeters:F2}"); Console.WriteLine($" Tile Size (pixels): {tile.TileSizePixels}"); Console.WriteLine($" Image Type: {tile.ImageType}"); Console.WriteLine($" Maps Version: {tile.MapsVersion}"); Console.WriteLine($" File Path: {tile.FilePath}"); Console.WriteLine($" Created At: {tile.CreatedAt:yyyy-MM-dd HH:mm:ss}"); if (tile.ZoomLevel != zoomLevel) { throw new Exception($"Expected zoom level {zoomLevel}, got {tile.ZoomLevel}"); } if (string.IsNullOrEmpty(tile.FilePath)) { throw new Exception("File path is empty"); } if (tile.TileSizePixels != 256) { throw new Exception($"Expected tile size 256 pixels, got {tile.TileSizePixels}"); } if (tile.ImageType != "jpg") { throw new Exception($"Expected image type 'jpg', got '{tile.ImageType}'"); } Console.WriteLine(); Console.WriteLine("✓ Tile downloaded successfully"); Console.WriteLine("✓ Tile metadata validated"); Console.WriteLine(); Console.WriteLine("Testing tile reuse (downloading same tile again)..."); var response2 = await httpClient.PostAsJsonAsync("/api/satellite/tiles/download", request); if (!response2.IsSuccessStatusCode) { var errorContent = await response2.Content.ReadAsStringAsync(); throw new Exception($"Second download failed with status {response2.StatusCode}: {errorContent}"); } var tile2 = await response2.Content.ReadFromJsonAsync(JsonOptions); if (tile2 == null) { throw new Exception("No tile data returned from second download"); } Console.WriteLine($"✓ Second download returned tile ID: {tile2.Id}"); Console.WriteLine("✓ Tile reuse functionality working"); Console.WriteLine(); Console.WriteLine("Single Tile Download Test: PASSED"); } } public record DownloadTileRequest { public double Latitude { get; set; } public double Longitude { get; set; } public int ZoomLevel { get; set; } } public record DownloadTileResponse { public Guid Id { get; set; } public int ZoomLevel { get; set; } public double Latitude { get; set; } public double Longitude { get; set; } public double TileSizeMeters { get; set; } public int TileSizePixels { get; set; } public string ImageType { get; set; } = string.Empty; public string? MapsVersion { get; set; } public string FilePath { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } }