Tests/VSAModule.WriteRequest.Tests.ps1
|
BeforeAll { $script:ModuleRoot = Split-Path -Path (Split-Path -Parent $PSCommandPath) Import-Module (Join-Path $script:ModuleRoot 'VSAModule.psd1') -Force } Describe "ConvertTo-VSARequestBody assembles bodies from bound parameters" { It "includes only bound parameters" { InModuleScope VSAModule { $bound = @{ OrgName = 'Acme'; OrgRef = 'acme' } # Website not bound $ht = ConvertTo-VSARequestBody -BoundParameters $bound -Include @('OrgName','OrgRef','Website') $ht.Keys | Should -Contain 'OrgName' $ht.Keys | Should -Contain 'OrgRef' $ht.Keys | Should -Not -Contain 'Website' } } It "includes an explicitly-bound 0 / \$false (ContainsKey, not truthiness)" { InModuleScope VSAModule { $bound = @{ NoOfEmployees = 0; TimeSheetFlag = $false } $ht = ConvertTo-VSARequestBody -BoundParameters $bound -Include @('NoOfEmployees','TimeSheetFlag') $ht['NoOfEmployees'] | Should -Be 0 $ht['TimeSheetFlag'] | Should -Be $false $ht.Keys | Should -Contain 'NoOfEmployees' $ht.Keys | Should -Contain 'TimeSheetFlag' } } It "renames parameters to body fields via -NameMap" { InModuleScope VSAModule { $bound = @{ OrganizationName = 'Acme'; OrgIdNumber = 0 } $ht = ConvertTo-VSARequestBody -BoundParameters $bound -Include @('OrganizationName','OrgIdNumber') ` -NameMap @{ OrganizationName = 'OrgName'; OrgIdNumber = 'OrgId' } $ht.Keys | Should -Contain 'OrgName' $ht.Keys | Should -Contain 'OrgId' $ht['OrgId'] | Should -Be 0 $ht.Keys | Should -Not -Contain 'OrganizationName' } } } Describe "Invoke-VSAWriteRequest is the shared write dispatch tail" { It "serializes a hashtable body and forwards it to the transport" { InModuleScope VSAModule { $script:body = $null; $script:method = $null; $script:suffix = $null Mock Invoke-VSARestMethod { $script:body = $Body; $script:method = $Method; $script:suffix = $URISuffix } Invoke-VSAWriteRequest -Body @{ Name = 'X' } -Method POST -URISuffix 'api/v1.0/things' | Out-Null $script:method | Should -Be 'POST' $script:suffix | Should -Be 'api/v1.0/things' ($script:body | ConvertFrom-Json).Name | Should -Be 'X' } } It "prunes \$null and empty-string but KEEPS an explicit 0 / \$false (F-52)" { InModuleScope VSAModule { $script:body = $null Mock Invoke-VSARestMethod { $script:body = $Body } Invoke-VSAWriteRequest -Method PUT -URISuffix 'api/v1.0/x' -Body @{ Keep0 = 0; KeepFalse = $false; DropNull = $null; DropEmpty = '' } | Out-Null $obj = $script:body | ConvertFrom-Json $obj.PSObject.Properties.Name | Should -Contain 'Keep0' $obj.PSObject.Properties.Name | Should -Contain 'KeepFalse' $obj.Keep0 | Should -Be 0 $obj.KeepFalse | Should -Be $false $obj.PSObject.Properties.Name | Should -Not -Contain 'DropNull' $obj.PSObject.Properties.Name | Should -Not -Contain 'DropEmpty' } } It "-KeepEmpty transmits null/empty fields unpruned" { InModuleScope VSAModule { $script:body = $null Mock Invoke-VSARestMethod { $script:body = $Body } Invoke-VSAWriteRequest -Method PUT -URISuffix 'api/v1.0/x' -KeepEmpty -Body @{ Empty = '' } | Out-Null ($script:body | ConvertFrom-Json).PSObject.Properties.Name | Should -Contain 'Empty' } } It "serializes nested bodies deep enough (default depth 10, not the old truncating 2)" { InModuleScope VSAModule { $script:body = $null Mock Invoke-VSARestMethod { $script:body = $Body } Invoke-VSAWriteRequest -Method POST -URISuffix 'api/v1.0/x' -Body @{ L1 = @{ L2 = @{ L3 = @{ L4 = 'deep' } } } } | Out-Null ($script:body | ConvertFrom-Json).L1.L2.L3.L4 | Should -Be 'deep' } } It "passes a pre-serialized string body through unchanged" { InModuleScope VSAModule { $script:body = $null Mock Invoke-VSARestMethod { $script:body = $Body } $json = '[{"key":"a","value":"b"}]' Invoke-VSAWriteRequest -Method PUT -URISuffix 'api/v1.0/x' -Body $json | Out-Null $script:body | Should -Be $json } } It "sends no body when -Body is omitted (templated-URI write)" { InModuleScope VSAModule { $script:body = 'SENTINEL' Mock Invoke-VSARestMethod { $script:body = $Body } Invoke-VSAWriteRequest -Method PUT -URISuffix 'api/v1.0/agents/1/rename/foo' | Out-Null [string]::IsNullOrEmpty($script:body) | Should -Be $true } } It "forwards -VSAConnection only when non-null (F-31)" { # Assert on the received parameter VALUE, not $PSBoundParameters.ContainsKey -- the latter # is unreliable for splatted params inside a Pester mock. InModuleScope VSAModule { $script:conn = 'SENTINEL' Mock Invoke-VSARestMethod { $script:conn = $VSAConnection } Invoke-VSAWriteRequest -Method POST -URISuffix 'api/v1.0/x' -Body @{ a = 1 } -VSAConnection $null | Out-Null $script:conn | Should -Be $null $conn = [VSAConnection]::new(); $conn.URI = 'https://x' Invoke-VSAWriteRequest -Method POST -URISuffix 'api/v1.0/x' -Body @{ a = 1 } -VSAConnection $conn | Out-Null $script:conn | Should -Not -Be $null $script:conn.URI | Should -Be 'https://x' } } It "with -ExtendedOutput forwards the switch and expands .Result" { InModuleScope VSAModule { $script:extended = $null Mock Invoke-VSARestMethod { $script:extended = [bool]$ExtendedOutput [pscustomobject]@{ Result = 12345; ResponseCode = 0 } # full envelope } $r = Invoke-VSAWriteRequest -Method POST -URISuffix 'api/v1.0/x' -Body @{ a = 1 } -ExtendedOutput $script:extended | Should -Be $true $r | Should -Be 12345 } } It "without -ExtendedOutput does not expand (returns transport result as-is)" { InModuleScope VSAModule { Mock Invoke-VSARestMethod { $true } $r = Invoke-VSAWriteRequest -Method POST -URISuffix 'api/v1.0/x' -Body @{ a = 1 } $r | Should -Be $true } } } Describe "Uniform ShouldProcess: -WhatIf gates the transport across converted write cmdlets" { It "-WhatIf blocks the request (no transport call)" { InModuleScope VSAModule { $script:calls = 0 Mock Invoke-VSARestMethod { $script:calls++ } New-VSANotification -Title 'T' -Text 'B' -WhatIf | Out-Null $script:calls | Should -Be 0 } } It "without -WhatIf the request goes through" { InModuleScope VSAModule { $script:calls = 0 Mock Invoke-VSARestMethod { $script:calls++ } New-VSANotification -Title 'T' -Text 'B' | Out-Null $script:calls | Should -Be 1 } } It "-WhatIf also gates a no-body templated write (Disable-VSAUser)" { InModuleScope VSAModule { $script:calls = 0 Mock Invoke-VSARestMethod { $script:calls++ } Disable-VSAUser -UserId 100 -WhatIf | Out-Null $script:calls | Should -Be 0 } } } |