Tests/Public/Set-PWSHYBKPIVPuk.Tests.ps1

[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '',
    Justification = 'Test fixture values, not real secrets; SecureString-typed parameters require a real SecureString even in unit tests.')]
param()

BeforeAll {
    Import-Module (Resolve-Path "$PSScriptRoot\..\..\Posh-YBKPIV.psd1") -Force

    $script:RealConfigPath = (Resolve-Path "$PSScriptRoot\..\..\Config\Posh-YBKPIV.json").Path
    InModuleScope Posh-YBKPIV -Parameters @{ ConfigPath = $script:RealConfigPath } {
        param($ConfigPath)
        $script:ConfigPath = $ConfigPath
    }

    $script:SecurePuk = ConvertTo-SecureString -String '12345678' -AsPlainText -Force
    $script:SecureNewPuk = ConvertTo-SecureString -String '87654321' -AsPlainText -Force
}

AfterAll {
    Remove-Module Posh-YBKPIV -ErrorAction SilentlyContinue
}

Describe 'Set-PWSHYBKPIVPuk' -Tag Unit {
    BeforeEach {
        $script:InstallExePath = 'C:\Program Files\Yubico\Yubico PIV Tool\bin\yubico-piv-tool.exe'
        Mock -ModuleName Posh-YBKPIV Test-Path { $true } -ParameterFilter { $Path -eq $script:InstallExePath }
        Mock -ModuleName Posh-YBKPIV Resolve-PWSHYBKPIVArchitecture { 'win64' }
        Mock -ModuleName Posh-YBKPIV Get-PWSHYBKPIVInstallPath { $script:InstallExePath }
        Mock -ModuleName Posh-YBKPIV Invoke-PWSHYBKPIVTool { [PSCustomObject]@{ ExitCode = 0; Output = @() } }
    }

    It 'Requires the -Puk and -NewPuk dynamic parameters' {
        { Set-PWSHYBKPIVPuk -Confirm:$false -ErrorAction Stop } | Should -Throw
    }

    It 'Calls Invoke-PWSHYBKPIVTool with the change-puk action when both PUKs are supplied' {
        Set-PWSHYBKPIVPuk -Puk $script:SecurePuk -NewPuk $script:SecureNewPuk -Confirm:$false
        Should -Invoke -ModuleName Posh-YBKPIV Invoke-PWSHYBKPIVTool -Times 1 -ParameterFilter { $Action -eq 'change-puk' }
    }

    It 'Does not attempt the change when -WhatIf is used' {
        Set-PWSHYBKPIVPuk -Puk $script:SecurePuk -NewPuk $script:SecureNewPuk -WhatIf
        Should -Invoke -ModuleName Posh-YBKPIV Invoke-PWSHYBKPIVTool -Times 0
    }

    It 'Throws when Invoke-PWSHYBKPIVTool fails' {
        Mock -ModuleName Posh-YBKPIV Invoke-PWSHYBKPIVTool { throw 'Verify PUK failed' }
        { Set-PWSHYBKPIVPuk -Puk $script:SecurePuk -NewPuk $script:SecureNewPuk -Confirm:$false } | Should -Throw -ExpectedMessage '*Verify PUK failed*'
    }

    It 'Throws a clear error when yubico-piv-tool.exe is not installed' {
        Mock -ModuleName Posh-YBKPIV Test-Path { $false } -ParameterFilter { $Path -eq $script:InstallExePath }
        { Set-PWSHYBKPIVPuk -Puk $script:SecurePuk -NewPuk $script:SecureNewPuk -Confirm:$false } | Should -Throw -ExpectedMessage '*Install-PWSHYBKPIVTool*'
    }
}