Tests/VSAModule.CertBypass.Tests.ps1
|
# Certificate-error bypass is edition-sensitive and was the source of a PS 5.1 regression (F-27b): # a PowerShell scriptblock assigned to ServerCertificateValidationCallback cannot run on the TLS # handshake thread, aborting the send ("An unexpected error occurred on a send"). The fix selects a # compiled strategy once at module load, feature-detected on -SkipCertificateCheck. # Computed during Discovery so the -Skip conditions below resolve to the running edition's path. $script:SupportsSkip = (Get-Command Invoke-RestMethod).Parameters.ContainsKey('SkipCertificateCheck') BeforeAll { $script:ModuleRoot = Split-Path -Path (Split-Path -Parent $PSCommandPath) Import-Module (Join-Path $script:ModuleRoot 'VSAModule.psd1') -Force } Describe "Certificate-bypass strategy is compiled, feature-detected, and edition-correct (F-27b)" { Context "source guarantees (platform-independent)" { It "no transport file assigns a PowerShell scriptblock to ServerCertificateValidationCallback" { foreach ($file in @('private/Get-RequestData.ps1', 'private/Invoke-VSAHttp.ps1', 'private/Invoke-VSAParallelRequest.ps1')) { $src = Get-Content -Path (Join-Path $script:ModuleRoot $file) -Raw $src | Should -Not -Match 'ServerCertificateValidationCallback\s*=\s*\{' -Because "$file must not hand a scriptblock to the TLS handshake thread (F-27b)" } } It "the Core path carries the bypass on the HttpClientHandler, not a request switch (F-67)" { $src = Get-Content -Path (Join-Path $script:ModuleRoot 'private/Invoke-VSAHttp.ps1') -Raw $src | Should -Match 'ServerCertificateCustomValidationCallback' $src | Should -Match 'DangerousAcceptAnyServerCertificateValidator' } It "the Framework path uses a compiled ICertificatePolicy type, not a scriptblock" { $psm1 = Get-Content -Path (Join-Path $script:ModuleRoot 'VSAModule.psm1') -Raw $psm1 | Should -Match 'class VSATrustAllCertificatePolicy\s*:\s*ICertificatePolicy' } It "the strategy is feature-detected on -SkipCertificateCheck, not an edition/version label" { $psm1 = Get-Content -Path (Join-Path $script:ModuleRoot 'VSAModule.psm1') -Raw $psm1 | Should -Match "Parameters\.ContainsKey\('SkipCertificateCheck'\)" } } Context "load-time selection" { It "exposes the two push/pop strategy scriptblocks" { InModuleScope VSAModule { $script:VSAPushCertBypass | Should -BeOfType ([scriptblock]) $script:VSAPopCertBypass | Should -BeOfType ([scriptblock]) } } It "no longer carries the retired request-splat strategy (F-67)" { # VSAAddSkipCertCheck existed only to add -SkipCertificateCheck to an Invoke-RestMethod # splat. The module transports over HttpClient now, so it is dead and was removed. InModuleScope VSAModule { Get-Variable -Name 'VSAAddSkipCertCheck' -Scope Script -ErrorAction SilentlyContinue | Should -BeNullOrEmpty } } } Context "PowerShell 7 / .NET Core runtime (handler validator)" -Skip:(-not $script:SupportsSkip) { It "push/pop are no-ops: Core ignores the process-global policy, so nothing is touched" { InModuleScope VSAModule { $before = [System.Net.ServicePointManager]::CertificatePolicy & $script:VSAPushCertBypass [System.Net.ServicePointManager]::CertificatePolicy | Should -Be $before & $script:VSAPopCertBypass [System.Net.ServicePointManager]::CertificatePolicy | Should -Be $before } } It "does not compile the Framework-only trust-all policy type" { ('VSATrustAllCertificatePolicy' -as [type]) | Should -BeNullOrEmpty } } Context "Windows PowerShell 5.1 / .NET Framework runtime (compiled policy)" -Skip:$script:SupportsSkip { It "push installs the compiled trust-all policy and pop restores the previous one" { InModuleScope VSAModule { ('VSATrustAllCertificatePolicy' -as [type]) | Should -Not -BeNullOrEmpty $before = [System.Net.ServicePointManager]::CertificatePolicy & $script:VSAPushCertBypass [System.Net.ServicePointManager]::CertificatePolicy | Should -BeOfType ([VSATrustAllCertificatePolicy]) & $script:VSAPopCertBypass [System.Net.ServicePointManager]::CertificatePolicy | Should -Be $before } } } } |