tests/Uninstaller.Tests.ps1

$moduleRoot = Split-Path -Parent $PSScriptRoot
Import-Module (Join-Path $moduleRoot 'Octa.psd1') -Force
# Get-OctaInstalledPrograms is an internal helper (not in FunctionsToExport) - dot-source
# directly for white-box testing, same pattern Categories.Tests.ps1 already uses.
. (Join-Path $moduleRoot 'public\Invoke-OctaUninstaller.ps1')

Describe 'Get-OctaInstalledPrograms' {
    It 'lists real installed programs without throwing (dry read only)' {
        { Get-OctaInstalledPrograms } | Should Not Throw
        $programs = @(Get-OctaInstalledPrograms)
        $programs.Count | Should BeGreaterThan 0
        $programs[0].DisplayName | Should Not BeNullOrEmpty
    }
}

Describe 'Invoke-OctaUninstaller' {
    It 'lists without mutating anything when called with no parameters' {
        { Invoke-OctaUninstaller } | Should Not Throw
    }

    It 'reports NotFound for a program that does not exist, without attempting anything' {
        $result = Invoke-OctaUninstaller -Remove 'ThisProgramDoesNotExist12345'
        $result.Status | Should Be 'NotFound'
    }

    It 'reports NothingToClean when there is no recent uninstall marker' {
        $markerPath = Join-Path $env:LOCALAPPDATA 'Octa\last-uninstall.json'
        Remove-Item -Path $markerPath -Force -ErrorAction SilentlyContinue
        $result = Invoke-OctaUninstaller -CleanLeftovers -Yes
        $result.Status | Should Be 'NothingToClean'
    }

    It '-CleanLeftovers (009/Kudu parity) only checks app-data folders matching the exact Publisher/DisplayName of the specific program just uninstalled - not a generic scan' {
        # research.md: a generic LOCALAPPDATA/APPDATA/PROGRAMDATA scan against ALL installed
        # programs was tested against real data and found unsafe (false-positives on active
        # software). This confirms the narrower, safe replacement: only the one known name.
        $publisherFolder = Join-Path $env:LOCALAPPDATA 'OctaPesterTestPublisher'
        New-Item -ItemType Directory -Path $publisherFolder -Force | Out-Null
        $markerPath = Join-Path $env:LOCALAPPDATA 'Octa\last-uninstall.json'
        [pscustomobject]@{
            DisplayName     = 'Octa Pester Test Program'
            Publisher       = 'OctaPesterTestPublisher'
            InstallLocation = $null
        } | ConvertTo-Json | Set-Content -Path $markerPath -Encoding utf8

        try {
            $result = Invoke-OctaUninstaller -CleanLeftovers -Yes
            $result.Status | Should Be 'Success'
            ($result.Removed.Path -contains $publisherFolder) | Should Be $true
            (Test-Path $publisherFolder) | Should Be $false
        }
        finally {
            Remove-Item -Path $publisherFolder -Recurse -Force -ErrorAction SilentlyContinue
            Remove-Item -Path $markerPath -Force -ErrorAction SilentlyContinue
        }
    }
}