Public/Tests/New-IntuneWin32AppPackage.Tests.ps1
|
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.intune.packaging.psd1') -Force . (Join-Path -Path $PSScriptRoot -ChildPath '../../../../tests/TestHelpers/New-TestIntuneWin.ps1') } AfterAll { Remove-Module -Name tcs.intune.packaging -Force -ErrorAction SilentlyContinue } Describe 'New-IntuneWin32AppPackage' { BeforeEach { $Source = Join-Path -Path $TestDrive -ChildPath ([guid]::NewGuid().ToString()) $null = New-Item -Path $Source -ItemType Directory Set-Content -Path (Join-Path -Path $Source -ChildPath 'setup.exe') -Value 'x' $Output = Join-Path -Path $TestDrive -ChildPath ([guid]::NewGuid().ToString()) $null = New-Item -Path $Output -ItemType Directory $Tool = Join-Path -Path $TestDrive -ChildPath 'IntuneWinAppUtil.exe' Set-Content -Path $Tool -Value 'x' # Stands in for IntuneWinAppUtil.exe: writes a real .intunewin (zip with Detection.xml) Mock -ModuleName tcs.intune.packaging Invoke-Executable { $null = New-TestIntuneWin -Path (Join-Path -Path $Output -ChildPath 'setup.intunewin') -ContentSize 2048 [PSCustomObject]@{ ExitCode = 0; StandardOutput = $null; StandardError = $null } } Mock -ModuleName tcs.intune.packaging Get-IntunePackagingTool { } Mock -ModuleName tcs.intune.packaging Confirm-ToolDownload { $false } } It 'Returns the package details read from the package metadata' { $result = New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output -IntuneWinAppUtilPath $Tool $result.Path | Should -Be (Join-Path -Path $Output -ChildPath 'setup.intunewin') $result.Name | Should -Be 'setup.exe' $result.FileName | Should -Be 'IntunePackage.intunewin' $result.SetupFile | Should -Be 'setup.exe' $result.UnencryptedContentSize | Should -Be 2000 Should -Invoke -ModuleName tcs.intune.packaging Invoke-Executable -Times 1 -Exactly -ParameterFilter { $FilePath -eq $Tool -and $Arguments -like '*-q' } } It 'Does not use the optional IntuneWin32App module' { (Get-Command -Name New-IntuneWin32AppPackage).Definition | Should -Not -Match 'Get-IntuneWin32AppMetaData' } It 'Removes a trailing separator from the output folder so it cannot escape the closing quote' { $null = New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder "$Output$([System.IO.Path]::DirectorySeparatorChar)" -IntuneWinAppUtilPath $Tool Should -Invoke -ModuleName tcs.intune.packaging Invoke-Executable -Times 1 -Exactly -ParameterFilter { $Arguments -like "*-o `"$Output`" -q" } } It 'Writes a non-terminating error and does not overwrite an existing package without -Force' { Set-Content -Path (Join-Path -Path $Output -ChildPath 'setup.intunewin') -Value 'old' $result = New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output -IntuneWinAppUtilPath $Tool -ErrorVariable pkgError -ErrorAction SilentlyContinue $result | Should -BeNullOrEmpty "$pkgError" | Should -Match '-Force' Should -Invoke -ModuleName tcs.intune.packaging Invoke-Executable -Times 0 -Exactly $null = New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output -IntuneWinAppUtilPath $Tool -Force Should -Invoke -ModuleName tcs.intune.packaging Invoke-Executable -Times 1 -Exactly } It 'Throws when the setup file is not in the source folder' { { New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'missing.exe' -OutputFolder $Output -IntuneWinAppUtilPath $Tool } | Should -Throw '*missing.exe*' } It 'Throws when the source or output folder does not exist' { { New-IntuneWin32AppPackage -SourceFolder (Join-Path -Path $TestDrive -ChildPath 'nope') -SetupFile 'setup.exe' -OutputFolder $Output -IntuneWinAppUtilPath $Tool } | Should -Throw '*source folder*' { New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder (Join-Path -Path $TestDrive -ChildPath 'nope') -IntuneWinAppUtilPath $Tool } | Should -Throw '*output folder*' } It 'Throws when IntuneWinAppUtil.exe fails' { Mock -ModuleName tcs.intune.packaging Invoke-Executable { [PSCustomObject]@{ ExitCode = 2; StandardOutput = ''; StandardError = 'bad setup' } } { New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output -IntuneWinAppUtilPath $Tool } | Should -Throw '*exit code 2*bad setup*' } It 'Creates nothing with -WhatIf' { $null = New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output -IntuneWinAppUtilPath $Tool -WhatIf Should -Invoke -ModuleName tcs.intune.packaging Invoke-Executable -Times 0 -Exactly } Context 'Finding and downloading IntuneWinAppUtil.exe' { It 'Uses the default tool when only a literal path test finds it (no download)' { # Test-Path -Path treats [ ] as wildcards; the old check used -or and downloaded the tool anyway $bracketFolder = Join-Path -Path $TestDrive -ChildPath 'tools[1]' $null = New-Item -Path $bracketFolder -ItemType Directory -Force $bracketTool = Join-Path -Path $bracketFolder -ChildPath 'IntuneWinAppUtil.exe' Set-Content -LiteralPath $bracketTool -Value 'x' Mock -ModuleName tcs.intune.packaging Get-IntuneWinAppUtilPath { $bracketTool } $null = New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output Should -Invoke -ModuleName tcs.intune.packaging Get-IntunePackagingTool -Times 0 -Exactly Should -Invoke -ModuleName tcs.intune.packaging Confirm-ToolDownload -Times 0 -Exactly Should -Invoke -ModuleName tcs.intune.packaging Invoke-Executable -Times 1 -Exactly -ParameterFilter { $FilePath -eq $bracketTool } } It 'Asks before downloading a missing tool and stops when the download is declined' { $missing = Join-Path -Path $TestDrive -ChildPath 'no-tool/IntuneWinAppUtil.exe' Mock -ModuleName tcs.intune.packaging Get-IntuneWinAppUtilPath { $missing } { New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output } | Should -Throw '*-AllowDownload*' Should -Invoke -ModuleName tcs.intune.packaging Confirm-ToolDownload -Times 1 -Exactly Should -Invoke -ModuleName tcs.intune.packaging Get-IntunePackagingTool -Times 0 -Exactly Should -Invoke -ModuleName tcs.intune.packaging Invoke-Executable -Times 0 -Exactly } It 'Downloads the pinned release without asking with -AllowDownload' { $missing = Join-Path -Path $TestDrive -ChildPath 'download/IntuneWinAppUtil.exe' Mock -ModuleName tcs.intune.packaging Get-IntuneWinAppUtilPath { $missing } Mock -ModuleName tcs.intune.packaging Get-IntunePackagingTool { [System.IO.FileInfo]$Tool } $null = New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output -AllowDownload Should -Invoke -ModuleName tcs.intune.packaging Confirm-ToolDownload -Times 0 -Exactly Should -Invoke -ModuleName tcs.intune.packaging Get-IntunePackagingTool -Times 1 -Exactly -ParameterFilter { $DownloadTag -eq 'v1.8.6' -and $Path -eq (Split-Path -Path $missing -Parent) } } It 'Does not download when an explicit IntuneWinAppUtilPath is missing' { { New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output -IntuneWinAppUtilPath (Join-Path -Path $TestDrive -ChildPath 'x/IntuneWinAppUtil.exe') -AllowDownload } | Should -Throw '*was not found*' Should -Invoke -ModuleName tcs.intune.packaging Get-IntunePackagingTool -Times 0 -Exactly } } Context 'Telemetry' { BeforeEach { Mock -ModuleName tcs.intune.packaging Invoke-TelemetryCollection { } } It 'Reports a failed End when packaging fails' { { New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'missing.exe' -OutputFolder $Output -IntuneWinAppUtilPath $Tool } | Should -Throw Should -Invoke -ModuleName tcs.intune.packaging Invoke-TelemetryCollection -Times 1 -Exactly -ParameterFilter { $Stage -eq 'End' -and $Failed -eq $true } Should -Invoke -ModuleName tcs.intune.packaging Invoke-TelemetryCollection -Times 0 -Exactly -ParameterFilter { $Stage -eq 'End' -and -not $Failed } } It 'Reports a failed End when the package exists and -Force is not used' { Set-Content -Path (Join-Path -Path $Output -ChildPath 'setup.intunewin') -Value 'old' $null = New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output -IntuneWinAppUtilPath $Tool -ErrorAction SilentlyContinue Should -Invoke -ModuleName tcs.intune.packaging Invoke-TelemetryCollection -Times 1 -Exactly -ParameterFilter { $Stage -eq 'End' -and $Failed -eq $true } Should -Invoke -ModuleName tcs.intune.packaging Invoke-TelemetryCollection -Times 0 -Exactly -ParameterFilter { $Stage -eq 'End' -and -not $Failed } } It 'Reports a successful End' { $null = New-IntuneWin32AppPackage -SourceFolder $Source -SetupFile 'setup.exe' -OutputFolder $Output -IntuneWinAppUtilPath $Tool Should -Invoke -ModuleName tcs.intune.packaging Invoke-TelemetryCollection -Times 1 -Exactly -ParameterFilter { $Stage -eq 'End' -and -not $Failed } } } } |