Skip to content

Add unit tests for CSV pipeline components #146

@undead2146

Description

@undead2146

Description

As part of EPIC #108, add comprehensive unit tests for CSVDiscoverer, CSVResolver, and CSVContentProvider with multi-language support.

Requirements

• Test discovery for different games and languages
• Test resolution and parsing of unified CSV schema
• Test filtering logic for game types and languages
• Test "All" language entries for shared files
• Mock dependencies as needed
• Ensure coverage for edge cases including multi-language scenarios
• Test language normalization (input any case → uppercase) across provider, discoverer, resolver
• Test LanguageDetector utility (pattern matches, fallbacks)

Acceptance Criteria

  • Unit tests for CSVDiscoverer with game-specific and language-specific discovery (index.json-first; config fallback)
  • Unit tests for CSVResolver with parsing and multi-language filtering
  • Unit tests for CSVContentProvider with pipeline integration and language parameters (normalization)
  • Mock implementations for all external dependencies
  • Edge case testing for invalid data, network failures, unsupported languages
  • Test coverage meets project standards (90%+)
  • All tests pass successfully
  • Multi-language scenarios tested: EN, DE, FR, ES, IT, KO, PL, PT-BR, ZH-CN, ZH-TW
  • "All" language filtering tested for shared files
  • Tests cover size-before-hash optimization and strict mode behavior
  • Tests cover LanguageDetector detection and fallback

Technical Details

  • Components: CSVDiscoverer, CSVResolver, CSVContentProvider
  • Testing Framework: xUnit with Moq
  • Mocking: HttpClient, configuration services, file system
  • Coverage Areas: Discovery, resolution, parsing, filtering, error handling, multi-language support
  • Location: GenHub.Tests/Features/Content/Services/CSVDiscovererTests.cs, CSVResolverTests.cs, CSVContentProviderTests.cs

Test Structure

  • CSVDiscovererTests: index.json parsing, game discovery, configuration fallback, HTTP handling
  • CSVResolverTests: CSV parsing (streaming), filtering logic, fast vs strict
  • CSVContentProviderTests: orchestration, language normalization, DI integration
  • LanguageDetectorTests: directory/file-pattern detection, fallback behavior

Test Scenarios

CSVDiscoverer Tests

[Fact]
public async Task DiscoverAsync_WithGeneralsQuery_ReturnsGeneralsManifest()
{
    // Arrange
    var mockConfig = new Mock<IConfigurationProviderService>();
    mockConfig.Setup(c => c.GetConfigurationValueAsync("CsvValidationCatalogs"))
        .ReturnsAsync(new[] { "https://example.com/generals.csv" });

    var discoverer = new CSVDiscoverer(mockConfig.Object, Mock.Of<ILogger<CSVDiscoverer>>());

    var query = new ContentSearchQuery { TargetGame = GameType.Generals };

    // Act
    var result = await discoverer.DiscoverAsync(query);

    // Assert
    result.IsSuccess.Should().BeTrue();
    result.Data.Should().Contain(r => r.Metadata.ContainsKey("gameType") &&
                                     r.Metadata["gameType"] == "Generals");
}

[Fact]
public async Task DiscoverAsync_WithNetworkFailure_ReturnsFailure()
{
    // Test network failure handling
}

CSVResolver Tests

[Fact]
public async Task ResolveAsync_WithValidCsv_CreatesManifest()
{
    // Arrange
    var mockBuilder = new Mock<IContentManifestBuilder>();
    var mockHttpClient = new Mock<HttpClient>();

    // Mock CSV content
    var csvContent = "relativePath,size,md5,sha256,gameType,gameVersion,language,isRequired\n" +
                    "game.dat,12345,abc123,def456,Generals,1.08,en,true";

    var resolver = new CSVResolver(mockBuilder.Object, Mock.Of<ILogger<CSVResolver>>());

    // Act
    var result = await resolver.ResolveAsync(searchResult);

    // Assert
    result.IsSuccess.Should().BeTrue();
    mockBuilder.Verify(b => b.BuildManifest(It.IsAny<ManifestId>(), It.IsAny<IEnumerable<ManifestFile>>()));
}

