Tests/Unit/Private/Resolve-SCAError.Tests.ps1
|
Import-Module (Join-Path $PSScriptRoot '../../../psSCA.psd1') -Force Describe 'Resolve-SCAError' { InModuleScope psSCA { BeforeAll { function Get-TestHttpErrorRecord { param([System.Net.HttpStatusCode]$StatusCode, [string]$Body) $responseMessage = [System.Net.Http.HttpResponseMessage]::new($StatusCode) $exception = [Microsoft.PowerShell.Commands.HttpResponseException]::new($StatusCode.ToString(), $responseMessage) $errorRecord = [System.Management.Automation.ErrorRecord]::new( $exception, 'WebCmdletWebResponseException', [System.Management.Automation.ErrorCategory]::InvalidOperation, $null) $errorRecord.ErrorDetails = [System.Management.Automation.ErrorDetails]::new($Body) return $errorRecord } } It 'extracts status code, message, and request id from a CyberArk error body' { $errorRecord = Get-TestHttpErrorRecord -StatusCode 403 -Body '{"message":"Insufficient permissions.","code":"E403","requestId":"req-abc-123"}' $resolved = Resolve-SCAError -ErrorRecord $errorRecord -Service 'SCA' -Operation 'Get-SCAAccessRequest' -Uri 'https://contoso.sca.cyberark.cloud/api/access/sessions' $resolved.Exception.Message | Should -Match 'HTTP Status : 403' $resolved.Exception.Message | Should -Match 'Insufficient permissions\.' $resolved.Exception.Message | Should -Match 'req-abc-123' $resolved.Exception.Message | Should -Match 'Get-SCAAccessRequest' $resolved.CategoryInfo.Category | Should -Be 'PermissionDenied' } It 'maps HTTP status codes to the expected PowerShell error category' { (Resolve-SCAError -ErrorRecord (Get-TestHttpErrorRecord -StatusCode 401 -Body '{"message":"Unauthorized"}') -Service 'SCA' -Operation 'Test' -Uri 'https://x').CategoryInfo.Category | Should -Be 'AuthenticationError' (Resolve-SCAError -ErrorRecord (Get-TestHttpErrorRecord -StatusCode 404 -Body '{"message":"Not found"}') -Service 'SCA' -Operation 'Test' -Uri 'https://x').CategoryInfo.Category | Should -Be 'ObjectNotFound' (Resolve-SCAError -ErrorRecord (Get-TestHttpErrorRecord -StatusCode 429 -Body '{"message":"Rate limited"}') -Service 'SCA' -Operation 'Test' -Uri 'https://x').CategoryInfo.Category | Should -Be 'LimitsExceeded' } It 'redacts bearer-token-shaped text in a non-JSON error body via Protect-SCASecret' { $errorRecord = Get-TestHttpErrorRecord -StatusCode 401 -Body 'Gateway rejected Authorization: Bearer super-secret-token-value' $resolved = Resolve-SCAError -ErrorRecord $errorRecord -Service 'SCA' -Operation 'Test' -Uri 'https://contoso.sca.cyberark.cloud/api/access/sessions' $resolved.Exception.Message | Should -Not -Match 'super-secret-token-value' $resolved.Exception.Message | Should -Match 'REDACTED' } It 'falls back to the exception message when the body is not JSON' { $errorRecord = Get-TestHttpErrorRecord -StatusCode 500 -Body 'Internal Server Error (not JSON)' $resolved = Resolve-SCAError -ErrorRecord $errorRecord -Service 'SCA' -Operation 'Test' -Uri 'https://contoso.sca.cyberark.cloud/api/access/sessions' $resolved.Exception.Message | Should -Match 'Internal Server Error' $resolved.CategoryInfo.Category | Should -Be 'InvalidOperation' } It 'includes the operation, service, and endpoint in the error message' { $errorRecord = Get-TestHttpErrorRecord -StatusCode 403 -Body '{"message":"denied"}' $resolved = Resolve-SCAError -ErrorRecord $errorRecord -Service 'UAP' -Operation 'Get-SCAAccessPolicy' -Uri 'https://contoso.uap.cyberark.cloud/api/policies' $resolved.Exception.Message | Should -Match 'Service : UAP' $resolved.Exception.Message | Should -Match 'Operation : Get-SCAAccessPolicy' $resolved.Exception.Message | Should -Match 'Endpoint : https://contoso.uap.cyberark.cloud/api/policies' } It 'handles a non-HTTP exception (e.g. a connection failure) without a status code' { $exception = [System.Net.Http.HttpRequestException]::new('Connection refused') $errorRecord = [System.Management.Automation.ErrorRecord]::new( $exception, 'ConnectionFailure', [System.Management.Automation.ErrorCategory]::ConnectionError, $null) $resolved = Resolve-SCAError -ErrorRecord $errorRecord -Service 'SCA' -Operation 'Test' -Uri 'https://contoso.sca.cyberark.cloud/api/access/sessions' $resolved.Exception.Message | Should -Not -Match 'HTTP Status' $resolved.Exception.Message | Should -Match 'Connection refused' $resolved.FullyQualifiedErrorId | Should -Be 'psSCA.SCA.Test' $resolved.CategoryInfo.Category | Should -Be 'InvalidOperation' } } } |