tests/CategoryFiltering.Tests.ps1
|
#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } <# .SYNOPSIS Pester tests for Invoke-AzureScout -Category parameter behavior. .DESCRIPTION Validates the -Category parameter: ValidateSet, default value, array type, and alias normalization logic (long names / alternate spellings mapped to canonical short folder names). No live Azure authentication is required. .NOTES Author: AzureScout Contributors Version: 1.0.0 Created: 2026-02-24 Phase: 18.2.5, 18.7 — Category Filtering #> BeforeAll { $script:ModuleRoot = Split-Path -Parent $PSScriptRoot $script:InvokeScript = Join-Path $script:ModuleRoot 'Modules' 'Public' 'PublicFunctions' 'Invoke-AzureScout.ps1' # Dot-source the script to load the function into scope without a full module import . $script:InvokeScript $script:Cmd = Get-Command -Name Invoke-AzureScout -ErrorAction SilentlyContinue } Describe 'Category Parameter — Metadata' { It 'Invoke-AzureScout function is available after dot-source' { $script:Cmd | Should -Not -BeNullOrEmpty } It 'Category parameter exists' { $script:Cmd.Parameters.ContainsKey('Category') | Should -BeTrue } It 'Category parameter is array type [string[]]' { $script:Cmd.Parameters['Category'].ParameterType | Should -Be ([string[]]) } It 'Category parameter default is @("All")' { $default = $script:Cmd.Parameters['Category'].DefaultValue if ($null -eq $default) { # Default may not be accessible via reflection; verify ValidateSet contains 'All' Set-ItResult -Skipped -Because 'Default value not inspectable via reflection on all PS versions' } else { $default | Should -Be @('All') } } It 'Category ValidateSet contains "All"' { $vs = $script:Cmd.Parameters['Category'].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] } $vs | Should -Not -BeNullOrEmpty $vs.ValidValues | Should -Contain 'All' } It 'Category ValidateSet contains all 15 named categories' { $expectedCategories = @('AI','Analytics','Compute','Containers','Databases','Hybrid','Identity','Integration','IoT','Management','Monitor','Networking','Security','Storage','Web') $vs = $script:Cmd.Parameters['Category'].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] } foreach ($cat in $expectedCategories) { $vs.ValidValues | Should -Contain $cat -Because "Category '$cat' must be in the ValidateSet" } } It 'Category ValidateSet has exactly 16 values (All + 15 categories)' { $vs = $script:Cmd.Parameters['Category'].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] } $vs.ValidValues.Count | Should -Be 16 } } Describe 'Category Alias Normalization — alias map in Invoke-AzureScout body' { # Load the raw script text once BeforeAll { $script:FunctionSource = Get-Content -Path $script:InvokeScript -Raw } It 'Alias map contains "AI + machine learning" -> "AI"' { $script:FunctionSource | Should -Match "'AI \+ machine learning'" } It 'Alias map contains "Internet of Things" -> "IoT"' { $script:FunctionSource | Should -Match "'Internet of Things'" } It 'Alias map contains "Monitoring" -> "Monitor"' { $script:FunctionSource | Should -Match "'Monitoring'" } It 'Alias map contains "Management and governance" -> "Management"' { $script:FunctionSource | Should -Match "'Management and governance'" } It 'Alias map contains "Web & Mobile" -> "Web"' { $script:FunctionSource | Should -Match "'Web & Mobile'" } It 'Alias map contains "Hybrid + multicloud" -> "Hybrid"' { $script:FunctionSource | Should -Match "'Hybrid \+ multicloud'" } It 'Function body performs alias normalization with ForEach-Object loop' { $script:FunctionSource | Should -Match '_categoryAliasMap' } It 'Function body deduplicates Category with Select-Object -Unique' { $script:FunctionSource | Should -Match 'Select-Object -Unique' } } Describe 'Category alias resolution logic — unit test of normalization block' { BeforeAll { # Extract and run just the alias-map block using a controlled $Category input $aliasMap = @{ 'AI + machine learning' = 'AI' 'AI+machine learning' = 'AI' 'Machine Learning' = 'AI' 'Internet of Things' = 'IoT' 'Monitoring' = 'Monitor' 'Management and governance' = 'Management' 'Management & governance' = 'Management' 'Web & Mobile' = 'Web' 'Hybrid + multicloud' = 'Hybrid' 'Hybrid+multicloud' = 'Hybrid' 'DevOps' = 'Management' 'Migration' = 'Management' } function Resolve-CategoryAlias { param([string[]]$Category) $map = @{ 'AI + machine learning' = 'AI' 'AI+machine learning' = 'AI' 'Machine Learning' = 'AI' 'Internet of Things' = 'IoT' 'Monitoring' = 'Monitor' 'Management and governance' = 'Management' 'Management & governance' = 'Management' 'Web & Mobile' = 'Web' 'Hybrid + multicloud' = 'Hybrid' 'Hybrid+multicloud' = 'Hybrid' 'DevOps' = 'Management' 'Migration' = 'Management' } $Category = $Category | ForEach-Object { if ($map.ContainsKey($_)) { $map[$_] } else { $_ } } $Category | Select-Object -Unique } } It '"AI + machine learning" resolves to "AI"' { Resolve-CategoryAlias -Category @('AI + machine learning') | Should -Be 'AI' } It '"Internet of Things" resolves to "IoT"' { Resolve-CategoryAlias -Category @('Internet of Things') | Should -Be 'IoT' } It '"Monitoring" resolves to "Monitor"' { Resolve-CategoryAlias -Category @('Monitoring') | Should -Be 'Monitor' } It '"Management and governance" resolves to "Management"' { Resolve-CategoryAlias -Category @('Management and governance') | Should -Be 'Management' } It '"Web & Mobile" resolves to "Web"' { Resolve-CategoryAlias -Category @('Web & Mobile') | Should -Be 'Web' } It '"Hybrid + multicloud" resolves to "Hybrid"' { Resolve-CategoryAlias -Category @('Hybrid + multicloud') | Should -Be 'Hybrid' } It '"DevOps" resolves to "Management"' { Resolve-CategoryAlias -Category @('DevOps') | Should -Be 'Management' } It '"Migration" resolves to "Management"' { Resolve-CategoryAlias -Category @('Migration') | Should -Be 'Management' } It 'Canonical short names pass through unchanged' { Resolve-CategoryAlias -Category @('Compute') | Should -Be 'Compute' Resolve-CategoryAlias -Category @('Networking') | Should -Be 'Networking' Resolve-CategoryAlias -Category @('Security') | Should -Be 'Security' } It 'Multiple aliases in one array resolve to unique canonical values' { $result = Resolve-CategoryAlias -Category @('Management and governance', 'DevOps', 'Migration') $result | Should -HaveCount 1 $result | Should -Contain 'Management' } It '"All" passes through unchanged' { Resolve-CategoryAlias -Category @('All') | Should -Be 'All' } } |