tests/LocalPilot.Tests.ps1

BeforeAll {
    $ModuleManifestPath = Join-Path -Path $PSScriptRoot -ChildPath '..\LocalPilot.psd1'
    Import-Module -Name $ModuleManifestPath -Force
}

Describe 'LocalPilot Module Packaging' {
    It 'Passes Test-ModuleManifest' {
        $manifest = Test-ModuleManifest -Path $ModuleManifestPath
        $manifest | Should -Not -BeNullOrEmpty
        $manifest.Version | Should -Be ([version]'1.0.0')
        $manifest.Author | Should -Be 'Matthew Bubb'
    }

    It 'Exports all expected public functions' {
        $expectedFunctions = @(
            'Get-LocalPilotRecipe',
            'Invoke-LocalPilot',
            'New-WorkstationBirthCertificate',
            'Invoke-LocalRemediation',
            'Register-LocalRemediation'
        )
        foreach ($fn in $expectedFunctions) {
            Get-Command -Name $fn -Module 'LocalPilot' | Should -Not -BeNullOrEmpty
        }
    }

    It 'Exports aliases Start-LocalPilot and Test-EndpointDrift' {
        (Get-Alias -Name 'Start-LocalPilot').Definition | Should -Be 'Invoke-LocalPilot'
        (Get-Alias -Name 'Test-EndpointDrift').Definition | Should -Be 'Invoke-LocalRemediation'
    }
}

Describe 'Get-LocalPilotRecipe' {
    It 'Returns the DevWorkstation blueprint with expected properties' {
        $recipe = Get-LocalPilotRecipe -Persona 'DevWorkstation'
        $recipe.Name | Should -Be 'DevWorkstation'
        $recipe.Debloat | Should -Be $true
        $recipe.HardenPrivacy | Should -Be $true
        $recipe.WingetPackages | Should -Contain 'Git.Git'
    }

    It 'Exports template as valid JSON' {
        $json = Get-LocalPilotRecipe -ExportTemplate
        $parsed = $json | ConvertFrom-Json
        $parsed.Name | Should -Be 'DevWorkstation'
    }
}

Describe 'New-WorkstationBirthCertificate' {
    It 'Generates structured hardware audit object with SHA-256 fingerprint' {
        $cert = New-WorkstationBirthCertificate -PassThru
        $cert | Should -Not -BeNullOrEmpty
        $cert.ComputerName | Should -Be $env:COMPUTERNAME
        $cert.HardwareFingerprint.Length | Should -Be 64
        $cert.OperatingSystem.Caption | Should -Not -BeNullOrEmpty
    }

    It 'Generates a valid Markdown report file' {
        $testMdPath = Join-Path -Path $TestDrive -ChildPath 'CertTest.md'
        New-WorkstationBirthCertificate -OutputPath $testMdPath
        Test-Path -Path $testMdPath | Should -Be $true
        $content = Get-Content -Path $testMdPath -Raw
        $content | Should -Match 'Workstation Birth Certificate'
        $content | Should -Match 'Hardware Fingerprint'
    }
}

Describe 'Invoke-LocalRemediation' {
    It 'Identifies a compliant endpoint when exit code is 0' {
        $result = Invoke-LocalRemediation -Name 'TestPass' -DetectionScript { exit 0 }
        $result.Status | Should -Be 'Compliant'
        $result.Compliant | Should -Be $true
        $result.InitialExitCode | Should -Be 0
        $result.RemediationExecuted | Should -Be $false
    }

    It 'Identifies a non-compliant endpoint when exit code is 1' {
        $result = Invoke-LocalRemediation -Name 'TestFail' -DetectionScript { exit 1 }
        $result.Status | Should -Be 'NonCompliant'
        $result.Compliant | Should -Be $false
        $result.InitialExitCode | Should -Be 1
        $result.RemediationExecuted | Should -Be $false
    }

    It 'Executes remediation and verifies drift resolution' {
        $result = Invoke-LocalRemediation -Name 'TestFix' `
            -DetectionScript { exit 1 } `
            -RemediationScript { exit 0 } `
            -Remediate
        $result.Status | Should -Be 'Remediated'
        $result.RemediationExecuted | Should -Be $true
        $result.RemediationExitCode | Should -Be 0
    }
}

Describe 'Invoke-LocalPilot' {
    It 'Runs with -WhatIf without throwing' {
        { Invoke-LocalPilot -Persona HomelabVM -WhatIf } | Should -Not -Throw
    }
}