Private/Generator/Tests/Get-OpenApiGenParameterType.Tests.ps1
|
BeforeAll { $env:TCS_CONFIG_ROOT = Join-Path -Path $TestDrive -ChildPath 'config' $env:TCS_SKIP_UPDATE_CHECK = '1' $env:TCS_TELEMETRY_OPTOUT = '1' $ModuleRoot = Split-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -Parent Import-Module -Name (Join-Path -Path $ModuleRoot -ChildPath 'tcs.openapi.psd1') -Force $RepoRoot = Split-Path -Path (Split-Path -Path $ModuleRoot -Parent) -Parent . (Join-Path -Path $RepoRoot -ChildPath 'tests/Helpers/New-TestOpenApiModel.ps1') } Describe 'Get-OpenApiGenParameterType' { BeforeAll { function Get-TestType { param($Schema, [string]$In = 'query', [switch]$Required, $Example) InModuleScope tcs.openapi -Parameters @{ Schema = $Schema; In = $In; Required = [bool]$Required; Example = $Example } { param($Schema, $In, $Required, $Example) Get-OpenApiGenParameterType -Schema $Schema -In $In -Required:$Required -Example $Example } } } It 'maps <Type>/<Format> to [<Expected>]' -TestCases @( @{ Type = 'string'; Format = ''; Expected = 'string' } @{ Type = 'string'; Format = 'date-time'; Expected = 'datetime' } @{ Type = 'string'; Format = 'binary'; Expected = 'object' } @{ Type = 'integer'; Format = 'int32'; Expected = 'int' } @{ Type = 'integer'; Format = 'int64'; Expected = 'long' } @{ Type = 'integer'; Format = ''; Expected = 'long' } @{ Type = 'number'; Format = 'float'; Expected = 'double' } @{ Type = 'object'; Format = ''; Expected = 'hashtable' } @{ Type = ''; Format = ''; Expected = 'object' } ) { param($Type, $Format, $Expected) (Get-TestType -Schema (New-TestSchema -Type $Type -Format $Format)).TypeName | Should -Be $Expected } It 'maps arrays to element arrays' { (Get-TestType -Schema (New-TestSchema -Type array -Items (New-TestSchema -Type integer -Format int32))).TypeName | Should -Be 'int[]' (Get-TestType -Schema (New-TestSchema -Type array -Items (New-TestSchema -Type object))).TypeName | Should -Be 'hashtable[]' (Get-TestType -Schema (New-TestSchema -Type array -Items (New-TestSchema -Type array))).TypeName | Should -Be 'object[]' (Get-TestType -Schema (New-TestSchema -Type array)).TypeName | Should -Be 'object[]' } It 'uses [switch] for optional booleans and [bool] for required and path booleans' { $boolean = New-TestSchema -Type boolean (Get-TestType -Schema $boolean -In query).TypeName | Should -Be 'switch' (Get-TestType -Schema $boolean -In header).IsSwitch | Should -BeTrue (Get-TestType -Schema $boolean -In query -Required).TypeName | Should -Be 'bool' (Get-TestType -Schema $boolean -In path -Required).TypeName | Should -Be 'bool' } It 'maps oneOf to [object]' { (Get-TestType -Schema (New-TestSchema -OneOf @((New-TestSchema -Type string), (New-TestSchema -Type integer)))).TypeName | Should -Be 'object' } It 'adds [AllowNull()] for nullable schemas' { (Get-TestType -Schema (New-TestSchema -Type string -Nullable)).Attributes | Should -Contain '[AllowNull()]' } It 'adds ValidateSet for enums, also for array items' { (Get-TestType -Schema (New-TestSchema -Type string -Enum @('a', "it's"))).Attributes | Should -Contain "[ValidateSet('a', 'it''s')]" (Get-TestType -Schema (New-TestSchema -Type array -Items (New-TestSchema -Type string -Enum @('x', 'y')))).Attributes | Should -Contain "[ValidateSet('x', 'y')]" (Get-TestType -Schema (New-TestSchema -Type integer -Format int32 -Enum @(1, 2))).Attributes | Should -Contain "[ValidateSet('1', '2')]" } It 'adds a case-sensitive ValidatePattern and skips an invalid pattern' { (Get-TestType -Schema (New-TestSchema -Type string -Pattern '^[a-z]+$')).Attributes | Should -Contain "[ValidatePattern('^[a-z]+$', Options = 'None')]" (Get-TestType -Schema (New-TestSchema -Type string -Pattern '([a-z')).Attributes.Count | Should -Be 0 } It 'adds ValidateLength from minLength and maxLength' { (Get-TestType -Schema (New-TestSchema -Type string -MinLength 1 -MaxLength 5)).Attributes | Should -Contain '[ValidateLength(1, 5)]' (Get-TestType -Schema (New-TestSchema -Type string -MaxLength 5)).Attributes | Should -Contain '[ValidateLength(0, 5)]' } It 'adds ValidateRange with literals of one type' { (Get-TestType -Schema (New-TestSchema -Type integer -Format int32 -Minimum 1 -Maximum 100)).Attributes | Should -Contain '[ValidateRange(1, 100)]' (Get-TestType -Schema (New-TestSchema -Type integer -Format int32 -Minimum 1)).Attributes | Should -Contain '[ValidateRange(1, 2147483647)]' (Get-TestType -Schema (New-TestSchema -Type integer -Minimum 0)).Attributes | Should -Contain '[ValidateRange(0l, 9223372036854775807l)]' (Get-TestType -Schema (New-TestSchema -Type number -Minimum 0 -Maximum 1.5)).Attributes | Should -Contain '[ValidateRange(0.0, 1.5)]' } It 'reads exclusive bounds as a flag or as the bound' { $flag = New-TestSchema -Type integer -Format int32 -Minimum 1 -Maximum 10 $flag | Add-Member -NotePropertyName ExclusiveMinimum -NotePropertyValue $true $flag | Add-Member -NotePropertyName ExclusiveMaximum -NotePropertyValue $false (Get-TestType -Schema $flag).Attributes | Should -Contain '[ValidateRange(2, 10)]' $bound = New-TestSchema -Type integer -Format int32 $bound | Add-Member -NotePropertyName ExclusiveMinimum -NotePropertyValue 0 $bound | Add-Member -NotePropertyName ExclusiveMaximum -NotePropertyValue 5 (Get-TestType -Schema $bound).Attributes | Should -Contain '[ValidateRange(1, 4)]' } It 'uses the schema example when the parameter has none' { $schema = New-TestSchema -Type string $schema | Add-Member -NotePropertyName Example -NotePropertyValue 'from-schema' (Get-TestType -Schema $schema).ExampleText | Should -Be "'from-schema'" } It 'looks up a schema stub without a type in the schema map and keeps its nullable flag' { $stub = New-TestSchema -RefName 'Address' -Nullable $schemas = [ordered]@{ Address = (New-TestSchema -Type object -RefName 'Address' -Properties ([ordered]@{ city = New-TestSchema -Type string })) } $type = InModuleScope tcs.openapi -Parameters @{ Schema = $stub; Schemas = $schemas } { param($Schema, $Schemas) Get-OpenApiGenParameterType -Schema $Schema -In 'body' -Schemas $Schemas } $type.TypeName | Should -Be 'hashtable' $type.Attributes | Should -Contain '[AllowNull()]' $arrayType = InModuleScope tcs.openapi -Parameters @{ Schema = (New-TestSchema -Type array -Items (New-TestSchema -RefName 'Address')); Schemas = $schemas } { param($Schema, $Schemas) Get-OpenApiGenParameterType -Schema $Schema -In 'body' -Schemas $Schemas } $arrayType.TypeName | Should -Be 'hashtable[]' } It 'adds ValidateCount from minItems and maxItems' { (Get-TestType -Schema (New-TestSchema -Type array -Items (New-TestSchema -Type string) -MinItems 1 -MaxItems 3)).Attributes | Should -Contain '[ValidateCount(1, 3)]' } It 'produces validation attributes that bind' { $schemas = @( (New-TestSchema -Type integer -Format int32 -Minimum 1 -Maximum 100), (New-TestSchema -Type integer -Maximum 5), (New-TestSchema -Type number -Minimum -1.5), (New-TestSchema -Type string -Pattern '^a' -MinLength 1), (New-TestSchema -Type array -Items (New-TestSchema -Type string -Enum @('a')) -MaxItems 2) ) foreach ($schema in $schemas) { $type = Get-TestType -Schema $schema $source = "function Test-Bind { param($($type.Attributes -join ' ') [$($type.TypeName)]`$Value) }" $block = [scriptblock]::Create($source) { . $block; (Get-Command -Name Test-Bind).Parameters.Count } | Should -Not -Throw } } It 'builds an example from Example, enum or type' { (Get-TestType -Schema (New-TestSchema -Type string) -Example 'abc').ExampleText | Should -Be "'abc'" (Get-TestType -Schema (New-TestSchema -Type string -Enum @('open'))).ExampleText | Should -Be "'open'" (Get-TestType -Schema (New-TestSchema -Type integer)).ExampleText | Should -Be '1' (Get-TestType -Schema (New-TestSchema -Type string -Format date-time)).ExampleText | Should -Be '(Get-Date)' (Get-TestType -Schema (New-TestSchema -Type array -Items (New-TestSchema -Type string))).ExampleText | Should -Be "@('example')" (Get-TestType -Schema (New-TestSchema -Type boolean) -Required).ExampleText | Should -Be '$true' (Get-TestType -Schema (New-TestSchema -Type boolean)).ExampleText | Should -BeNullOrEmpty } } |