MSIX.Tests/MSIX.v0_11.Tests.ps1
|
BeforeAll { Import-Module (Resolve-Path (Join-Path $PSScriptRoot '..\MSIX.psd1')) -Force } AfterAll { Remove-Module MSIX -ErrorAction SilentlyContinue } Describe 'PSF builders added in v0.11' -Tag 'Builders' { Context 'New-MsixPsfDynamicLibraryConfig' { It 'Returns DynamicLibraryFixup.dll' { $r = New-MsixPsfDynamicLibraryConfig -Mappings @( @{ name='liba.dll'; filepath='VFS/ProgramFilesX64/App/lib/liba.dll' } ) $r.dll | Should -Be 'DynamicLibraryFixup.dll' } It 'Throws on missing fields' { { New-MsixPsfDynamicLibraryConfig -Mappings @(@{ name='liba.dll' }) } | Should -Throw '*filepath*' { New-MsixPsfDynamicLibraryConfig -Mappings @(@{ filepath='x' }) } | Should -Throw '*name*' } It 'Preserves order in relativePaths' { $r = New-MsixPsfDynamicLibraryConfig -Mappings @( @{ name='a.dll'; filepath='lib/a.dll' } @{ name='b.dll'; filepath='lib/b.dll' } ) $r.config.relativePaths.Count | Should -Be 2 $r.config.relativePaths[0].name | Should -Be 'a.dll' } } Context 'New-MsixPsfWaitForDebuggerConfig' { It 'Returns WaitForDebuggerFixup.dll' { (New-MsixPsfWaitForDebuggerConfig).dll | Should -Be 'WaitForDebuggerFixup.dll' } It 'Includes processes when given' { $r = New-MsixPsfWaitForDebuggerConfig -Processes 'app','launcher' $r.config.processes.Count | Should -Be 2 $r.config.processes[0].executable | Should -Be 'app' } It 'Empty config when no processes' { $r = New-MsixPsfWaitForDebuggerConfig $r.config.Keys | Should -Not -Contain 'processes' } } } Describe '-NoSign alias: <Name>' -Tag 'NoSign' -ForEach @( @{ Name = 'Add-MsixPsfV2' } @{ Name = 'Add-MsixCapability' } @{ Name = 'Remove-MsixUninstallerArtifact' } @{ Name = 'Add-MsixSplashScreen' } @{ Name = 'Update-MsixPackageVersion' } @{ Name = 'Add-MsixVcRuntimeBundle' } @{ Name = 'Set-MsixFileSystemWriteVirtualization' } @{ Name = 'Set-MsixRegistryWriteVirtualization' } @{ Name = 'Set-MsixInstalledLocationVirtualization' } @{ Name = 'Add-MsixLoaderSearchPathOverride' } @{ Name = 'Add-MsixFirewallRule' } @{ Name = 'Add-MsixProtocolHandler' } @{ Name = 'Add-MsixFileTypeAssociation' } @{ Name = 'Add-MsixStartupTask' } @{ Name = 'Add-MsixFontExtension' } @{ Name = 'Set-MsixBrandMetadata' } @{ Name = 'Remove-MsixDesktopShortcut' } ) { It 'has -NoSign alias' { $cmd = Get-Command $Name -Module MSIX -ErrorAction SilentlyContinue $cmd | Should -Not -BeNullOrEmpty $skip = $cmd.Parameters['SkipSigning'] $skip | Should -Not -BeNullOrEmpty $skip.Aliases | Should -Contain 'NoSign' } } Describe 'Get-MsixManifest is polymorphic (v0.11)' -Tag 'Manifest' { BeforeAll { $script:Tmp = Join-Path $env:TEMP "msix-mf-poly-$([guid]::NewGuid().ToString('N').Substring(0,8))" New-Item $script:Tmp -ItemType Directory -Force | Out-Null } AfterAll { Remove-Item $script:Tmp -Recurse -Force -ErrorAction SilentlyContinue } It 'Reads an XML file directly' { $xmlPath = Join-Path $script:Tmp 'AppxManifest.xml' @' <?xml version="1.0" encoding="utf-8"?> <Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"> <Identity Name="A" Publisher="CN=X" Version="1.0.0.0" /> <Applications><Application Id="A" Executable="x.exe" /></Applications> </Package> '@ | Set-Content $xmlPath $m = Get-MsixManifest -Path $xmlPath $m.Package.Identity.Name | Should -Be 'A' } It 'Reads a folder containing AppxManifest.xml' { $m = Get-MsixManifest -Path $script:Tmp $m.Package.Identity.Name | Should -Be 'A' } It 'Throws cleanly on a non-existent path' { { Get-MsixManifest -Path (Join-Path $script:Tmp 'no-such-thing.xml') } | Should -Throw '*Path not found*' } } Describe 'Auto-fix planner (v0.11)' -Tag 'AutoFix' { It 'Invoke-MsixAutoFixFromAnalysis -DryRun returns an empty plan when there are no findings' { $stub = [pscustomobject]@{ PackagePath = 'C:\nope.msix' Findings = @() SuggestedFixups = @() } $r = Invoke-MsixAutoFixFromAnalysis -Report $stub -DryRun $r.Plan.Count | Should -Be 0 } It 'Plans RemoveUninstallers when an UninstallerArtifact finding exists' { $stub = [pscustomobject]@{ PackagePath = 'C:\nope.msix' Findings = @( [pscustomobject]@{ Severity='Warning'; Category='UninstallerArtifact'; Symptom='x'; Recommendation='y'; Evidence='z' } ) SuggestedFixups = @() } $r = Invoke-MsixAutoFixFromAnalysis -Report $stub -DryRun $r.Plan.Stage | Should -Contain 'RemoveUninstallers' } It 'Plans manifest fixes from ManifestFix:* findings' { $stub = [pscustomobject]@{ PackagePath = 'C:\nope.msix' Findings = @( [pscustomobject]@{ Severity='Info'; Category='ManifestFix:FileSystemWriteVirtualization'; Symptom='x'; Recommendation='y'; Evidence='z' } [pscustomobject]@{ Severity='Info'; Category='ManifestFix:RegistryWriteVirtualization'; Symptom='x'; Recommendation='y'; Evidence='z' } ) SuggestedFixups = @() } $r = Invoke-MsixAutoFixFromAnalysis -Report $stub -DryRun $r.Plan.Stage | Should -Contain 'FileSystemWriteVirtualization' $r.Plan.Stage | Should -Contain 'RegistryWriteVirtualization' } It 'Skips PSF when -PreferManifestOverPsf and a manifest fix covers the same symptom' { $stub = [pscustomobject]@{ PackagePath = 'C:\nope.msix' Findings = @( [pscustomobject]@{ Severity='Info'; Category='ManifestFix:FileSystemWriteVirtualization'; Symptom='x'; Recommendation='y'; Evidence='z' } ) SuggestedFixups = @( New-MsixPsfFileRedirectionConfig -Base 'logs' -Patterns '.*\.log' ) } $r = Invoke-MsixAutoFixFromAnalysis -Report $stub -DryRun -PreferManifestOverPsf $true $r.Plan.Stage | Should -Not -Contain 'InjectPsf' } It 'Includes PSF when -PreferManifestOverPsf $false' { $stub = [pscustomobject]@{ PackagePath = 'C:\nope.msix' Findings = @( [pscustomobject]@{ Severity='Info'; Category='ManifestFix:FileSystemWriteVirtualization'; Symptom='x'; Recommendation='y'; Evidence='z' } ) SuggestedFixups = @( New-MsixPsfFileRedirectionConfig -Base 'logs' -Patterns '.*\.log' ) } $r = Invoke-MsixAutoFixFromAnalysis -Report $stub -DryRun -PreferManifestOverPsf $false $r.Plan.Stage | Should -Contain 'InjectPsf' } It 'Skips StartupTask when -StartupTaskAppId / -StartupTaskName missing' { $stub = [pscustomobject]@{ PackagePath = 'C:\nope.msix' Findings = @( [pscustomobject]@{ Severity='Info'; Category='ManifestFix:StartupTask'; Symptom='x'; Recommendation='y'; Evidence='z' } ) SuggestedFixups = @() } $r = Invoke-MsixAutoFixFromAnalysis -Report $stub -DryRun $r.Plan.Stage | Should -Not -Contain 'StartupTask' } It 'Plans StartupTask when params supplied' { $stub = [pscustomobject]@{ PackagePath = 'C:\nope.msix' Findings = @( [pscustomobject]@{ Severity='Info'; Category='ManifestFix:StartupTask'; Symptom='x'; Recommendation='y'; Evidence='z' } ) SuggestedFixups = @() } $r = Invoke-MsixAutoFixFromAnalysis -Report $stub -DryRun ` -StartupTaskAppId 'App' -StartupTaskName 'Demo' $r.Plan.Stage | Should -Contain 'StartupTask' } } |