mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-08-22 07:36:25 +00:00
203 lines
8.4 KiB
PowerShell
203 lines
8.4 KiB
PowerShell
BeforeAll {
|
|
function Wait-ForKeyPress {}
|
|
function Test-AppInWingetList { param($appId, $InstalledList) $false }
|
|
|
|
. (Join-Path $PSScriptRoot '..\Scripts\FileIO\Import-JsonFile.ps1')
|
|
. (Join-Path $PSScriptRoot '..\Scripts\Helpers\Add-Parameter.ps1')
|
|
. (Join-Path $PSScriptRoot '..\Scripts\FileIO\Save-ToFile.ps1')
|
|
. (Join-Path $PSScriptRoot '..\Scripts\FileIO\Import-Settings.ps1')
|
|
. (Join-Path $PSScriptRoot '..\Scripts\FileIO\Save-Settings.ps1')
|
|
. (Join-Path $PSScriptRoot '..\Scripts\FileIO\Import-AppsFromFile.ps1')
|
|
. (Join-Path $PSScriptRoot '..\Scripts\FileIO\Import-AppDetailsFromJson.ps1')
|
|
. (Join-Path $PSScriptRoot '..\Scripts\FileIO\Import-AppPresetsFromJson.ps1')
|
|
. (Join-Path $PSScriptRoot '..\Scripts\FileIO\Get-ValidatedAppList.ps1')
|
|
$script:JsonFixturePath = Join-Path $PSScriptRoot 'TestData\JsonFileLoading'
|
|
}
|
|
|
|
Describe 'Save-ToFile' {
|
|
It 'reports the write error and returns false when persistence fails' {
|
|
Mock Set-Content { throw [System.IO.IOException]::new('Disk is full') }
|
|
Mock Write-Error {}
|
|
|
|
Save-ToFile -Config @{ Setting = $true } -FilePath (Join-Path $TestDrive 'settings.json') | Should -BeFalse
|
|
|
|
Should -Invoke Write-Error -Times 1 -Exactly -ParameterFilter {
|
|
$Message -eq "Failed to write '$TestDrive\settings.json': Disk is full"
|
|
}
|
|
}
|
|
}
|
|
|
|
Describe 'Import-Settings' {
|
|
BeforeEach {
|
|
$script:Params = @{}
|
|
$script:ModernStandbySupported = $false
|
|
$script:Features = @{
|
|
Supported = [PSCustomObject]@{ FeatureId = 'Supported'; MinVersion = 22000; MaxVersion = 30000 }
|
|
TooNew = [PSCustomObject]@{ FeatureId = 'TooNew'; MinVersion = 99999; MaxVersion = $null }
|
|
DisableModernStandbyNetworking = [PSCustomObject]@{ FeatureId = 'DisableModernStandbyNetworking'; MinVersion = $null; MaxVersion = $null }
|
|
}
|
|
Mock Get-ItemPropertyValue { 22631 }
|
|
Mock Add-Parameter {}
|
|
Mock Write-Error {}
|
|
}
|
|
|
|
It 'loads enabled, known, compatible settings and skips all other entries' {
|
|
Import-Settings -filePath (Join-Path $script:JsonFixturePath 'DefaultSettings.Valid.json')
|
|
|
|
Should -Invoke Add-Parameter -Times 1 -Exactly -ParameterFilter { $parameterName -eq 'Supported' -and $value -eq 'configured' }
|
|
}
|
|
|
|
It 'throws when <Case>' -ForEach @(
|
|
@{ Case = 'the last-used settings JSON is invalid'; FileName = 'LastUsedSettings.Invalid.json'; WriteErrorCalls = 1 }
|
|
@{ Case = 'the default settings file has no Settings property'; FileName = 'DefaultSettings.MissingSettings.json'; WriteErrorCalls = 0 }
|
|
) {
|
|
$path = Join-Path $script:JsonFixturePath $FileName
|
|
|
|
{
|
|
& {
|
|
$ErrorActionPreference = 'Continue'
|
|
Import-Settings -filePath $path
|
|
}
|
|
} | Should -Throw "Failed to load settings from $FileName"
|
|
Should -Invoke Add-Parameter -Times 0 -Exactly
|
|
Should -Invoke Write-Error -Times $WriteErrorCalls -Exactly
|
|
}
|
|
}
|
|
|
|
Describe 'Save-Settings' {
|
|
BeforeEach {
|
|
$script:SavedSettingsFilePath = Join-Path $TestDrive 'LastUsedSettings.json'
|
|
$script:ControlParams = @('Silent', 'WhatIf')
|
|
$script:Features = @{ Feature = [PSCustomObject]@{ FeatureId = 'Feature' } }
|
|
Mock Save-ToFile { $true }
|
|
Mock Write-Host {}
|
|
Mock Write-Output {}
|
|
}
|
|
|
|
It 'saves only feature parameters and excludes control or unknown parameters' {
|
|
$script:Params = @{ Feature = 'configured'; Silent = $true; Unknown = 42 }
|
|
|
|
Save-Settings
|
|
|
|
Should -Invoke Save-ToFile -Times 1 -Exactly -ParameterFilter {
|
|
$FilePath -eq $script:SavedSettingsFilePath -and
|
|
@($Config.Settings).Count -eq 1 -and
|
|
$Config.Settings[0].Name -eq 'Feature' -and
|
|
$Config.Settings[0].Value -eq 'configured'
|
|
}
|
|
}
|
|
|
|
It 'does not persist in WhatIf mode' {
|
|
$script:Params = @{ Feature = $true; WhatIf = $true }
|
|
|
|
Save-Settings
|
|
|
|
Should -Invoke Save-ToFile -Times 0 -Exactly
|
|
}
|
|
|
|
It 'reports a persistence failure without throwing' {
|
|
$script:Params = @{ Feature = $true }
|
|
Mock Save-ToFile { $false }
|
|
|
|
{ Save-Settings } | Should -Not -Throw
|
|
Should -Invoke Write-Host -Times 1 -Exactly -ParameterFilter { $Object -like 'Error:*' }
|
|
}
|
|
}
|
|
|
|
Describe 'Import-AppsFromFile' {
|
|
It 'returns selected IDs, trims whitespace, and supports scalar and array AppId values' {
|
|
$path = Join-Path $TestDrive 'apps.json'
|
|
'{"Apps":[{"AppId":" One.App ","SelectedByDefault":true},{"AppId":["Two.App"," "],"SelectedByDefault":true},{"AppId":"Ignored.App","SelectedByDefault":false}]}' |
|
|
Set-Content -LiteralPath $path -Encoding UTF8
|
|
|
|
@(Import-AppsFromFile -appsFilePath $path) | Should -Be @('One.App', 'Two.App')
|
|
}
|
|
|
|
It 'returns an empty collection for a missing file' {
|
|
@(Import-AppsFromFile -appsFilePath (Join-Path $TestDrive 'missing.json')) | Should -HaveCount 0
|
|
}
|
|
|
|
It 'reports invalid JSON and invokes the CLI acknowledgement hook' {
|
|
$path = Join-Path $TestDrive 'invalid-apps.json'
|
|
'not json' | Set-Content -LiteralPath $path
|
|
Mock Write-Error {}
|
|
Mock Wait-ForKeyPress {}
|
|
|
|
@(Import-AppsFromFile -appsFilePath $path) | Should -HaveCount 0
|
|
Should -Invoke Write-Error -Times 1 -Exactly
|
|
Should -Invoke Wait-ForKeyPress -Times 1 -Exactly
|
|
}
|
|
}
|
|
|
|
Describe 'Get-ValidatedAppList' {
|
|
It 'normalizes wildcard selections and skips unsupported applications' {
|
|
Mock Import-AppDetailsFromJson { @([PSCustomObject]@{ AppId = @('One.App', 'Two.App') }) }
|
|
Mock Write-Host {}
|
|
|
|
@(Get-ValidatedAppList -appsList @('*One.App*', ' Missing.App ')) | Should -Be @('One.App')
|
|
Should -Invoke Write-Host -Times 1 -Exactly -ParameterFilter { $Object -like "*Missing.App*" }
|
|
}
|
|
}
|
|
|
|
Describe 'Import-AppDetailsFromJson' {
|
|
BeforeEach {
|
|
$script:AppsListFilePath = Join-Path $TestDrive 'Apps.json'
|
|
'{"Apps":[{"AppId":["One.App","Alias.App"],"FriendlyName":"One","SelectedByDefault":true,"RemovalMethod":"WinGet"},{"AppId":"Two.App","SelectedByDefault":false},{"AppId":" ","SelectedByDefault":true}],"Presets":[{"Name":"Minimal","AppIds":["One.App"]}]}' |
|
|
Set-Content -LiteralPath $script:AppsListFilePath -Encoding UTF8
|
|
}
|
|
|
|
It 'projects app metadata, defaults removal method, and honors initial checked state' {
|
|
$apps = @(Import-AppDetailsFromJson -InitialCheckedFromJson)
|
|
|
|
$apps | Should -HaveCount 2
|
|
$apps[0].DisplayName | Should -Be 'One (One.App, Alias.App)'
|
|
$apps[0].IsChecked | Should -BeTrue
|
|
$apps[0].RemovalMethod | Should -Be 'WinGet'
|
|
$apps[1].FriendlyName | Should -Be 'Two.App'
|
|
$apps[1].RemovalMethod | Should -Be 'Appx'
|
|
$apps[1].AppId -is [array] | Should -BeTrue
|
|
@($apps[1].AppId) | Should -HaveCount 1
|
|
}
|
|
|
|
It 'skips missing, blank, and non-string app IDs without failing the complete catalog' {
|
|
'{"Apps":[{"AppId":null},{"FriendlyName":"Missing"},{"AppId":42},{"AppId":[" Valid.App ",null,{},""]}]}' |
|
|
Set-Content -LiteralPath $script:AppsListFilePath -Encoding UTF8
|
|
|
|
$apps = @(Import-AppDetailsFromJson)
|
|
|
|
$apps | Should -HaveCount 1
|
|
$apps[0].AppId -is [array] | Should -BeTrue
|
|
$apps[0].AppId | Should -Be @('Valid.App')
|
|
}
|
|
|
|
It 'filters to installed apps using Appx and winget detection' {
|
|
Mock Get-AppxPackage { param($Name) if ($Name -eq 'Two.App') { [PSCustomObject]@{ Name = $Name } } }
|
|
Mock Test-AppInWingetList { $false }
|
|
|
|
$apps = @(Import-AppDetailsFromJson -OnlyInstalled -InstalledList @())
|
|
|
|
$apps | Should -HaveCount 1
|
|
$apps[0].AppId | Should -Be 'Two.App'
|
|
}
|
|
|
|
It 'loads presets and preserves their ID arrays' {
|
|
$presets = @(Import-AppPresetsFromJson)
|
|
|
|
$presets | Should -HaveCount 1
|
|
$presets[0].Name | Should -Be 'Minimal'
|
|
$presets[0].AppIds -is [array] | Should -BeTrue
|
|
$presets[0].AppIds | Should -Be 'One.App'
|
|
}
|
|
|
|
It 'returns empty collections and reports malformed JSON' {
|
|
'not json' | Set-Content -LiteralPath $script:AppsListFilePath
|
|
Mock Write-Error {}
|
|
Mock Write-Warning {}
|
|
|
|
@(Import-AppDetailsFromJson) | Should -HaveCount 0
|
|
@(Import-AppPresetsFromJson) | Should -HaveCount 0
|
|
Should -Invoke Write-Error -Times 1 -Exactly
|
|
Should -Invoke Write-Warning -Times 1 -Exactly
|
|
}
|
|
}
|