# Converters tests — GitConverter.TestsApp.Converters This folder contains unit and integration tests that validate detection, routing and the concrete converter implementations used by the ConsoleApp and `GitConverter.Lib`. Purpose - Verify correct mapping from input artifacts to the appropriate converter implementation (extension mapping, JSON sniffing, archive voting, KMZ detection). - Validate `ConverterUtils` behaviours (path validation, safe archive extraction, zip-slip guards, output path construction and cleanup). - Exercise end-to-end converter behaviour for representative sample artifacts (CSV, Shapefile, GML, KML, GeoJSON) using small `TestData` samples. - Assert logging and diagnostics are emitted at expected levels to aid debugging. Test types - Unit tests - Fast, isolated tests for detection heuristics (`JsonFormatDetector`), factory routing (`ConverterFactory`), and small helper methods in `ConverterUtils`. - Use injected registrations or lightweight fakes for `IConverter` to avoid invoking heavy drivers in unit tests. - Integration tests - End-to-end conversion scenarios that call `ConversionService` or `UniversalGisConverter` and verify output files exist in an `output` folder. - Tests use small files placed under `TestsApp/TestData/` and skip when sample data is absent so CI stays non-fatal. - Gate expensive or licensed tests (Aspose) behind an environment flag or license check. - Logging tests - Use `TestLogger` capture and `LogAssert` helpers to assert tokens at specific `LogLevel` values (Debug/Info/Warn/Error). Key helpers and patterns - Per-test temp roots - Create a unique temp root under `Path.GetTempPath()` per test and delete it in `Dispose()` (best-effort cleanup). This avoids cross-test interference when running tests in parallel. - Registration injection - For unit tests use `new ConverterFactory(registrations, testLogger)` with a small `Dictionary>` to control which converters are available. - Use a `FakeFactory` that records `LastRequestedKey` to assert which converter key the detection code attempted to resolve. - Archive creation - Use `System.IO.Compression.ZipFile` or `ZipArchive` to create small, deterministic zip archives for archive-voting tests. - When testing FileGDB or `.gdb` detection include the base directory in the archive so the `.gdb` folder appears in zip entries (use `ZipFile.CreateFromDirectory(..., includeBaseDirectory: true)` where available). - JSON detection tests - Provide small JSON snippets to exercise fingerprinting for GeoJSON, EsriJSON, TopoJSON and newline-delimited `GeoJsonSeq`. - For archive voting, create zips with multiple JSON entries to validate voting and tiebreakers. Running tests - From IDE - Build the solution and run tests from Test Explorer. - Ensure `GitConverter.ConsoleApp` is built when running CLI/Program tests so reflection-based `Program` probes find the assembly. - CLI - `dotnet build` - `dotnet test ./GitConverter.TestsApp/GitConverter.TestsApp.csproj` - Run a single test - Use your test runner or `dotnet test --filter` to run a specific test by name. Integration gating and licensing - Gate integration tests that require an Aspose license or large proprietary samples behind an opt-in environment variable such as `GITCONVERTER_ENABLE_INTEGRATION=1`. - Prefer provisioning license files via CI secrets and check `AsposeLicenseManager.ApplyLicense()` in tests that require licensed behavior. Skip tests when license is not available. Assertions and resilience - Prefer presence checks and stable tokens - Assert that at least one output file with the expected extension exists instead of exact filename matching. - Use `FileExtensionHelpers.ToDotExtension(...)` to compute expected extensions in tests. - For messages and logs use case-insensitive `Contains` on stable substrings rather than asserting full message equality. - Be tolerant of implementation wording changes - When asserting failure messages prefer checking for a small set of plausible keywords (e.g., "archive", "missing", "invalid") so tests remain robust to non-functional text changes. Debugging failing tests - Capture both `Console.Out` and `Console.Error` and the `TestLogger` messages; combine them when investigating failures. - For CLI/Program tests that report "no Program type found" inspect the probe diagnostics which list all locations the helper searched. - Attach captured stdout/stderr and `TestLogger` output when filing issues. Adding a new converter or tests 1. Implement and register the converter - Add an `IConverter` implementation and register it in `ConverterFactory` (or inject via the constructor for tests). 2. Update mapping helpers - Add file extension mappings to `FileExtensionHelpers` and driver mapping in `ConverterUtils.ConversionOptionToDriver`. 3. Add unit tests - Add detection/factory tests covering the new format option and any JSON fingerprints if relevant. 4. Add integration tests and samples - Place small sample(s) under `TestsApp/TestData/` and mark them in the test project with `PreserveNewest`. - Add a gated integration test that converts the sample and asserts output files exist. CI guidance - Keep the majority of tests fast and non-licensed so main CI runs quickly. - Run licensed integration tests in separate pipelines or matrix jobs that provision required secrets and samples. Troubleshooting checklist - Missing ConsoleApp type - Ensure `GitConverter.ConsoleApp` is built and its assembly is present in probed output directories. - Unexpected test message failures - Prefer broad substring checks; if many tests break because of wording changes update tests to assert stable tokens. - Archive extraction or zip-slip failures - Verify test-created archives have the exact entry paths expected by the detection code and that test zips are not corrupted. Contact - When filing issues include the failing test name, stack trace, combined stdout/stderr, and `TestLogger` output. If relevant, include the small sample file used by the test or its path under `TestData`. This README should be the maintainer reference for working on converter tests. For implementation details look at XML remarks in the helper and test classes for per-method guidance.