Public/Tests/Get-MsiSequence.Tests.ps1
|
BeforeDiscovery { # Windows PowerShell 5.1 has no $IsWindows variable and only runs on Windows $IsWindowsHost = ($PSVersionTable.PSEdition -eq 'Desktop') -or $IsWindows $IsWindowsElevated = $false if ($IsWindowsHost) { $principal = New-Object -TypeName System.Security.Principal.WindowsPrincipal -ArgumentList ([System.Security.Principal.WindowsIdentity]::GetCurrent()) $IsWindowsElevated = $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) } } BeforeAll { $env:TCS_CONFIG_ROOT = Join-Path -Path $TestDrive -ChildPath 'config' $env:TCS_SKIP_UPDATE_CHECK = '1' $env:TCS_TELEMETRY_OPTOUT = '1' $ModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent Import-Module -Name (Join-Path -Path $ModuleRoot -ChildPath 'tcs.utils.psd1') -Force } AfterAll { Remove-Module -Name tcs.utils -Force -ErrorAction SilentlyContinue } Describe 'Get-MsiSequence' { BeforeAll { $FunctionPath = Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -ChildPath 'Get-MsiSequence.ps1' } It 'Uses only syntax that Windows PowerShell 5.1 can parse' { $tokens = $null $errors = $null $null = [System.Management.Automation.Language.Parser]::ParseFile($FunctionPath, [ref]$tokens, [ref]$errors) $errors | Should -BeNullOrEmpty @($tokens | Where-Object { $_.Text -in @('??', '??=', '?.', '?[') }) | Should -BeNullOrEmpty } It 'Lets -SequenceTable be combined with the display switches' { $parameters = (Get-Command -Name Get-MsiSequence).Parameters $parameters['SequenceTable'].ParameterSets.Keys | Should -Contain 'All' $parameters['ShowSequences'].ParameterSets.Keys | Should -Contain 'All' } It 'Rejects a path that does not exist' { { Get-MsiSequence -MsiPath (Join-Path -Path $TestDrive -ChildPath 'missing.msi') } | Should -Throw '*File not found*' } It 'Rejects a file that is not an .msi' { $notMsi = Join-Path -Path $TestDrive -ChildPath 'setup.exe' Set-Content -Path $notMsi -Value 'x' { Get-MsiSequence -MsiPath $notMsi } | Should -Throw '*not an MSI*' } It 'Throws a clear error on non-Windows platforms' -Skip:$IsWindowsHost { $msi = Join-Path -Path $TestDrive -ChildPath 'package.msi' Set-Content -Path $msi -Value 'x' { Get-MsiSequence -MsiPath $msi } | Should -Throw '*requires Windows*' } It 'Writes an error, without throwing, for a file that is not a valid MSI database' -Skip:(-not $IsWindowsHost) { $msi = Join-Path -Path $TestDrive -ChildPath 'invalid.msi' Set-Content -Path $msi -Value 'this is not an MSI database' { Get-MsiSequence -MsiPath $msi -ShowFiles -ErrorVariable msiErrors -ErrorAction SilentlyContinue } | Should -Not -Throw $output = Get-MsiSequence -MsiPath $msi -ErrorVariable msiErrors -ErrorAction SilentlyContinue $output | Should -BeNullOrEmpty $msiErrors | Should -Not -BeNullOrEmpty } It 'Quotes the MSI and target paths passed to msiexec when extracting' -Skip:(-not $IsWindowsElevated) { $folder = Join-Path -Path $TestDrive -ChildPath 'with space' $null = New-Item -Path $folder -ItemType Directory -Force $msi = Join-Path -Path $folder -ChildPath 'my package.msi' Set-Content -Path $msi -Value 'x' $target = Join-Path -Path $folder -ChildPath 'extract here' $null = New-Item -Path $target -ItemType Directory -Force Mock -ModuleName tcs.utils Start-Process { [PSCustomObject]@{ ExitCode = 0 } } Get-MsiSequence -MsiPath $msi -ExtractTo $target -InformationAction SilentlyContinue Should -Invoke -ModuleName tcs.utils Start-Process -Times 1 -Exactly -ParameterFilter { ($ArgumentList -join ' ') -like '/a "*my package.msi" /qb TARGETDIR="*extract here"' } } } |