using GitConverter.Lib.Converters; using GitConverter.Lib.Factories; using GitConverter.Lib.Models; namespace GitConverter.TestsApp.Converters { /// /// Unit tests for ConversionService.Run covering: /// - JSON detection path using JsonFormatDetector /// - Extension-based dispatch /// - Unknown extension failure /// public class ConversionServiceTests : IDisposable { private readonly string _tempDir; public ConversionServiceTests() { _tempDir = Path.Combine(Path.GetTempPath(), "GitConverter.ConversionServiceTests", Guid.NewGuid().ToString("N")); Directory.CreateDirectory(_tempDir); } public void Dispose() { try { if (Directory.Exists(_tempDir)) Directory.Delete(_tempDir, true); } catch { } } // Simple fake converter that records invocation and returns success class FakeConverter : IConverter { public bool Invoked { get; private set; } public string LastOption { get; private set; } public ConversionResult Convert(string gisInputFilePath, string gisTargetFormatOption, string outFolderPath, string tempFolderPath) { Invoked = true; LastOption = gisTargetFormatOption; return ConversionResult.Success("ok"); } } // Fake factory that maps a single key to the provided fake converter class FakeFactory : IConverterFactory { private readonly string _key; private readonly IConverter _conv; public FakeFactory(string key, IConverter conv) { _key = key; _conv = conv; } // Not used by these tests; implement if needed by future tests. public IConverter Create(string formatOption) => throw new NotImplementedException(); public bool TryCreate(string formatOption, out IConverter converter) { if (string.Equals(formatOption, _key, StringComparison.OrdinalIgnoreCase)) { converter = _conv; return true; } converter = null; return false; } public IReadOnlyCollection GetSupportedOptions() => new[] { _key }; } [Fact(DisplayName = "Run_DetectsJson_GeoJson_and_invokes_converter")] public void Run_DetectsJson_GeoJson_and_invokes_converter() { // Arrange: create a small geojson file var json = @"{ ""type"": ""FeatureCollection"", ""features"": [] }"; var input = Path.Combine(_tempDir, "in.json"); File.WriteAllText(input, json); var outFolder = Path.Combine(_tempDir, "out"); var tempFolder = Path.Combine(_tempDir, "tmp"); var fake = new FakeConverter(); var factory = new FakeFactory("GeoJson", fake); // Act var result = ConversionService.Run(input, outFolder, tempFolder, factory); // Assert Assert.NotNull(result); Assert.True(result.IsSuccess, "Conversion should succeed using GeoJson converter"); Assert.True(fake.Invoked, "Fake converter should have been invoked"); Assert.Equal("GeoJson", fake.LastOption); } [Fact(DisplayName = "Run_UsesExtensionMapping_for_nonJson")] public void Run_UsesExtensionMapping_for_nonJson() { // Arrange: .shp single-file (we don't require file contents here, just mapping) var input = Path.Combine(_tempDir, "file.shp"); File.WriteAllText(input, "dummy"); // presence is enough for mapping path var outFolder = Path.Combine(_tempDir, "out2"); var tempFolder = Path.Combine(_tempDir, "tmp2"); var fake = new FakeConverter(); var factory = new FakeFactory("Shapefile", fake); // Act var result = ConversionService.Run(input, outFolder, tempFolder, factory); // Assert Assert.NotNull(result); Assert.True(result.IsSuccess, "Conversion should succeed using Shapefile converter"); Assert.True(fake.Invoked); Assert.Equal("Shapefile", fake.LastOption); } [Fact(DisplayName = "Run_ReturnsFailure_OnUnknownExtension")] public void Run_ReturnsFailure_OnUnknownExtension() { // Arrange: unknown extension var input = Path.Combine(_tempDir, "file.unknownext"); File.WriteAllText(input, "dummy"); var outFolder = Path.Combine(_tempDir, "out3"); var tempFolder = Path.Combine(_tempDir, "tmp3"); // Use a factory that doesn't resolve the unknown extension var result = ConversionService.Run(input, outFolder, tempFolder, factory: new FakeFactory("DoesNotMatch", new FakeConverter())); // Assert Assert.NotNull(result); Assert.False(result.IsSuccess); } } }