tests/functions/Import-MtMaesterResult.Tests.ps1

Describe 'Import-MtMaesterResult' {
    BeforeAll {
        # Create a temp directory for test JSON files
        $testDir = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath "MaesterImportTests_$([guid]::NewGuid().ToString('N'))"
        New-Item -Path $testDir -ItemType Directory -Force | Out-Null

        # Single-tenant result object
        $singleTenantData = [PSCustomObject]@{
            TenantId       = 'tenant-1-id'
            TenantName     = 'Tenant One'
            Result         = 'Passed'
            TotalCount     = 10
            PassedCount    = 8
            FailedCount    = 2
            ErrorCount     = 0
            SkippedCount   = 0
            InvestigateCount = 0
            NotRunCount    = 0
            ExecutedAt     = '2026-04-01T10:00:00'
            CurrentVersion = '2.0.0'
            LatestVersion  = '2.0.0'
            Tests          = @(
                [PSCustomObject]@{ Id = 'MT.1001'; Result = 'Passed'; Block = 'Maester' }
                [PSCustomObject]@{ Id = 'MT.1002'; Result = 'Failed'; Block = 'Maester' }
            )
            Blocks         = @(
                [PSCustomObject]@{ Name = 'Maester'; PassedCount = 8; FailedCount = 2; TotalCount = 10 }
            )
            EndOfJson      = 'EndOfJson'
        }

        $singleTenantData2 = [PSCustomObject]@{
            TenantId       = 'tenant-2-id'
            TenantName     = 'Tenant Two'
            Result         = 'Failed'
            TotalCount     = 5
            PassedCount    = 3
            FailedCount    = 2
            ErrorCount     = 0
            SkippedCount   = 0
            InvestigateCount = 0
            NotRunCount    = 0
            ExecutedAt     = '2026-04-01T11:00:00'
            CurrentVersion = '2.0.0'
            LatestVersion  = '2.0.0'
            Tests          = @(
                [PSCustomObject]@{ Id = 'MT.1001'; Result = 'Failed'; Block = 'Maester' }
            )
            Blocks         = @(
                [PSCustomObject]@{ Name = 'Maester'; PassedCount = 3; FailedCount = 2; TotalCount = 5 }
            )
            EndOfJson      = 'EndOfJson'
        }

        # Multi-tenant merged format
        $mergedData = [PSCustomObject]@{
            Tenants        = @($singleTenantData, $singleTenantData2)
            CurrentVersion = '2.0.0'
            LatestVersion  = '2.0.0'
            EndOfJson      = 'EndOfJson'
        }

        # Write test files
        $file1 = Join-Path $testDir 'TestResults-2026-04-01-100000.json'
        $singleTenantData | ConvertTo-Json -Depth 5 | Out-File -FilePath $file1 -Encoding UTF8

        $file2 = Join-Path $testDir 'TestResults-2026-04-01-110000.json'
        $singleTenantData2 | ConvertTo-Json -Depth 5 | Out-File -FilePath $file2 -Encoding UTF8

        $mergedFile = Join-Path $testDir 'merged-results.json'
        $mergedData | ConvertTo-Json -Depth 7 | Out-File -FilePath $mergedFile -Encoding UTF8

        # Write an invalid JSON file
        $invalidFile = Join-Path $testDir 'invalid.json'
        '{ "NotAResult": true }' | Out-File -FilePath $invalidFile -Encoding UTF8

        # Write a malformed file
        $malformedFile = Join-Path $testDir 'malformed.json'
        'this is not json at all' | Out-File -FilePath $malformedFile -Encoding UTF8

        # Create a subdirectory with results (for directory discovery)
        $subDir = Join-Path $testDir 'sub-results'
        New-Item -Path $subDir -ItemType Directory -Force | Out-Null
        $singleTenantData | ConvertTo-Json -Depth 5 | Out-File -FilePath (Join-Path $subDir 'TestResults-2026-04-01-100000.json') -Encoding UTF8

        # Create a custom-named file (not matching TestResults-* pattern)
        $customFile = Join-Path $testDir 'production.json'
        $singleTenantData | ConvertTo-Json -Depth 5 | Out-File -FilePath $customFile -Encoding UTF8
    }

    AfterAll {
        # Clean up temp directory
        if (Test-Path $testDir) {
            Remove-Item -Path $testDir -Recurse -Force
        }
    }

    Context 'Loading single-tenant JSON files' {
        It 'Should load a single file by path' {
            $results = Import-MtMaesterResult -Path $file1

            $results | Should -Not -BeNullOrEmpty
            $results.Count | Should -BeExactly 1
            $results[0].TenantId | Should -BeExactly 'tenant-1-id'
            $results[0].TenantName | Should -BeExactly 'Tenant One'
        }

        It 'Should load multiple files by path' {
            $results = Import-MtMaesterResult -Path $file1, $file2

            $results | Should -Not -BeNullOrEmpty
            $results.Count | Should -BeExactly 2
            $results[0].TenantId | Should -BeExactly 'tenant-1-id'
            $results[1].TenantId | Should -BeExactly 'tenant-2-id'
        }

        It 'Should preserve all properties on loaded results' {
            $results = Import-MtMaesterResult -Path $file1

            $results[0].Tests.Count | Should -BeExactly 2
            $results[0].TotalCount | Should -BeExactly 10
            $results[0].ExecutedAt | Should -Not -BeNullOrEmpty
            $results[0].CurrentVersion | Should -BeExactly '2.0.0'
        }
    }

    Context 'Loading multi-tenant merged JSON' {
        It 'Should auto-expand a merged file into individual tenant results' {
            $results = Import-MtMaesterResult -Path $mergedFile

            $results | Should -Not -BeNullOrEmpty
            $results.Count | Should -BeExactly 2
            $results[0].TenantId | Should -BeExactly 'tenant-1-id'
            $results[1].TenantId | Should -BeExactly 'tenant-2-id'
        }

        It 'Should treat expanded tenants as standalone results' {
            $results = Import-MtMaesterResult -Path $mergedFile

            $results[0].Tests | Should -Not -BeNullOrEmpty
            $results[1].Tests | Should -Not -BeNullOrEmpty
        }
    }

    Context 'Directory discovery' {
        It 'Should discover TestResults-*.json files in a directory' {
            $results = Import-MtMaesterResult -Path $subDir

            $results | Should -Not -BeNullOrEmpty
            $results.Count | Should -BeExactly 1
            $results[0].TenantId | Should -BeExactly 'tenant-1-id'
        }

        It 'Should fall back to all *.json files when no TestResults-* files exist' {
            # Create a directory with only custom-named JSON files
            $customDir = Join-Path $testDir 'custom-names'
            New-Item -Path $customDir -ItemType Directory -Force | Out-Null
            $singleTenantData | ConvertTo-Json -Depth 5 | Out-File -FilePath (Join-Path $customDir 'production.json') -Encoding UTF8
            $singleTenantData2 | ConvertTo-Json -Depth 5 | Out-File -FilePath (Join-Path $customDir 'development.json') -Encoding UTF8

            $results = Import-MtMaesterResult -Path $customDir

            $results | Should -Not -BeNullOrEmpty
            $results.Count | Should -BeExactly 2
        }
    }

    Context 'Glob patterns' {
        It 'Should resolve glob patterns for file paths' {
            $globPattern = Join-Path $testDir 'TestResults-*.json'
            $results = Import-MtMaesterResult -Path $globPattern

            $results | Should -Not -BeNullOrEmpty
            $results.Count | Should -BeExactly 2
        }
    }

    Context 'Validation and error handling' {
        It 'Should skip files missing required properties with a warning' {
            $results = Import-MtMaesterResult -Path $invalidFile -WarningAction SilentlyContinue

            $results.Count | Should -BeExactly 0
        }

        It 'Should skip malformed JSON files with a warning' {
            $results = Import-MtMaesterResult -Path $malformedFile -WarningAction SilentlyContinue

            $results.Count | Should -BeExactly 0
        }

        It 'Should emit an error for nonexistent paths' {
            { Import-MtMaesterResult -Path './nonexistent/path/file.json' -ErrorAction Stop } | Should -Throw
        }
    }

    Context 'Pipeline input' {
        It 'Should accept pipeline input from strings' {
            $results = @($file1, $file2) | Import-MtMaesterResult

            $results | Should -Not -BeNullOrEmpty
            $results.Count | Should -BeExactly 2
        }

        It 'Should accept pipeline input from Get-ChildItem via FullName alias' {
            $results = Get-ChildItem -Path $testDir -Filter 'TestResults-*.json' | Import-MtMaesterResult

            $results | Should -Not -BeNullOrEmpty
            $results.Count | Should -BeExactly 2
        }
    }

    Context 'Integration with Merge-MtMaesterResult' {
        It 'Should pipe directly into Merge-MtMaesterResult' {
            $merged = Import-MtMaesterResult -Path $file1, $file2 | Merge-MtMaesterResult

            $merged | Should -Not -BeNullOrEmpty
            $merged.Tenants | Should -Not -BeNullOrEmpty
            $merged.Tenants.Count | Should -BeExactly 2
            $merged.EndOfJson | Should -BeExactly 'EndOfJson'
        }
    }
}