Tests/PowerTree.Registry.Tests.ps1
|
$ErrorActionPreference = "Stop" $modulePath = Join-Path $PSScriptRoot "../PowerTree.psd1" Import-Module $modulePath -Force Describe "registry filtering and output" { InModuleScope PowerTree { It "matches wildcard filters and handles empty patterns" { Test-FilterMatch -ItemName "PowerTree" -Patterns @("Power*") | Should -BeTrue Test-FilterMatch -ItemName "PowerTree" -Patterns @("Other*") | Should -BeFalse Test-FilterMatch -ItemName "PowerTree" -Patterns @() | Should -BeFalse } It "resets flags and marks only the final item" { $items = @( [pscustomobject]@{ Name = "a"; IsLast = $true }, [pscustomobject]@{ Name = "b"; IsLast = $false } ) $result = @(Set-LastItemFlag $items) $result[0].IsLast | Should -BeFalse $result[1].IsLast | Should -BeTrue } It "sorts default values, named values, and keys together" { $values = @( [pscustomobject]@{ TypeName = "String"; Name = "z" }, [pscustomobject]@{ TypeName = "String"; Name = "(Default)" }, [pscustomobject]@{ TypeName = "DWord"; Name = "a" } ) $keys = @( [pscustomobject]@{ TypeName = "Key"; Name = "Beta" }, [pscustomobject]@{ TypeName = "Key"; Name = "Alpha" } ) @(Invoke-RegistryItemSorting $values $keys $false $false).Name | Should -Be @("(Default)", "a", "z", "Alpha", "Beta") @(Invoke-RegistryItemSorting $values $keys $true $false).TypeName | Should -Be @("DWord", "Key", "Key", "String", "String") } It "formats registry configuration" { $config = [pscustomobject]@{ SortValuesByType = $true SortDescending = $true UseRegistryDataTypes = $true NoValues = $true DisplayItemCounts = $true MaxDepth = 2 Include = @("Name*") Exclude = @("Secret*") } $content = (Get-RegistryConfigurationData $config) -join "`n" $content | Should -Match "Type Descending" $content | Should -Match "REG_SZ" $content | Should -Match "Name\*" $content | Should -Match "Secret\*" } It "builds registry output and replaces its stats placeholder" { $lineStyle = Build-TreeLineStyle Unicode $config = [pscustomobject]@{ Path = "HKCU:\Software" LineStyle = $lineStyle SortValuesByType = $false SortDescending = $false UseRegistryDataTypes = $false NoValues = $false DisplayItemCounts = $false MaxDepth = -1 Include = @() Exclude = @() } $builder = Invoke-OutputBuilderRegistry -TreeRegistryConfig $config ` -ShowExecutionStats $true -ShowConfigurations $true $stats = [RegistryStats]::new() $stats.KeysProcessed = 2 $stats.ValuesProcessed = 3 $stats.UpdateDepth(2) Show-RegistryStats -RegistryStats $stats -ExecutionTime ([timespan]::FromSeconds(1)) ` -LineStyle $lineStyle -OutputBuilder $builder $builder.ToString() | Should -Match "# PowerTreeRegistry Output" $builder.ToString() | Should -Match "Configuration:" $builder.ToString() | Should -Match "2\s+3\s+5" $builder.ToString() | Should -Not -Match "Append the stats" } } } Describe "Windows registry traversal" -Skip:(-not $IsWindows) { InModuleScope PowerTree { BeforeAll { $script:keyName = "PowerTreeTests-" + [guid]::NewGuid().ToString("N") $script:registryPath = "HKCU:\Software\$keyName" [void](New-Item -Path $registryPath -Force) [void](New-Item -Path "$registryPath\Alpha" -Force) [void](New-Item -Path "$registryPath\Excluded" -Force) New-ItemProperty -Path $registryPath -Name "Name" -Value "PowerTree" -PropertyType String -Force | Out-Null New-ItemProperty -Path $registryPath -Name "Number" -Value 42 -PropertyType DWord -Force | Out-Null New-ItemProperty -Path $registryPath -Name "SecretValue" -Value "hidden" -PropertyType String -Force | Out-Null New-ItemProperty -Path "$registryPath\Alpha" -Name "ChildValue" -Value "child" -PropertyType String -Force | Out-Null } AfterAll { if ($registryPath -match '^HKCU:\\Software\\PowerTreeTests-[a-f0-9]{32}$') { Remove-Item -LiteralPath $registryPath -Recurse -Force } } It "normalizes and validates a registry path" { $fullPath = "HKEY_CURRENT_USER\Software\$keyName" Get-Path $fullPath | Should -Be $registryPath } It "processes child keys with exclusions and item counts" { $keys = @(Get-ProcessedRegistryKeys -RegistryPath $registryPath -Exclude @("Excluded") ` -HasKeyFilters $true -DisplayItemCounts $true) $keys.Count | Should -Be 1 $keys[0].Name | Should -Be "Alpha" $keys[0].ValueCount | Should -Be 1 $keys[0].SubKeyCount | Should -Be 0 } It "processes values with filters and registry data type names" { $regKey = Get-Item -LiteralPath $registryPath $typeMap = @{ String = "REG_SZ"; DWord = "REG_DWORD" } $values = @(Get-ProcessedRegistryValues -RegKey $regKey -RegistryTypeMap $typeMap ` -UseRegistryDataTypes $true -Include @("N*") -Exclude @("Secret*") -HasValueFilters $true) $values.Name | Should -Be @("Name", "Number") $values.TypeName | Should -Be @("REG_SZ", "REG_DWORD") } It "composes values, child keys, sorting, filtering, and last flags" { $items = @(Get-RegistryItems -RegistryPath $registryPath -DisplayItemCounts $true ` -SortValuesByType $false -UseRegistryDataTypes $false -Exclude @("Secret*", "Excluded")) $items.Name | Should -Contain "Name" $items.Name | Should -Contain "Number" $items.Name | Should -Contain "Alpha" $items.Name | Should -Not -Contain "SecretValue" $items.Name | Should -Not -Contain "Excluded" @($items | Where-Object IsLast).Count | Should -Be 1 $items[-1].IsLast | Should -BeTrue } It "renders a recursive registry tree into a collection" { $config = [pscustomobject]@{ Path = $registryPath NoValues = $false Exclude = @("Secret*", "Excluded") Include = @() MaxDepth = -1 LineStyle = Build-TreeLineStyle Unicode DisplayItemCounts = $true SortValuesByType = $false SortDescending = $false UseRegistryDataTypes = $false } $output = [System.Collections.Generic.List[string]]::new() $stats = Get-TreeRegistryView -TreeRegistryConfig $config -OutputCollection $output $output -join "`n" | Should -Match "Type\s+Hierarchy" $output -join "`n" | Should -Match "Alpha" $output -join "`n" | Should -Match "ChildValue = child" $stats.KeysProcessed | Should -Be 1 $stats.ValuesProcessed | Should -Be 3 $stats.MaxDepthReached | Should -Be 1 } It "runs the public registry command with filters and file output" { $homePath = Join-Path $TestDrive "registry-home" [void][System.IO.Directory]::CreateDirectory((Join-Path $homePath ".PowerTree")) $configPath = Join-Path $homePath ".PowerTree/config.json" @{ Shared = @{ ShowConnectorLines = $true ShowExecutionStats = $true ShowConfigurations = $false LineStyle = "Unicode" OpenOutputFileOnFinish = $false } FileSystem = @{} Registry = @{ MaxDepth = -1; ExcludeKeys = @() } } | ConvertTo-Json -Depth 5 | Set-Content $configPath $originalHome = $env:HOME $originalUserProfile = $env:USERPROFILE $env:HOME = $homePath $env:USERPROFILE = $homePath try { $outputPath = Join-Path $TestDrive "registry.txt" Show-PowerTreeRegistry -Path $registryPath -Exclude @("Secret*", "Excluded") ` -UseRegistryDataTypes -DisplayItemCounts -OutFile $outputPath *> $null $content = [System.IO.File]::ReadAllText($outputPath) $content | Should -Match "REG_SZ" $content | Should -Match "Alpha" $content | Should -Not -Match "SecretValue" $content | Should -Match "Keys\s+Values" } finally { $env:HOME = $originalHome $env:USERPROFILE = $originalUserProfile } } } } |