Tests/VSAModule.IdMapDedup.Tests.ps1
|
BeforeAll { $script:ModuleRoot = Split-Path -Path (Split-Path -Parent $PSCommandPath) Import-Module (Join-Path $script:ModuleRoot 'VSAModule.psd1') -Force } Describe "Hoisted ID maps are single-sourced and match their ValidateSet literals (T-7.6 / F-53)" { It "TenantModuleIdMap exists exactly once, in private/VSAEndpointMaps.ps1; TenantRoleTypeIdMap is gone (F-64)" { # The maps were extracted from the .psm1 into a dot-sourced private data file for readability; # TenantModuleIdMap must still be single-sourced there. TenantRoleTypeIdMap was removed in F-64 # (role types are now resolved dynamically via Get-VSARoleType) and must not exist anywhere. $mapsFile = Join-Path $script:ModuleRoot 'private/VSAEndpointMaps.ps1' Test-Path $mapsFile | Should -Be $true $maps = Get-Content -Path $mapsFile -Raw ([regex]::Matches($maps, '\$(?:script:)?TenantModuleIdMap\s*=\s*@\{')).Count | Should -Be 1 # TenantModuleIdMap not redefined elsewhere; TenantRoleTypeIdMap not defined anywhere at all. $allFiles = @(Get-ChildItem -Path (Join-Path $script:ModuleRoot 'public'), (Join-Path $script:ModuleRoot 'private') -Filter '*.ps1' -File) $allFiles += Get-Item (Join-Path $script:ModuleRoot 'VSAModule.psm1') foreach ($f in $allFiles) { $content = Get-Content -LiteralPath $f.FullName -Raw if ($f.Name -ne 'VSAEndpointMaps.ps1') { $content | Should -Not -Match '\$(?:script:)?TenantModuleIdMap\s*=\s*@\{' } $content | Should -Not -Match '\$(?:script:)?TenantRoleTypeIdMap\s*=\s*@\{' } } It "Enable-VSATenantModule's ModuleName/ModuleId ValidateSets match the module-scope map's keys/values" { InModuleScope VSAModule { $cmd = Get-Command Enable-VSATenantModule $namesInSet = [string[]](($cmd.Parameters['ModuleName'].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] }).ValidValues) $idsInSet = [int[]](($cmd.Parameters['ModuleId'].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] }).ValidValues) @(Compare-Object $namesInSet ([string[]]$TenantModuleIdMap.Keys)) | Should -BeNullOrEmpty @(Compare-Object $idsInSet ([int[]]$TenantModuleIdMap.Values)) | Should -BeNullOrEmpty } } It "Remove-VSATenantModule's ModuleName/ModuleId ValidateSets match the module-scope map's keys/values" { InModuleScope VSAModule { $cmd = Get-Command Remove-VSATenantModule $namesInSet = [string[]](($cmd.Parameters['ModuleName'].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] }).ValidValues) $idsInSet = [int[]](($cmd.Parameters['ModuleId'].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] }).ValidValues) @(Compare-Object $namesInSet ([string[]]$TenantModuleIdMap.Keys)) | Should -BeNullOrEmpty @(Compare-Object $idsInSet ([int[]]$TenantModuleIdMap.Values)) | Should -BeNullOrEmpty } } It "Enable/Clear-VSATenantRoleType no longer hardcode a role-type ValidateSet (F-64: resolved at runtime)" { # The stale ValidateSet + static map were replaced by live Get-VSARoleType resolution, so an # instance's custom / multi-tenant role types are reachable. Assert the ValidateSet is gone. InModuleScope VSAModule { foreach ($pair in @(@('Enable-VSATenantRoleType','RoleType'), @('Clear-VSATenantRoleType','RoleTypeName'))) { $cmd = Get-Command $pair[0] $vs = $cmd.Parameters[$pair[1]].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] } $vs | Should -BeNullOrEmpty -Because "$($pair[0]) -$($pair[1]) should resolve dynamically, not via a hardcoded ValidateSet" } } } It "Enable-VSATenantModule resolves a multi-select ModuleName correctly (F-35-style array-key bug fixed)" { InModuleScope VSAModule { $script:body = $null Mock Invoke-VSARestMethod { $script:body = $Body } Enable-VSATenantModule -TenantId 10001 -ModuleName 'Agent', 'Backup' | Out-Null $arr = $script:body | ConvertFrom-Json $arr | Should -Contain 9 $arr | Should -Contain 12 } } It "Remove-VSATenantModule resolves ModuleName to the correct Id" { InModuleScope VSAModule { $script:capturedSuffix = $null Mock Invoke-VSARestMethod { $script:capturedSuffix = $URISuffix } Remove-VSATenantModule -TenantId 10001 -ModuleName 'Backup' | Out-Null $script:capturedSuffix | Should -Match 'moduleId=12' } } It "Enable-VSATenantRoleType resolves RoleType names to Ids via live Get-VSARoleType (incl. instance-specific ones)" { InModuleScope VSAModule { $script:body = $null # A live role-type set that includes types the OLD hardcoded map never had. Mock Get-VSARoleType { @( [pscustomobject]@{ RoleTypeId = 4; RoleTypeName = 'VSA Admin' } [pscustomobject]@{ RoleTypeId = 90; RoleTypeName = 'Multi-Tenant' } [pscustomobject]@{ RoleTypeId = 1234; RoleTypeName = 'Multi-Tenant Admin' } ) } Mock Invoke-VSARestMethod { $script:body = $Body } Enable-VSATenantRoleType -TenantId 10001 -RoleType 'Multi-Tenant', 'Multi-Tenant Admin' | Out-Null $arr = $script:body | ConvertFrom-Json $arr | Should -Contain 90 $arr | Should -Contain 1234 } } It "Enable-VSATenantRoleType throws a clear error for a role type that does not exist on the instance" { InModuleScope VSAModule { Mock Get-VSARoleType { @([pscustomobject]@{ RoleTypeId = 4; RoleTypeName = 'VSA Admin' }) } Mock Invoke-VSARestMethod {} { Enable-VSATenantRoleType -TenantId 10001 -RoleType 'No Such Role' } | Should -Throw -ExpectedMessage '*No role type found with name ''No Such Role''*' } } It "Clear-VSATenantRoleType resolves RoleTypeName to the correct Id via live Get-VSARoleType" { InModuleScope VSAModule { $script:capturedSuffix = $null Mock Get-VSATenants { [pscustomobject]@{ Id = '99'; Ref = 'Acme' } } Mock Get-VSARoleType { @([pscustomobject]@{ RoleTypeId = 1234; RoleTypeName = 'Multi-Tenant Admin' }) } Mock Invoke-VSARestMethod { $script:capturedSuffix = $URISuffix } Clear-VSATenantRoleType -TenantName 'Acme' -RoleTypeName 'Multi-Tenant Admin' | Out-Null $script:capturedSuffix | Should -Match 'roleTypeId=1234' } } } |