internal/ConvertTo-MyCorpResult.ps1

<#
.SYNOPSIS
    Converts Pester results into the MyCorp result model.
.DESCRIPTION
    Rebranded, signature-free version of ConvertTo-MtMyCorpResult.
    Hybrid rule applied:
       - Public function renamed → ConvertTo-MyCorpResult
       - Mt-internal helper functions preserved
       - Uses $__MyCorpSession instead of $__MtSession
#>


function ConvertTo-MyCorpResult {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [psobject] $PesterResults
    )

    # --- Local helper functions (internal private scope) ---

    function GetTenantName() {
        if (Test-MtConnection Graph) {
            $org = Invoke-MtGraphRequest -RelativeUri 'organization'
            return $org.DisplayName
        } elseif (Test-MtConnection Teams) {
            $tenant = Get-CsTenant
            return $tenant.DisplayName
        } else {
            return "TenantName (not connected to Graph)"
        }
    }

    function GetTenantId() {
        if (Test-MtConnection Graph) {
            return (Get-MgContext).TenantId
        } elseif (Test-MtConnection Teams) {
            return (Get-CsTenant).TenantId
        } else {
            return "TenantId (not connected to Graph)"
        }
    }

    function GetAccount() {
        if (Test-MtConnection Graph) {
            return (Get-MgContext).Account
        } else {
            return "Account (not connected to Graph)"
        }
    }

    function GetTestsSorted() {
        $active = $PesterResults.Tests |
            Where-Object { $_.Result -in 'Passed','Failed' } |
            Sort-Object -Property Name

        $inactive = $PesterResults.Tests |
            Where-Object { $_.Result -notin 'Passed','Failed' } |
            Sort-Object -Property Name

        return @($active) + @($inactive)
    }

    function GetFormattedDate($date) {
        if (!$IsCoreCLR) {
            return $date.ToString("o")
        }
        return $date
    }

    function GetLatestMyCorpVersion() {
        if (Get-Command 'Find-Module' -ErrorAction SilentlyContinue) {
            try { return (Find-Module -Name MyCorp).Version } catch { }
        }
        return 'Unknown'
    }

    # --- Gather contextual details ---

    $tenantId   = GetTenantId
    $tenantName = GetTenantName
    $account    = GetAccount

    # Module version tracking
    $currentVersion = ((Get-Module -Name MyCorp).Version | Select-Object -Last 1).ToString()
    $latestVersion  = GetLatestMyCorpVersion

    $sortedTests = GetTestsSorted
    $testsOut = @()
    $blocksOut = @()

    $testIndex = 0
    $timeSpanFormat = 'hh\:mm\:ss'

    foreach ($test in $sortedTests) {
        $testIndex++
        $name = $test.ExpandedName

        # custom naming override
        $customName = $__MyCorpSession.TestResultDetail[$test.ExpandedName].TestTitle
        if ($customName) { $name = $customName }

        # help URL extraction
        $helpUrl = ''
        $start = $name.IndexOf("See https")
        if ($start -gt 0) {
            $helpUrl = $name.Substring($start + 4).Trim()
            $name = $name.Substring(0, $start).Trim()
        }

        # TestId: Title parsing
        $titleStart = $name.IndexOf(':')
        $testId = $name
        $testTitle = $name
        if ($titleStart -gt 0) {
            $testId    = $name.Substring(0, $titleStart).Trim()
            $testTitle = $name.Substring($titleStart + 1).Trim()
        } else {
            Write-Warning "Test name missing ':' → $name"
        }

        $detail = $__MyCorpSession.TestResultDetail[$test.ExpandedName]
        $testSetting = Get-MtMyCorpConfigTestSetting -TestId $testId

        $severity = $detail.Severity
        if ($testSetting -and $testSetting.Severity) {
            $severity = $testSetting.Severity
        }

        $testsOut += [PSCustomObject]@{
            Index           = $testIndex
            Id              = $testId
            Title           = $testTitle
            Name            = $name
            HelpUrl         = $helpUrl
            Severity        = $severity
            Tag             = @($test.Block.Tag + $test.Tag | Select-Object -Unique)
            Result          = $test.Result
            ScriptBlock     = $test.ScriptBlock.ToString()
            ScriptBlockFile = $test.ScriptBlock.File
            ErrorRecord     = $test.ErrorRecord
            Block           = $test.Block.ExpandedName
            Duration        = $test.Duration.ToString($timeSpanFormat)
            ResultDetail    = $detail
        }
    }

    # --- Aggregate blocks ---
    foreach ($container in $PesterResults.Containers) {
        foreach ($block in $container.Blocks) {
            $existing = $blocksOut | Where-Object { $_.Name -eq $block.Name }

            if (-not $existing) {
                $blocksOut += [PSCustomObject]@{
                    Name         = $block.Name
                    Result       = $block.Result
                    FailedCount  = $block.FailedCount
                    PassedCount  = $block.PassedCount
                    SkippedCount = $block.SkippedCount
                    NotRunCount  = $block.NotRunCount
                    TotalCount   = $block.TotalCount
                    Tag          = $block.Tag
                }
            } else {
                $existing.FailedCount  += $block.FailedCount
                $existing.PassedCount  += $block.PassedCount
                $existing.SkippedCount += $block.SkippedCount
                $existing.NotRunCount  += $block.NotRunCount
                $existing.TotalCount   += $block.TotalCount
            }
        }
    }

    # --- Final composed result model ---

    $result = [PSCustomObject]@{
        Result            = $PesterResults.Result
        FailedCount       = $PesterResults.FailedCount
        PassedCount       = $PesterResults.PassedCount
        SkippedCount      = $PesterResults.SkippedCount
        TotalCount        = $PesterResults.TotalCount
        ExecutedAt        = GetFormattedDate($PesterResults.ExecutedAt)
        TotalDuration     = $PesterResults.Duration.ToString($timeSpanFormat)
        UserDuration      = $PesterResults.UserDuration.ToString($timeSpanFormat)
        DiscoveryDuration = $PesterResults.DiscoveryDuration.ToString($timeSpanFormat)
        FrameworkDuration = $PesterResults.FrameworkDuration.ToString($timeSpanFormat)
        TenantId          = $tenantId
        TenantName        = $tenantName
        Account           = $account
        CurrentVersion    = $currentVersion
        LatestVersion     = $latestVersion
        Tests             = $testsOut
        Blocks            = $blocksOut
    }

    return $result
}