Tests/Get-MsecEntraLicense.Tests.ps1
|
#Requires -Module Pester # # Tests for Get-MsecEntraLicense. Verifies the /subscribedSkus projection, and in # particular that ServicePlans contains ONLY successfully-provisioned plans - the # capability flags in Get-MsecEntraTenantSecuritySetting are derived from that # field, so a plan that is present-but-disabled must not read as available. BeforeAll { $modulePath = Join-Path $PSScriptRoot '..' 'Msec.psm1' Import-Module $modulePath -Force -ErrorAction Stop $script:TestThumbBytes = [byte[]](1..20) } AfterAll { Remove-Module Msec -Force -ErrorAction SilentlyContinue } Describe 'Get-MsecEntraLicense' { BeforeEach { InModuleScope Msec -Parameters @{ Thumb = $script:TestThumbBytes } { param($Thumb) $script:MsecSession = @{ TenantId = 'tenant' ClientId = 'client' KeyVaultName = 'kv-test' KeyName = 'msec-app' ThumbprintBytes = $Thumb Tokens = @{} } } } It 'projects SKUs and keeps only successfully-provisioned service plans' { $rows = InModuleScope Msec { Mock Invoke-MsecKeyVaultSign -MockWith { [byte[]](1..10) } Mock Invoke-RestMethod -ParameterFilter { $Uri -match 'oauth2/v2.0/token' } -MockWith { [pscustomobject]@{ access_token = 'mock'; expires_in = 3600 } } Mock Invoke-RestMethod -ParameterFilter { $Uri -match '/subscribedSkus' } -MockWith { [pscustomobject]@{ value = @( [pscustomobject]@{ skuId = 'sku-e5' skuPartNumber = 'SPE_E5' appliesTo = 'User' capabilityStatus = 'Enabled' consumedUnits = 18 prepaidUnits = [pscustomobject]@{ enabled = 20; warning = 1; suspended = 0 } servicePlans = @( [pscustomobject]@{ servicePlanName = 'AAD_PREMIUM'; provisioningStatus = 'Success' } [pscustomobject]@{ servicePlanName = 'AAD_PREMIUM_P2'; provisioningStatus = 'Success' } [pscustomobject]@{ servicePlanName = 'INTUNE_A'; provisioningStatus = 'Success' } # Present but NOT usable - must be excluded from ServicePlans. [pscustomobject]@{ servicePlanName = 'WINDEFATP'; provisioningStatus = 'PendingProvisioning' } ) } [pscustomobject]@{ skuId = 'sku-pbi' skuPartNumber = 'POWER_BI_STANDARD' appliesTo = 'User' capabilityStatus = 'Enabled' consumedUnits = 2 prepaidUnits = [pscustomobject]@{ enabled = 1000000; warning = 0; suspended = 0 } servicePlans = @( [pscustomobject]@{ servicePlanName = 'BI_AZURE_P0'; provisioningStatus = 'Success' } ) } ) } } Get-MsecEntraLicense } $rows.Count | Should -Be 2 $e5 = $rows | Where-Object SkuPartNumber -eq 'SPE_E5' $e5.SkuId | Should -Be 'sku-e5' $e5.Enabled | Should -Be 20 $e5.Assigned | Should -Be 18 $e5.WarningUnits | Should -Be 1 $e5.CapabilityStatus | Should -Be 'Enabled' # Only Success plans surface in ServicePlans... $e5.ServicePlans | Should -Contain 'AAD_PREMIUM' $e5.ServicePlans | Should -Contain 'INTUNE_A' $e5.ServicePlans | Should -Not -Contain 'WINDEFATP' # ...but ServicePlanDetail keeps everything, so the difference is visible. $e5.ServicePlanDetail.servicePlanName | Should -Contain 'WINDEFATP' $e5.Raw.skuId | Should -Be 'sku-e5' $e5.PSObject.TypeNames | Should -Contain 'MsecEntraLicense' } It 'coerces a SKU with no service plans to an empty array, not $null' { $row = InModuleScope Msec { Mock Invoke-MsecKeyVaultSign -MockWith { [byte[]](1..10) } Mock Invoke-RestMethod -ParameterFilter { $Uri -match 'oauth2/v2.0/token' } -MockWith { [pscustomobject]@{ access_token = 'mock'; expires_in = 3600 } } Mock Invoke-RestMethod -ParameterFilter { $Uri -match '/subscribedSkus' } -MockWith { [pscustomobject]@{ value = @( [pscustomobject]@{ skuId = 'sku-empty' skuPartNumber = 'WINDOWS_STORE' consumedUnits = 0 prepaidUnits = [pscustomobject]@{ enabled = 1000000; warning = 0; suspended = 0 } servicePlans = $null } ) } } Get-MsecEntraLicense } # The -contains pattern downstream code uses must not blow up. { $row | Where-Object ServicePlans -contains 'AAD_PREMIUM' } | Should -Not -Throw ($row | Where-Object ServicePlans -contains 'AAD_PREMIUM') | Should -BeNullOrEmpty } It 'rewrites a 403 to mention the missing Organization.Read.All permission' { InModuleScope Msec { Mock Invoke-MsecKeyVaultSign -MockWith { [byte[]](1..10) } Mock Invoke-RestMethod -ParameterFilter { $Uri -match 'oauth2/v2.0/token' } -MockWith { [pscustomobject]@{ access_token = 'mock'; expires_in = 3600 } } Mock Invoke-RestMethod -ParameterFilter { $Uri -match '/subscribedSkus' } -MockWith { throw 'Response status code does not indicate success: 403 (Forbidden).' } { Get-MsecEntraLicense } | Should -Throw -ExpectedMessage '*Organization.Read.All*' } } } |