Enhance output documentation and error handling

This commit is contained in:
Jeffrey
2026-08-22 17:14:09 +02:00
parent 80eadd531c
commit c921730703
17 changed files with 228 additions and 66 deletions
+24
View File
@@ -61,6 +61,30 @@ Describe 'Test-ConfigConsistency' {
Test-ConfigConsistency -Config $config | Should -Match 'no importable data'
}
It 'reports an error for invalid app entries' {
$config = [PSCustomObject]@{ Version = '1.0'; Apps = 42 }
Test-ConfigConsistency -Config $config | Should -Match 'Apps entries must be strings'
}
It 'reports an error for nonnumeric deployment indexes' {
$config = [PSCustomObject]@{
Version = '1.0'
Deployment = @(@{ Name = 'AppRemovalScopeIndex'; Value = 'all' })
}
Test-ConfigConsistency -Config $config | Should -Match 'AppRemovalScopeIndex must be a supported numeric value'
}
It 'reports an error for out-of-range deployment indexes' {
$config = [PSCustomObject]@{
Version = '1.0'
Deployment = @(@{ Name = 'UserSelectionIndex'; Value = 3 })
}
Test-ConfigConsistency -Config $config | Should -Match 'UserSelectionIndex must be a supported numeric value'
}
It 'returns null for a consistent all-users scope' {
$config = [PSCustomObject]@{
Version = '1.0'
+2 -2
View File
@@ -211,7 +211,7 @@ Describe 'Get-AppRemovalScopeTarget' {
Get-AppRemovalScopeTarget -AppRemovalScopeCombo $combo -OtherUsernameTextBox $usernameBox | Should -BeNullOrEmpty
}
It 'defaults to AllUsers for an unrecognized ComboBoxItem Name' {
It 'returns null for an unrecognized ComboBoxItem Name' {
$combo = New-Object System.Windows.Controls.ComboBox
$item = New-Object System.Windows.Controls.ComboBoxItem
$item.Name = 'SomeUnrelatedControl'
@@ -219,7 +219,7 @@ Describe 'Get-AppRemovalScopeTarget' {
$combo.SelectedItem = $item
$usernameBox = New-Object System.Windows.Controls.TextBox
Get-AppRemovalScopeTarget -AppRemovalScopeCombo $combo -OtherUsernameTextBox $usernameBox | Should -Be 'AllUsers'
Get-AppRemovalScopeTarget -AppRemovalScopeCombo $combo -OtherUsernameTextBox $usernameBox | Should -BeNullOrEmpty
}
It 'returns an empty string for the target-user scope when the username is blank' {
+34 -27
View File
@@ -91,6 +91,17 @@ Describe 'Remove-SelectedApps' {
$script:AppRemovalFailures | Should -Be 0
}
It 'counts a failed WinGet scheduling result for a target user' {
$script:Params = @{ User = 'Alice' }
Mock Get-AppRemovalMethod { 'WinGet' }
Mock Remove-WinGetApp { $false }
Mock Test-AppInWingetList { $false }
Remove-SelectedApps -appsList @('One.App') | Should -BeFalse
$script:AppRemovalFailures | Should -Be 1
}
It 'counts a WinGet removal that remains installed after a successful command' {
Mock Get-AppRemovalMethod { 'WinGet' }
Mock Test-AppInWingetList { $true }
@@ -197,41 +208,28 @@ Describe 'Remove-WinGetApp' {
}
}
It 'returns false when winget exits unsuccessfully' {
Mock Invoke-NonBlocking { [PSCustomObject]@{ Success = $false; ExitCode = 1; Output = @('failure') } }
Mock Write-Verbose {}
Remove-WinGetApp -app 'One.App' | Should -BeFalse
Should -Invoke Write-Verbose -Times 1 -Exactly -ParameterFilter { $Message -match 'exit code 1' }
}
It 'returns false for a non-zero WinGet exit code without writing an error record' {
Mock Invoke-NonBlocking { [PSCustomObject]@{ Success = $false; ExitCode = -1978335212; Output = @('No installed package found matching input criteria.') } }
Mock Write-Verbose {}
Remove-WinGetApp -app 'One.App' | Should -BeFalse
Should -Invoke Write-Verbose -Times 1 -Exactly -ParameterFilter { $Message -match 'post-removal inventory check' }
Should -Invoke Write-Verbose -Times 1 -Exactly -ParameterFilter { $Message -match 'No installed package found' }
}
It 'writes captured winget output to the verbose stream before returning success' {
Mock Invoke-NonBlocking { [PSCustomObject]@{ Success = $true; ExitCode = 0; Output = @('Successfully uninstalled One.App') } }
It 'returns true and logs WinGet output regardless of exit code' -ForEach @(
@{ ExitCode = 0; Output = 'Successfully uninstalled One.App' }
@{ ExitCode = 1; Output = 'Package was not found' }
@{ ExitCode = -1978335212; Output = 'No installed package found matching input criteria.' }
) {
$script:expectedExitCode = $ExitCode
$script:expectedOutput = $Output
Mock Invoke-NonBlocking { [PSCustomObject]@{ ExitCode = $script:expectedExitCode; Output = @($script:expectedOutput) } }
Mock Write-Verbose {}
Remove-WinGetApp -app 'One.App' | Should -BeTrue
Should -Invoke Write-Verbose -Times 1 -Exactly -ParameterFilter { $Message -eq 'Successfully uninstalled One.App' }
Should -Invoke Write-Verbose -Times 1 -Exactly -ParameterFilter { $Message -eq $script:expectedOutput }
Should -Invoke Write-Verbose -Times 1 -Exactly -ParameterFilter { $Message -eq "WinGet uninstall for One.App returned exit code $script:expectedExitCode." }
}
It 'writes captured winget diagnostics to the verbose stream when winget fails' {
Mock Invoke-NonBlocking { [PSCustomObject]@{ Success = $false; ExitCode = 1; Output = @('Package was not found') } }
Mock Write-Verbose {}
It 'returns the RunOnce scheduling result for a target user' {
$script:Params = @{ User = 'Alice' }
Mock Invoke-NonBlocking { [PSCustomObject]@{ ExitCode = 1; Output = @() } }
Mock Set-RunOnceWingetTask { $false }
Remove-WinGetApp -app 'One.App' | Should -BeFalse
Should -Invoke Write-Verbose -Times 1 -Exactly -ParameterFilter { $Message -eq 'Package was not found' }
}
}
@@ -250,6 +248,15 @@ Describe 'Remove-EdgeAutostartValue' {
Should -Invoke Remove-ItemProperty -Times 0 -Exactly
}
It 'treats a missing registry key as already cleaned up' {
Mock Get-ItemProperty { throw [System.Management.Automation.ItemNotFoundException]::new('not found') }
Mock Remove-ItemProperty {}
Remove-EdgeAutostartValue -Path 'HKCU:\Software\Example' -Name 'Microsoft Edge Update' | Should -BeTrue
Should -Invoke Remove-ItemProperty -Times 0 -Exactly
}
It 'removes an existing value' {
Mock Get-ItemProperty { [PSCustomObject]@{ 'Microsoft Edge Update' = 'enabled' } }
Mock Remove-ItemProperty {}