Private/Testing/Test-ResponseSchema.ps1
|
function Test-ResponseSchema { <# .SYNOPSIS Validates API response against swagger schema definition. .DESCRIPTION Compares the properties in an API response against the expected properties defined in the swagger schema. Reports missing and extra properties. .PARAMETER Response The API response to validate. .PARAMETER SwaggerSchema The swagger schema definition (from Get-SwaggerSchema). .PARAMETER ApiVersion API version for loading swagger file. Default is 'v1'. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [AllowNull()] $Response, [Parameter(Mandatory = $true)] [AllowNull()] $SwaggerSchema, [Parameter()] [ValidateSet('v1', 'v1-beta')] [string]$ApiVersion = 'v1' ) $result = [PSCustomObject]@{ IsValid = $true TotalExpected = 0 TotalFound = 0 MatchingProps = @() MissingProps = @() ExtraProps = @() Message = '' } # Handle null response if ($null -eq $Response) { $result.IsValid = $false $result.Message = 'Response is null' return $result } # Handle null schema if ($null -eq $SwaggerSchema) { $result.Message = 'No swagger schema available for validation' return $result } # Get response properties from first item $responseItems = @($Response) if ($responseItems.Count -eq 0) { $result.Message = 'Response is empty' return $result } $responseProps = @($responseItems[0].PSObject.Properties.Name) # Get expected properties from schema $expectedProps = @() # Load swagger for resolving refs $moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) $swaggerFile = Join-Path $moduleRoot ".swagger" "$ApiVersion.json" $swagger = $null if (Test-Path $swaggerFile) { $swagger = Get-Content $swaggerFile -Raw | ConvertFrom-Json -AsHashtable } # Extract properties from schema if ($SwaggerSchema.ResponseSchema) { $schema = $SwaggerSchema.ResponseSchema # Handle array responses if ($schema.type -eq 'array' -and $schema.items) { $itemSchema = $schema.items if ($itemSchema.'$ref' -and $swagger) { $itemSchema = Resolve-SwaggerRef -Swagger $swagger -Ref $itemSchema.'$ref' } if ($itemSchema.properties) { $expectedProps = @($itemSchema.properties.Keys) } } # Handle object responses elseif ($schema.properties) { $expectedProps = @($schema.properties.Keys) } # Handle $ref at root elseif ($schema.'$ref' -and $swagger) { $resolved = Resolve-SwaggerRef -Swagger $swagger -Ref $schema.'$ref' if ($resolved.properties) { $expectedProps = @($resolved.properties.Keys) } } } # If we couldn't extract expected props, try response example if ($expectedProps.Count -eq 0 -and $SwaggerSchema.ResponseExample) { $example = $SwaggerSchema.ResponseExample if ($example -is [array] -and $example.Count -gt 0) { $expectedProps = @($example[0].PSObject.Properties.Name) } elseif ($example -is [hashtable]) { $expectedProps = @($example.Keys) } } $result.TotalExpected = $expectedProps.Count $result.TotalFound = $responseProps.Count # Compare properties $result.MatchingProps = @($responseProps | Where-Object { $_ -in $expectedProps }) $result.MissingProps = @($expectedProps | Where-Object { $_ -notin $responseProps }) $result.ExtraProps = @($responseProps | Where-Object { $_ -notin $expectedProps }) # Determine validity (missing props = fail, extra props = warning) if ($result.MissingProps.Count -gt 0) { $result.IsValid = $false $result.Message = "Missing $($result.MissingProps.Count) expected properties: $($result.MissingProps -join ', ')" } elseif ($result.ExtraProps.Count -gt 0) { $result.Message = "Found $($result.ExtraProps.Count) extra properties not in schema: $($result.ExtraProps -join ', ')" } else { $result.Message = "All $($result.TotalExpected) expected properties found" } return $result } function Format-SchemaValidation { <# .SYNOPSIS Formats schema validation results for console output. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] $ValidationResult ) $lines = @() if ($ValidationResult.IsValid) { $lines += " Schema: VALID ($($ValidationResult.MatchingProps.Count)/$($ValidationResult.TotalExpected) properties)" } else { $lines += " Schema: INVALID" if ($ValidationResult.MissingProps.Count -gt 0) { $lines += " Missing: $($ValidationResult.MissingProps -join ', ')" } } if ($ValidationResult.ExtraProps.Count -gt 0) { $lines += " Extra: $($ValidationResult.ExtraProps -join ', ')" } return $lines -join "`n" } |