[Fact]
public async Task FilterEntriesByGame_WithGeneralsGameType_FiltersCorrectly()
{
    // Test filtering logic for Generals vs Zero Hour
}

CSVContentProvider Tests

[Fact]
public void Constructor_WithValidDependencies_ConfiguresPipeline()
{
    // Arrange
    var mockDiscoverer = new Mock<IContentDiscoverer>();
    var mockResolver = new Mock<IContentResolver>();
    var mockDeliverer = new Mock<IContentDeliverer>();

    // Act
    var provider = new CSVContentProvider(
        mockDiscoverer.Object,
        mockResolver.Object,
        mockDeliverer.Object,
        Mock.Of<ILogger<CSVContentProvider>>());

    // Assert
    provider.Discoverer.Should().Be(mockDiscoverer.Object);
    provider.Resolver.Should().Be(mockResolver.Object);
    provider.Deliverer.Should().Be(mockDeliverer.Object);
}

LanguageDetector Tests

[Fact]
public void DetectLanguage_WithSupportedLanguage_ReturnsLanguage()
{
    // Arrange
    var detector = new LanguageDetector();

    // Act
    var result = detector.DetectLanguage("en-US");

    // Assert
    result.Should().Be("EN");
}

[Fact]
public void DetectLanguage_WithUnsupportedLanguage_ReturnsFallback()
{
    // Arrange
    var detector = new LanguageDetector();

    // Act
    var result = detector.DetectLanguage("xx-YY");

    // Assert
    result.Should().Be("EN"); // Assuming EN is the fallback
}

Mocking Strategy

External Dependencies

  • HttpClient: Mock HTTP responses for CSV downloads
  • IConfigurationProviderService: Mock configuration values
  • IContentManifestBuilder: Mock manifest building
  • File System: Mock file operations for caching

Test Data

  • Valid CSV: Well-formed CSV with all required columns
  • Invalid CSV: Missing columns, malformed data, empty files
  • Network Failures: Timeouts, 404s, connection errors
  • Large Datasets: Performance testing with 80k+ rows

Coverage Goals

  • CSVDiscoverer: 95% coverage

    • Configuration loading
    • HTTP error handling
    • Query parameter processing
    • Result formatting
  • CSVResolver: 95% coverage

    • CSV parsing and validation
    • Game type filtering
    • Language filtering
    • Manifest building
    • Error scenarios
  • CSVContentProvider: 90% coverage

    • Pipeline orchestration
    • Dependency injection
    • Error propagation
    • Configuration handling

Related Files

  • Implementation: CSVDiscoverer.cs, CSVResolver.cs, CSVContentProvider.cs
  • Test base: Existing test patterns in GenHub.Tests
  • Mocking: Moq framework for dependency mocking

Pipeline Flow Integration

This component provides comprehensive testing of the CSV pipeline:

Unit Tests → Mock Pipeline → Test Execution → Validation Results
                              ↑                              ↓
                    (Test scenarios)              (Coverage metrics)

Responsibilities in Pipeline

  1. Component Testing: Test each pipeline component in isolation
  2. Integration Testing: Test pipeline components working together
  3. Mock Coordination: Mock external dependencies (HTTP, config, file system)
  4. Coverage Validation: Ensure all code paths are tested

Testing Flow

  • Input: Test scenarios covering discovery, resolution, and orchestration
  • Mock Setup: Configure mocks for HTTP responses, configuration, and file operations
  • Pipeline Execution: Run tests against mocked pipeline components
  • Output: Test results with coverage metrics and failure analysis

Previous Step

  • CSV Pipeline Components are implemented and registered in DI
  • Components are ready for testing

Next Steps

  • Test Results used to validate pipeline functionality
  • Failed tests indicate issues in pipeline implementation
  • Coverage reports guide additional test development

Metadata

Metadata

Assignees

Labels

Content-PipelineComponents of the content-pipeline systemTestingTopic related to (unit) tests

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions