winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

Microsoft.WinGet.Configuration.Tests.ps1 (41685B)


      1 # Copyright (c) Microsoft Corporation. All rights reserved.
      2 # Licensed under the MIT License.
      3 
      4 <#
      5 .Synopsis
      6    Pester tests related to the Microsoft.WinGet.Configuration PowerShell module.
      7    'Invoke-Pester' should be called in an admin PowerShell window.
      8    Requires local test repo to be setup.
      9 #>
     10 [CmdletBinding()]
     11 param(
     12     # The location of the test data
     13     [string]$ConfigurationTestDataPath
     14 )
     15 
     16 BeforeAll {
     17     $env:POWERSHELL_TELEMETRY_OPTOUT = "true"
     18     $deviceGroupPolicyRoot = "HKLM:\Software\Policies\Microsoft\Windows"
     19     $wingetPolicyKeyName = "AppInstaller"
     20     $wingetGroupPolicyRegistryRoot = $deviceGroupPolicyRoot + "\" + $wingetPolicyKeyName
     21     $e2eTestModule = "xE2ETestResource"
     22 
     23     Import-Module Microsoft.WinGet.Configuration
     24 
     25     # TODO: Installing within the test run on the build server (only) somehow causes below error:
     26     #       [CORE] Started MSStore package execution. ProductId: 9PCX3HX4HZ0Z PackageFamilyName: Microsoft.DesiredStateConfiguration-Preview_8wekyb3d8bbwe
     27     #       [CLI ] MSStore install failed. ProductId: 9PCX3HX4HZ0Z HResult: 0x80010002
     28     #       So install the DSCv3 package here.
     29     Import-Module Microsoft.WinGet.Client
     30     $installResult = Install-WingetPackage -Id 9PCX3HX4HZ0Z -Source msstore
     31     if ($installResult.Status -ne 'Ok')
     32     {
     33         Write-Error "Failed to install DSCv3 package. Status: $($installResult.Status). ExtendedErrorCode: $($installResult.ExtendedErrorCode)." -ErrorAction Stop
     34     }
     35 
     36     function CreatePolicyKeyIfNotExists()
     37     {
     38         $registryExists = test-path  -Path $wingetGroupPolicyRegistryRoot
     39 
     40         if(-Not($registryExists))
     41         {
     42             New-Item -Path $deviceGroupPolicyRoot -Name $wingetPolicyKeyName
     43         }
     44     }
     45 
     46     function CleanupGroupPolicyKeyIfExists()
     47     {
     48         $registryExists = test-path  -Path $wingetGroupPolicyRegistryRoot
     49 
     50         if($registryExists)
     51         {
     52             Remove-Item -Path  $wingetGroupPolicyRegistryRoot -Recurse
     53         }
     54     }
     55 
     56     function CleanupGroupPolicies()
     57     {
     58         $registryExists = test-path  -Path $wingetGroupPolicyRegistryRoot
     59 
     60         if($registryExists)
     61         {
     62             Remove-ItemProperty -Path $wingetGroupPolicyRegistryRoot -Name *
     63         }
     64     }
     65 
     66     if ([System.String]::IsNullOrEmpty($ConfigurationTestDataPath))
     67     {
     68         $ConfigurationTestDataPath = (Join-Path $PSScriptRoot "..\..\AppInstallerCLIE2ETests\TestData\Configuration\")
     69     }
     70 
     71     function GetConfigTestDataPath()
     72     {
     73         return $ConfigurationTestDataPath
     74     }
     75 
     76     function DeleteConfigTxtFiles()
     77     {
     78         Get-ChildItem $(GetConfigTestDataPath) -Filter *.txt -Recurse | ForEach-Object { Remove-Item $_ }
     79     }
     80 
     81     function GetConfigTestDataFile([string] $fileName)
     82     {
     83         $path = Join-Path $(GetConfigTestDataPath) $fileName
     84 
     85         if (-not (Test-Path $path))
     86         {
     87             throw "$path does not exists"
     88         }
     89 
     90         return $path
     91     }
     92 
     93     enum TestModuleLocation
     94     {
     95         CurrentUser
     96         AllUsers
     97         Custom
     98         DefaultLocation
     99     }
    100 
    101     function GetExpectedModulePath([TestModuleLocation]$testModuleLocation)
    102     {
    103         switch ($testModuleLocation)
    104         {
    105             ([TestModuleLocation]::CurrentUser)
    106             {
    107                 $path = [Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments)
    108                 return Join-Path $path "PowerShell\Modules"
    109             }
    110             ([TestModuleLocation]::AllUsers)
    111             {
    112                 $path = [Environment]::GetFolderPath([Environment+SpecialFolder]::ProgramFiles)
    113                 return Join-Path $path "PowerShell\Modules"
    114             }
    115             ([TestModuleLocation]::DefaultLocation)
    116             {
    117                 $path = [Environment]::GetFolderPath([Environment+SpecialFolder]::LocalApplicationData)
    118                 return Join-Path $path "Microsoft\WinGet\Configuration\Modules"
    119             }
    120             ([TestModuleLocation]::Custom)
    121             {
    122                 return Join-Path $env:TEMP "E2EPesterCustomModules"
    123             }
    124             default
    125             {
    126                 throw $testModuleLocation
    127             }
    128         }
    129     }
    130 
    131     function CleanupPsModulePath()
    132     {
    133         $wingetPath = GetExpectedModulePath DefaultLocation
    134         $customPath = GetExpectedModulePath Custom
    135         $modulePath = $env:PsModulePath
    136         $newModulePath = ($modulePath.Split(';') | Where-Object { $_ -ne $wingetPath } | Where-Object { $_ -ne $customPath }) -join ';'
    137         $env:PsModulePath = $newModulePath
    138     }
    139 
    140     function EnsureModuleState([string]$moduleName, [bool]$present, [string]$repository = $null, [TestModuleLocation]$testModuleLocation = [TestModuleLocation]::CurrentUser)
    141     {
    142         CleanupPsModulePath
    143         $wingetPath = GetExpectedModulePath DefaultLocation
    144         $customPath = GetExpectedModulePath Custom
    145         $env:PsModulePath += ";$wingetPath;$customPath"
    146 
    147         $availableModules = Get-Module $moduleName -ListAvailable
    148         $isPresent = $null -ne $availableModules
    149 
    150         if ($isPresent)
    151         {
    152             foreach ($module in $availableModules)
    153             {
    154                 try
    155                 {
    156                     $item = Get-Item $module.Path -ErrorAction Stop
    157                     while ($item.Name -ne $moduleName)
    158                     {
    159                         $item = Get-Item $item.PSParentPath -ErrorAction Stop
    160                     }
    161 
    162                     if (-not $present)
    163                     {
    164                         Get-ChildItem $item.FullName -Recurse | Remove-Item -Force -Recurse -ErrorAction Stop
    165                         Remove-Item $item -ErrorAction Stop
    166                     }
    167                     else
    168                     {
    169                         # Must be in the right location
    170                         $expected = GetExpectedModulePath $testModuleLocation
    171                         if ($expected -ne $item.Parent.FullName)
    172                         {
    173                             Get-ChildItem $item.FullName -Recurse | Remove-Item -Force -Recurse -ErrorAction Stop
    174                             Remove-Item $item -ErrorAction Stop
    175                             $isPresent = $false
    176                         }
    177                     }
    178                 }
    179                 catch [System.Management.Automation.ItemNotFoundException]
    180                 {
    181                     Write-Host "Item not found, ignoring..." $_.Exception.Message
    182                 }
    183             }
    184         }
    185 
    186         if ((-not $isPresent) -and $present)
    187         {
    188             $params = @{
    189                 Name = $moduleName
    190                 Force = $true
    191             }
    192 
    193             if (-not [string]::IsNullOrEmpty($repository))
    194             {
    195                 $params.Add('Repository', $repository)
    196             }
    197 
    198             if (($testModuleLocation -eq [TestModuleLocation]::CurrentUser) -or
    199                 ($testModuleLocation -eq [TestModuleLocation]::AllUsers))
    200             {
    201                 if ($testModuleLocation -eq [TestModuleLocation]::AllUsers)
    202                 {
    203                     $params.Add('Scope', 'AllUsers')
    204                 }
    205 
    206                 Install-Module @params
    207             }
    208             else
    209             {
    210                 $path = $customPath
    211                 if (($testModuleLocation -eq [TestModuleLocation]::WinGetModulePath) -or
    212                     ($testModuleLocation -eq [TestModuleLocation]::DefaultLocation))
    213                 {
    214                     $path = $wingetPath
    215                 }
    216                 $params.Add('Path', $path)
    217 
    218                 Save-Module @params
    219             }
    220         }
    221 
    222         CleanupPsModulePath
    223     }
    224 
    225     function EnsureDSCv3TestResourcePresence()
    226     {
    227         $localAppDataPath = [Environment]::GetFolderPath([Environment+SpecialFolder]::LocalApplicationData)
    228         $resourcePath = Join-Path $localAppDataPath "Microsoft\WindowsApps\test-file.dsc.resource.json"
    229         if (-not (Test-Path $resourcePath))
    230         {
    231             wingetdev dscv3 test-file --manifest -o $resourcePath
    232         }
    233     }
    234 }
    235 
    236 Describe 'Test-GroupPolicies' {
    237     BeforeAll {
    238         CleanupGroupPolicies
    239         CreatePolicyKeyIfNotExists
    240     }
    241 
    242     It "Disable WinGetPolicy and run Get-WinGetConfiguration" {
    243 
    244         $policyKeyValueName =  "EnableAppInstaller"
    245 
    246         Set-ItemProperty -Path $wingetGroupPolicyRegistryRoot -Name $policyKeyValueName -Value 0
    247         $registryKey  =  Get-ItemProperty -Path $wingetGroupPolicyRegistryRoot -Name $policyKeyValueName
    248         $registryKey | Should -Not -BeNullOrEmpty
    249         $registryKey.EnableAppInstaller | Should -Be 0
    250 
    251         # [NOTE:] We don't need a valid yml file path to test Group Policy blocking scenario as it is the earliest check, 
    252         # so just using some random file path for this test.
    253         { Get-WinGetConfiguration -File "Z:\NonExisting_SettingsFile.yml" } | Should -Throw "This operation is disabled by Group Policy : Enable Windows Package Manager"
    254 
    255         CleanupGroupPolicies
    256     }
    257 
    258     It "Disable EnableWindowsPackageManagerCommandLineInterfaces Policy and run Get-WinGetConfiguration" {
    259        $policyKeyValueName =  "EnableWindowsPackageManagerCommandLineInterfaces"
    260 
    261         Set-ItemProperty -Path $wingetGroupPolicyRegistryRoot -Name $policyKeyValueName -Value 0
    262         $registryKey  =  Get-ItemProperty -Path $wingetGroupPolicyRegistryRoot -Name $policyKeyValueName
    263         $registryKey | Should -Not -BeNullOrEmpty
    264         $registryKey.EnableWindowsPackageManagerCommandLineInterfaces | Should -Be 0
    265 
    266         # [NOTE:] We don't  need a valid yml file path to test Group Policy blocking scenario as it is the earliest check, 
    267         # so just using some random file path for this test.
    268         { Get-WinGetConfiguration -File "Z:\NonExisting_SettingsFile.yml" } | Should -Throw "This operation is disabled by Group Policy : Enable Windows Package Manager command line interfaces"
    269 
    270         CleanupGroupPolicies
    271     }
    272 
    273     It "Disable EnableWindowsPackageManagerConfiguration Policy and run Get-WinGetConfiguration" {
    274        $policyKeyValueName =  "EnableWindowsPackageManagerConfiguration"
    275 
    276         Set-ItemProperty -Path $wingetGroupPolicyRegistryRoot -Name $policyKeyValueName -Value 0
    277         $registryKey  =  Get-ItemProperty -Path $wingetGroupPolicyRegistryRoot -Name $policyKeyValueName
    278         $registryKey | Should -Not -BeNullOrEmpty
    279         $registryKey.EnableWindowsPackageManagerConfiguration | Should -Be 0
    280 
    281         # [NOTE:] We don't  need a valid yml file path to test Group Policy blocking scenario as it is the earliest check, 
    282         # so just using some random file path for this test.
    283         { Get-WinGetConfiguration -File "Z:\NonExisting_SettingsFile.yml" } | Should -Throw "This operation is disabled by Group Policy : Enable Windows Package Manager Configuration"
    284 
    285         CleanupGroupPolicies
    286     }
    287 
    288     AfterAll {
    289         CleanupGroupPolicies
    290         CleanupGroupPolicyKeyIfExists
    291     }
    292 }
    293 
    294 Describe 'Get configuration' {
    295 
    296     It 'Get configuration and details' {
    297         EnsureModuleState $e2eTestModule $false
    298 
    299         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    300         $set = Get-WinGetConfiguration -File $testFile
    301         $set | Should -Not -BeNullOrEmpty
    302 
    303         $set = Get-WinGetConfigurationDetails -Set $set
    304         $set | Should -Not -BeNullOrEmpty
    305     }
    306 
    307     It 'Get configuration and details DSCv3' {
    308         EnsureDSCv3TestResourcePresence
    309 
    310         $testFile = GetConfigTestDataFile "ShowDetails_DSCv3.yml"
    311         $set = Get-WinGetConfiguration -File $testFile
    312         $set | Should -Not -BeNullOrEmpty
    313 
    314         $set = Get-WinGetConfigurationDetails -Set $set
    315         $set | Should -Not -BeNullOrEmpty
    316     }
    317 
    318     It 'Get details piped' {
    319         EnsureModuleState $e2eTestModule $false
    320 
    321         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    322         $set = Get-WinGetConfiguration -File $testFile | Get-WinGetConfigurationDetails
    323         $set | Should -Not -BeNullOrEmpty
    324     }
    325 
    326     It 'Get configuration and details positional' {
    327         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    328         $set = Get-WinGetConfiguration $testFile
    329         $set | Should -Not -BeNullOrEmpty
    330 
    331         $set = Get-WinGetConfigurationDetails $set
    332         $set | Should -Not -BeNullOrEmpty
    333     }
    334 
    335     It 'File doesnt exit' {
    336         $testFile = "c:\dir\fakeFile.txt"
    337         { Get-WinGetConfiguration -File $testFile } | Should -Throw $testFile
    338     }
    339 
    340     It 'Invalid file' {
    341         $testFile = GetConfigTestDataFile "Empty.yml"
    342         { Get-WinGetConfiguration -File $testFile } | Should -Throw "*0x8A15C002*"
    343     }
    344 
    345     It 'Missing property' {
    346         $testFile = GetConfigTestDataFile "NotConfig.yml"
    347         { Get-WinGetConfiguration -File $testFile } | Should -Throw '*0x8A15C00E*$schema*missing*'
    348     }
    349 
    350     It 'Missing configurationVersion' {
    351         $testFile = GetConfigTestDataFile "NoVersion.yml"
    352         { Get-WinGetConfiguration -File $testFile } | Should -Throw "*0x8A15C00E*configurationVersion*missing*"
    353     }
    354 
    355     It 'Unknown version' {
    356         $testFile = GetConfigTestDataFile "UnknownVersion.yml"
    357         { Get-WinGetConfiguration -File $testFile } | Should -Throw "*0x8A15C004*Configuration file version*is not known.*"
    358     }
    359 
    360     It 'Resource wrong type' {
    361         $testFile = GetConfigTestDataFile "ResourcesNotASequence.yml"
    362         { Get-WinGetConfiguration -File $testFile } | Should -Throw "*0x8A15C003*resources*wrong type*"
    363     }
    364 
    365     It 'Unit wrong type' {
    366         $testFile = GetConfigTestDataFile "UnitNotAMap.yml"
    367         { Get-WinGetConfiguration -File $testFile } | Should -Throw "*0x8A15C003*resources*0*wrong type*"
    368     }
    369 
    370     It 'No resource name' {
    371         $testFile = GetConfigTestDataFile "NoResourceName.yml"
    372         { Get-WinGetConfiguration -File $testFile } | Should -Throw "*0x8A15C00D*resource*invalid value*Module/*"
    373     }
    374 
    375     It 'Module mismatch' {
    376         $testFile = GetConfigTestDataFile "ModuleMismatch.yml"
    377         { Get-WinGetConfiguration -File $testFile } | Should -Throw "*0x8A15C00D*invalid value*DifferentModule*"
    378     }
    379 }
    380 
    381 Describe 'Invoke-WinGetConfiguration' {
    382 
    383     BeforeEach {
    384         DeleteConfigTxtFiles
    385     }
    386     
    387 <# PS Gallery tests are unreliable.
    388     It 'From Gallery' {
    389         EnsureModuleState "XmlContentDsc" $false
    390 
    391         $testFile = GetConfigTestDataFile "PSGallery_NoModule_NoSettings.yml"
    392         $set = Get-WinGetConfiguration -File $testFile
    393         $set | Should -Not -BeNullOrEmpty
    394 
    395         $result = Invoke-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    396         $result | Should -Not -BeNullOrEmpty
    397         $result.ResultCode | Should -Be -1978286075
    398         $result.UnitResults.Count | Should -Be 1
    399         $result.UnitResults[0].State | Should -Be "Completed"
    400         $result.UnitResults[0].ResultCode | Should -Be -1978285819
    401     }
    402 #>
    403 
    404     It 'From TestRepo' {
    405         EnsureModuleState $e2eTestModule $false
    406 
    407         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    408         $set = Get-WinGetConfiguration -File $testFile
    409         $set | Should -Not -BeNullOrEmpty
    410 
    411         $result = Invoke-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    412         $result | Should -Not -BeNullOrEmpty
    413         $result.ResultCode | Should -Be 0
    414         $result.UnitResults.Count | Should -Be 1
    415         $result.UnitResults[0].State | Should -Be "Completed"
    416         $result.UnitResults[0].ResultCode | Should -Be 0
    417 
    418         $expectedFile = Join-Path $(GetConfigTestDataPath) "Configure_TestRepo.txt"
    419         Test-Path $expectedFile | Should -Be $true
    420         Get-Content $expectedFile -Raw | Should -Be "Contents!"
    421 
    422         $expectedModule = Join-Path $(GetExpectedModulePath DefaultLocation) $e2eTestModule
    423         Test-Path $expectedModule | Should -Be $true
    424     }
    425 
    426     It 'From TestRepo Location' -ForEach @(
    427         @{ Location = "CurrentUser"; }
    428         @{ Location = "AllUsers"; }
    429         @{ Location = "DefaultLocation"; }
    430         @{ Location = "Custom"; }) {
    431         $modulePath = "'"
    432         switch ($location)
    433         {
    434             ([TestModuleLocation]::CurrentUser)
    435             {
    436                 $modulePath = "currentuser"
    437                 break
    438             }
    439             ([TestModuleLocation]::AllUsers)
    440             {
    441                 $modulePath = "allusers"
    442                 break
    443             }
    444             ([TestModuleLocation]::DefaultLocation)
    445             {
    446                 $modulePath = "default"
    447                 break
    448             }
    449             ([TestModuleLocation]::Custom)
    450             {
    451                 $modulePath = GetExpectedModulePath Custom
    452                 break
    453             }
    454             default {
    455                 throw $location
    456             }
    457         }
    458     
    459         EnsureModuleState $e2eTestModule $false
    460 
    461         $testFile = GetConfigTestDataFile "Configure_TestRepo_Location.yml"
    462         $set = Get-WinGetConfiguration -File $testFile -ModulePath $modulePath
    463         $set | Should -Not -BeNullOrEmpty
    464 
    465         $result = Invoke-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    466         $result | Should -Not -BeNullOrEmpty
    467         $result.ResultCode | Should -Be 0
    468         $result.UnitResults.Count | Should -Be 1
    469         $result.UnitResults[0].State | Should -Be "Completed"
    470         $result.UnitResults[0].ResultCode | Should -Be 0
    471 
    472         $expectedModule = Join-Path $(GetExpectedModulePath $location) $e2eTestModule
    473         Test-Path $expectedModule | Should -Be $true
    474     }
    475 
    476     It 'From DSCv3' {
    477         EnsureDSCv3TestResourcePresence
    478 
    479         $testFile = GetConfigTestDataFile "ShowDetails_DSCv3.yml"
    480         $set = Get-WinGetConfiguration -File $testFile
    481         $set | Should -Not -BeNullOrEmpty
    482 
    483         $result = Invoke-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    484         $result | Should -Not -BeNullOrEmpty
    485         $result.ResultCode | Should -Be 0
    486         $result.UnitResults.Count | Should -Be 1
    487         $result.UnitResults[0].State | Should -Be "Completed"
    488         $result.UnitResults[0].ResultCode | Should -Be 0
    489 
    490         $expectedFile = Join-Path $(GetConfigTestDataPath) "ShowDetails_DSCv3.txt"
    491         Test-Path $expectedFile | Should -Be $true
    492         Get-Content $expectedFile -Raw | Should -Be "DSCv3 Contents!"
    493     }
    494 
    495     It 'Piped' {
    496         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    497         $result = Get-WinGetConfiguration -File $testFile | Invoke-WinGetConfiguration -AcceptConfigurationAgreements
    498         $result | Should -Not -BeNullOrEmpty
    499         $result.ResultCode | Should -Be 0
    500         $result.UnitResults.Count | Should -Be 1
    501         $result.UnitResults[0].State | Should -Be "Completed"
    502         $result.UnitResults[0].ResultCode | Should -Be 0
    503 
    504         $expectedFile = Join-Path $(GetConfigTestDataPath) "Configure_TestRepo.txt"
    505         Test-Path $expectedFile | Should -Be $true
    506         Get-Content $expectedFile -Raw | Should -Be "Contents!"
    507     }
    508 
    509     It 'Positional' {
    510         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    511         $set = Get-WinGetConfiguration $testFile
    512         $set | Should -Not -BeNullOrEmpty
    513 
    514         $result = Invoke-WinGetConfiguration -AcceptConfigurationAgreements $set
    515         $result | Should -Not -BeNullOrEmpty
    516         $result.ResultCode | Should -Be 0
    517         $result.UnitResults.Count | Should -Be 1
    518         $result.UnitResults[0].State | Should -Be "Completed"
    519         $result.UnitResults[0].ResultCode | Should -Be 0
    520 
    521         $expectedFile = Join-Path $(GetConfigTestDataPath) "Configure_TestRepo.txt"
    522         Test-Path $expectedFile | Should -Be $true
    523         Get-Content $expectedFile -Raw | Should -Be "Contents!"
    524     }
    525 
    526     It 'Independent Resource - One Failure' {
    527         $testFile = GetConfigTestDataFile "IndependentResources_OneFailure.yml"
    528         $set = Get-WinGetConfiguration -File $testFile
    529         $set | Should -Not -BeNullOrEmpty
    530 
    531         $result = Invoke-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    532         $result | Should -Not -BeNullOrEmpty
    533         $result.ResultCode | Should -Be -1978286075
    534         $result.UnitResults.Count | Should -Be 2
    535         $result.UnitResults[0].State | Should -Be "Completed"
    536         $result.UnitResults[0].ResultCode | Should -Be -1978285819
    537         $result.UnitResults[1].State | Should -Be "Completed"
    538         $result.UnitResults[1].ResultCode | Should -Be 0
    539 
    540         $expectedFile = Join-Path $(GetConfigTestDataPath) "IndependentResources_OneFailure.txt"
    541         Test-Path $expectedFile | Should -Be $true
    542         Get-Content $expectedFile -Raw | Should -Be "Contents!"
    543     }
    544 
    545     It 'Dependent Resource - Failure' {
    546         $testFile = GetConfigTestDataFile "DependentResources_Failure.yml"
    547         $set = Get-WinGetConfiguration -File $testFile
    548         $set | Should -Not -BeNullOrEmpty
    549 
    550         $result = Invoke-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    551         $result | Should -Not -BeNullOrEmpty
    552         $result.ResultCode | Should -Be -1978286075
    553         $result.UnitResults.Count | Should -Be 2
    554         $result.UnitResults[0].State | Should -Be "Completed"
    555         $result.UnitResults[0].ResultCode | Should -Be -1978285819
    556         $result.UnitResults[1].State | Should -Be "Skipped"
    557         $result.UnitResults[1].ResultCode | Should -Be -1978286072
    558 
    559         $expectedFile = Join-Path $(GetConfigTestDataPath) "DependentResources_Failure.txt"
    560         Test-Path $expectedFile | Should -Be $false
    561     }
    562 
    563     It 'ResourceCaseInsensitive' {
    564         $testFile = GetConfigTestDataFile "ResourceCaseInsensitive.yml"
    565         $set = Get-WinGetConfiguration -File $testFile
    566         $set | Should -Not -BeNullOrEmpty
    567 
    568         $result = Invoke-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    569         $result | Should -Not -BeNullOrEmpty
    570         $result.ResultCode | Should -Be 0
    571         $result.UnitResults.Count | Should -Be 1
    572         $result.UnitResults[0].State | Should -Be "Completed"
    573         $result.UnitResults[0].ResultCode | Should -Be 0
    574 
    575         $expectedFile = Join-Path $(GetConfigTestDataPath) "ResourceCaseInsensitive.txt"
    576         Test-Path $expectedFile | Should -Be $true
    577         Get-Content $expectedFile -Raw | Should -Be "Contents!"
    578     }
    579 }
    580 
    581 Describe 'Start|Complete-WinGetConfiguration' {
    582 
    583     BeforeEach {
    584         DeleteConfigTxtFiles
    585     }
    586     
    587 <# PS Gallery tests are unreliable.
    588     It 'From Gallery' {
    589         EnsureModuleState "XmlContentDsc" $false
    590 
    591         $testFile = GetConfigTestDataFile "PSGallery_NoModule_NoSettings.yml"
    592         $set = Get-WinGetConfiguration -File $testFile
    593         $set | Should -Not -BeNullOrEmpty
    594 
    595         $job = Start-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    596         $job | Should -Not -BeNullOrEmpty
    597 
    598         $result = Complete-WinGetConfiguration -ConfigurationJob $job
    599         $result | Should -Not -BeNullOrEmpty
    600         $result.ResultCode | Should -Be -1978286075
    601         $result.UnitResults.Count | Should -Be 1
    602         $result.UnitResults[0].State | Should -Be "Completed"
    603         $result.UnitResults[0].ResultCode | Should -Be -1978285819
    604     }
    605 #>
    606 
    607     It 'From TestRepo' {
    608         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    609         $set = Get-WinGetConfiguration -File $testFile
    610         $set | Should -Not -BeNullOrEmpty
    611 
    612         $job = Start-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    613         $job | Should -Not -BeNullOrEmpty
    614 
    615         $result = Complete-WinGetConfiguration -ConfigurationJob $job
    616         $result | Should -Not -BeNullOrEmpty
    617         $result.ResultCode | Should -Be 0
    618         $result.UnitResults.Count | Should -Be 1
    619         $result.UnitResults[0].State | Should -Be "Completed"
    620         $result.UnitResults[0].ResultCode | Should -Be 0
    621 
    622         $expectedFile = Join-Path $(GetConfigTestDataPath) "Configure_TestRepo.txt"
    623         Test-Path $expectedFile | Should -Be $true
    624         Get-Content $expectedFile -Raw | Should -Be "Contents!"
    625 
    626         # Verify can't be used after.
    627         { Start-WinGetConfiguration -AcceptConfigurationAgreements -Set $set } | Should -Throw "Operation is not valid due to the current state of the object."
    628     }
    629 
    630     It 'From TestRepo Location' -ForEach @(
    631         @{ Location = "CurrentUser"; }
    632         @{ Location = "AllUsers"; }
    633         @{ Location = "DefaultLocation"; }
    634         @{ Location = "Custom"; }) {
    635         $modulePath = "'"
    636         switch ($location)
    637         {
    638             ([TestModuleLocation]::CurrentUser)
    639             {
    640                 $modulePath = "currentuser"
    641                 break
    642             }
    643             ([TestModuleLocation]::AllUsers)
    644             {
    645                 $modulePath = "allusers"
    646                 break
    647             }
    648             ([TestModuleLocation]::DefaultLocation)
    649             {
    650                 $modulePath = "default"
    651                 break
    652             }
    653             ([TestModuleLocation]::Custom)
    654             {
    655                 $modulePath = GetExpectedModulePath Custom
    656                 break
    657             }
    658             default {
    659                 throw $location
    660             }
    661         }
    662     
    663         EnsureModuleState $e2eTestModule $false
    664 
    665         $testFile = GetConfigTestDataFile "Configure_TestRepo_Location.yml"
    666         $set = Get-WinGetConfiguration -File $testFile -ModulePath $modulePath
    667         $set | Should -Not -BeNullOrEmpty
    668 
    669         $job = Start-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    670         $job | Should -Not -BeNullOrEmpty
    671 
    672         $result = Complete-WinGetConfiguration -ConfigurationJob $job
    673         $result | Should -Not -BeNullOrEmpty
    674         $result.ResultCode | Should -Be 0
    675         $result.UnitResults.Count | Should -Be 1
    676         $result.UnitResults[0].State | Should -Be "Completed"
    677         $result.UnitResults[0].ResultCode | Should -Be 0
    678 
    679         $expectedModule = Join-Path $(GetExpectedModulePath $location) $e2eTestModule
    680         Test-Path $expectedModule | Should -Be $true
    681     }
    682 
    683     It 'From DSCv3' {
    684         EnsureDSCv3TestResourcePresence
    685 
    686         $testFile = GetConfigTestDataFile "ShowDetails_DSCv3.yml"
    687         $set = Get-WinGetConfiguration -File $testFile
    688         $set | Should -Not -BeNullOrEmpty
    689 
    690         $job = Start-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    691         $job | Should -Not -BeNullOrEmpty
    692 
    693         $result = Complete-WinGetConfiguration -ConfigurationJob $job
    694         $result | Should -Not -BeNullOrEmpty
    695         $result.ResultCode | Should -Be 0
    696         $result.UnitResults.Count | Should -Be 1
    697         $result.UnitResults[0].State | Should -Be "Completed"
    698         $result.UnitResults[0].ResultCode | Should -Be 0
    699 
    700         $expectedFile = Join-Path $(GetConfigTestDataPath) "ShowDetails_DSCv3.txt"
    701         Test-Path $expectedFile | Should -Be $true
    702         Get-Content $expectedFile -Raw | Should -Be "DSCv3 Contents!"
    703 
    704         # Verify can't be used after.
    705         { Start-WinGetConfiguration -AcceptConfigurationAgreements -Set $set } | Should -Throw "Operation is not valid due to the current state of the object."
    706     }
    707 
    708     It 'Piped' {
    709         DeleteConfigTxtFiles
    710         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    711         $result = Get-WinGetConfiguration -File $testFile | Start-WinGetConfiguration -AcceptConfigurationAgreements | Complete-WinGetConfiguration
    712         $result | Should -Not -BeNullOrEmpty
    713         $result.ResultCode | Should -Be 0
    714         $result.UnitResults.Count | Should -Be 1
    715         $result.UnitResults[0].State | Should -Be "Completed"
    716         $result.UnitResults[0].ResultCode | Should -Be 0
    717 
    718         $expectedFile = Join-Path $(GetConfigTestDataPath) "Configure_TestRepo.txt"
    719         Test-Path $expectedFile | Should -Be $true
    720         Get-Content $expectedFile -Raw | Should -Be "Contents!"
    721     }
    722 
    723     It 'Positional' {
    724         DeleteConfigTxtFiles
    725         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    726         $set = Get-WinGetConfiguration $testFile
    727         $set | Should -Not -BeNullOrEmpty
    728 
    729         $job = Start-WinGetConfiguration -AcceptConfigurationAgreements $set
    730         $job | Should -Not -BeNullOrEmpty
    731 
    732         $result = Complete-WinGetConfiguration $job
    733         $result | Should -Not -BeNullOrEmpty
    734         $result.ResultCode | Should -Be 0
    735         $result.UnitResults.Count | Should -Be 1
    736         $result.UnitResults[0].State | Should -Be "Completed"
    737         $result.UnitResults[0].ResultCode | Should -Be 0
    738 
    739         $expectedFile = Join-Path $(GetConfigTestDataPath) "Configure_TestRepo.txt"
    740         Test-Path $expectedFile | Should -Be $true
    741         Get-Content $expectedFile -Raw | Should -Be "Contents!"
    742     }
    743 
    744     It 'Independent Resource - One Failure' {
    745         $testFile = GetConfigTestDataFile "IndependentResources_OneFailure.yml"
    746         $set = Get-WinGetConfiguration -File $testFile
    747         $set | Should -Not -BeNullOrEmpty
    748 
    749         $job = Start-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    750         $job | Should -Not -BeNullOrEmpty
    751 
    752         $result = Complete-WinGetConfiguration -ConfigurationJob $job
    753         $result | Should -Not -BeNullOrEmpty
    754         $result.ResultCode | Should -Be -1978286075
    755         $result.UnitResults.Count | Should -Be 2
    756         $result.UnitResults[0].State | Should -Be "Completed"
    757         $result.UnitResults[0].ResultCode | Should -Be -1978285819
    758 
    759         $result.UnitResults[1].State | Should -Be "Completed"
    760         $result.UnitResults[1].ResultCode | Should -Be 0
    761 
    762         $expectedFile = Join-Path $(GetConfigTestDataPath) "IndependentResources_OneFailure.txt"
    763         Test-Path $expectedFile | Should -Be $true
    764         Get-Content $expectedFile -Raw | Should -Be "Contents!"
    765     }
    766 
    767     It 'Dependent Resource - Failure' {
    768         $testFile = GetConfigTestDataFile "DependentResources_Failure.yml"
    769         $set = Get-WinGetConfiguration -File $testFile
    770         $set | Should -Not -BeNullOrEmpty
    771 
    772         $job = Start-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    773         $job | Should -Not -BeNullOrEmpty
    774 
    775         $result = Complete-WinGetConfiguration -ConfigurationJob $job
    776         $result | Should -Not -BeNullOrEmpty
    777         $result.ResultCode | Should -Be -1978286075
    778         $result.UnitResults.Count | Should -Be 2
    779         $result.UnitResults[0].State | Should -Be "Completed"
    780         $result.UnitResults[0].ResultCode | Should -Be -1978285819
    781         $result.UnitResults[1].State | Should -Be "Skipped"
    782         $result.UnitResults[1].ResultCode | Should -Be -1978286072
    783 
    784         $expectedFile = Join-Path $(GetConfigTestDataPath) "DependentResources_Failure.txt"
    785         Test-Path $expectedFile | Should -Be $false
    786     }
    787 
    788     It 'ResourceCaseInsensitive' {
    789         $testFile = GetConfigTestDataFile "ResourceCaseInsensitive.yml"
    790         $set = Get-WinGetConfiguration -File $testFile
    791         $set | Should -Not -BeNullOrEmpty
    792 
    793         $job = Start-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    794         $job | Should -Not -BeNullOrEmpty
    795 
    796         $result = Complete-WinGetConfiguration -ConfigurationJob $job
    797         $result | Should -Not -BeNullOrEmpty
    798         $result.ResultCode | Should -Be 0
    799         $result.UnitResults.Count | Should -Be 1
    800         $result.UnitResults[0].State | Should -Be "Completed"
    801         $result.UnitResults[0].ResultCode | Should -Be 0
    802 
    803         $expectedFile = Join-Path $(GetConfigTestDataPath) "ResourceCaseInsensitive.txt"
    804         Test-Path $expectedFile | Should -Be $true
    805         Get-Content $expectedFile -Raw | Should -Be "Contents!"
    806     }
    807 }
    808 
    809 Describe 'Test-WinGetConfiguration' {
    810 
    811     BeforeEach {
    812         DeleteConfigTxtFiles
    813     }
    814 
    815     It 'Negative' {
    816         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    817         $set = Get-WinGetConfiguration -File $testFile
    818         $set | Should -Not -BeNullOrEmpty
    819 
    820         $result = Test-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    821         $result | Should -Not -BeNullOrEmpty
    822         $result.TestResult | Should -Be "Negative"
    823         $result.UnitResults.Count | Should -Be 1
    824         $result.UnitResults[0].TestResult | Should -Be "Negative"
    825         $result.UnitResults[0].ResultCode | Should -Be 0
    826     }
    827 
    828     It 'Positive' {
    829         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    830         $set = Get-WinGetConfiguration -File $testFile
    831         $set | Should -Not -BeNullOrEmpty
    832 
    833         $expectedFile = Join-Path $(GetConfigTestDataPath) "Configure_TestRepo.txt"
    834         Set-Content -Path $expectedFile -Value "Contents!" -NoNewline
    835 
    836         $result = Test-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    837         $result | Should -Not -BeNullOrEmpty
    838         $result.TestResult | Should -Be "Positive"
    839         $result.UnitResults.Count | Should -Be 1
    840         $result.UnitResults[0].TestResult | Should -Be "Positive"
    841         $result.UnitResults[0].ResultCode | Should -Be 0
    842     }
    843 
    844     It 'Negative DSCv3' {
    845         EnsureDSCv3TestResourcePresence
    846 
    847         $testFile = GetConfigTestDataFile "ShowDetails_DSCv3.yml"
    848         $set = Get-WinGetConfiguration -File $testFile
    849         $set | Should -Not -BeNullOrEmpty
    850 
    851         $result = Test-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    852         $result | Should -Not -BeNullOrEmpty
    853         $result.TestResult | Should -Be "Negative"
    854         $result.UnitResults.Count | Should -Be 1
    855         $result.UnitResults[0].TestResult | Should -Be "Negative"
    856         $result.UnitResults[0].ResultCode | Should -Be 0
    857     }
    858 
    859     It 'Positive DSCv3' {
    860         EnsureDSCv3TestResourcePresence
    861 
    862         $testFile = GetConfigTestDataFile "ShowDetails_DSCv3.yml"
    863         $set = Get-WinGetConfiguration -File $testFile
    864         $set | Should -Not -BeNullOrEmpty
    865 
    866         $expectedFile = Join-Path $(GetConfigTestDataPath) "ShowDetails_DSCv3.txt"
    867         Set-Content -Path $expectedFile -Value "DSCv3 Contents!" -NoNewline
    868 
    869         $result = Test-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    870         $result | Should -Not -BeNullOrEmpty
    871         $result.TestResult | Should -Be "Positive"
    872         $result.UnitResults.Count | Should -Be 1
    873         $result.UnitResults[0].TestResult | Should -Be "Positive"
    874         $result.UnitResults[0].ResultCode | Should -Be 0
    875     }
    876 
    877     It 'Piped' {
    878         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    879         $result = Get-WinGetConfiguration -File $testFile | Test-WinGetConfiguration -AcceptConfigurationAgreements
    880         $result | Should -Not -BeNullOrEmpty
    881         $result.TestResult | Should -Be "Negative"
    882         $result.UnitResults.Count | Should -Be 1
    883         $result.UnitResults[0].TestResult | Should -Be "Negative"
    884         $result.UnitResults[0].ResultCode | Should -Be 0
    885     }
    886 
    887     It 'Positional' {
    888         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
    889         $set = Get-WinGetConfiguration $testFile
    890         $set | Should -Not -BeNullOrEmpty
    891 
    892         $result = Test-WinGetConfiguration -AcceptConfigurationAgreements $set
    893         $result | Should -Not -BeNullOrEmpty
    894         $result.TestResult | Should -Be "Negative"
    895         $result.UnitResults.Count | Should -Be 1
    896         $result.UnitResults[0].TestResult | Should -Be "Negative"
    897         $result.UnitResults[0].ResultCode | Should -Be 0
    898     }
    899 
    900     It "Failed" {
    901         $testFile = GetConfigTestDataFile "IndependentResources_OneFailure.yml"
    902         $set = Get-WinGetConfiguration -File $testFile
    903         $set | Should -Not -BeNullOrEmpty
    904 
    905         $result = Test-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
    906         $result | Should -Not -BeNullOrEmpty
    907         $result.TestResult | Should -Be "Failed"
    908         $result.UnitResults.Count | Should -Be 2
    909         $result.UnitResults[0].TestResult | Should -Be "Failed"
    910         $result.UnitResults[0].ResultCode | Should -Be -1978285819
    911         $result.UnitResults[1].TestResult | Should -Be "Negative"
    912         $result.UnitResults[1].ResultCode | Should -Be 0
    913     }
    914 }
    915 
    916 Describe 'Confirm-WinGetConfiguration' {
    917 
    918     It 'Duplicate Identifiers' {
    919         $testFile = GetConfigTestDataFile "DuplicateIdentifiers.yml"
    920         $set = Get-WinGetConfiguration -File $testFile
    921         $set | Should -Not -BeNullOrEmpty
    922 
    923         $result = Confirm-WinGetConfiguration -Set $set
    924         $result | Should -Not -BeNullOrEmpty
    925         $result.ResultCode | Should -Be -1978286074
    926         $result.UnitResults.Count | Should -Be 3
    927         $result.UnitResults[0].ResultCode | Should -Be -1978286074
    928         $result.UnitResults[1].ResultCode | Should -Be -1978286074
    929         $result.UnitResults[2].ResultCode | Should -Be 0
    930     }
    931 
    932     It 'Missing dependency' {
    933         $testFile = GetConfigTestDataFile "MissingDependency.yml"
    934         $set = Get-WinGetConfiguration -File $testFile
    935         $set | Should -Not -BeNullOrEmpty
    936 
    937         $result = Confirm-WinGetConfiguration -Set $set
    938         $result | Should -Not -BeNullOrEmpty
    939         $result.ResultCode | Should -Be -1978286073
    940         $result.UnitResults.Count | Should -Be 3
    941         $result.UnitResults[0].ResultCode | Should -Be 0
    942         $result.UnitResults[1].ResultCode | Should -Be 0
    943         $result.UnitResults[2].ResultCode | Should -Be -1978286073
    944     }
    945 
    946     It 'Dependency cycle' {
    947         $testFile = GetConfigTestDataFile "DependencyCycle.yml"
    948         $set = Get-WinGetConfiguration -File $testFile
    949         $set | Should -Not -BeNullOrEmpty
    950 
    951         $result = Confirm-WinGetConfiguration -Set $set
    952         $result | Should -Not -BeNullOrEmpty
    953         $result.ResultCode | Should -Be -1978286068
    954         $result.UnitResults.Count | Should -Be 3
    955         $result.UnitResults[0].ResultCode | Should -Be -1978286072
    956         $result.UnitResults[1].ResultCode | Should -Be -1978286072
    957         $result.UnitResults[2].ResultCode | Should -Be 0
    958     }
    959 
    960     It 'No issue' {
    961         $testFile = GetConfigTestDataFile "PSGallery_NoSettings.yml"
    962         $set = Get-WinGetConfiguration -File $testFile
    963         $set | Should -Not -BeNullOrEmpty
    964 
    965         $result = Confirm-WinGetConfiguration -Set $set
    966         $result | Should -Not -BeNullOrEmpty
    967         $result.ResultCode | Should -Be 0
    968     }
    969 
    970     It 'Piped' {
    971         $testFile = GetConfigTestDataFile "DuplicateIdentifiers.yml"
    972         $result = Get-WinGetConfiguration -File $testFile | Confirm-WinGetConfiguration
    973         $result.UnitResults.Count | Should -Be 3
    974         $result.UnitResults[0].ResultCode | Should -Be -1978286074
    975         $result.UnitResults[1].ResultCode | Should -Be -1978286074
    976         $result.UnitResults[2].ResultCode | Should -Be 0
    977     }
    978 
    979     It 'Positional' {
    980         $testFile = GetConfigTestDataFile "DuplicateIdentifiers.yml"
    981         $set = Get-WinGetConfiguration $testFile
    982         $set | Should -Not -BeNullOrEmpty
    983 
    984         $result = Confirm-WinGetConfiguration $set
    985         $result | Should -Not -BeNullOrEmpty
    986         $result.ResultCode | Should -Be -1978286074
    987         $result.UnitResults.Count | Should -Be 3
    988         $result.UnitResults[0].ResultCode | Should -Be -1978286074
    989         $result.UnitResults[1].ResultCode | Should -Be -1978286074
    990         $result.UnitResults[2].ResultCode | Should -Be 0
    991     }
    992 }
    993 
    994 Describe 'Configuration History' {
    995 
    996     BeforeEach {
    997         DeleteConfigTxtFiles
    998     }
    999 
   1000     It 'History Lifecycle' {
   1001         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
   1002         $set = Get-WinGetConfiguration -File $testFile
   1003         $set | Should -Not -BeNullOrEmpty
   1004 
   1005         $result = Invoke-WinGetConfiguration -AcceptConfigurationAgreements -Set $set
   1006         $result | Should -Not -BeNullOrEmpty
   1007         $result.ResultCode | Should -Be 0
   1008         $result.UnitResults.Count | Should -Be 1
   1009         $result.UnitResults[0].State | Should -Be "Completed"
   1010         $result.UnitResults[0].ResultCode | Should -Be 0
   1011 
   1012         $historySet = Get-WinGetConfiguration -InstanceIdentifier $set.InstanceIdentifier
   1013         $historySet | Should -Not -BeNullOrEmpty
   1014         $historySet.InstanceIdentifier | Should -Be $set.InstanceIdentifier
   1015 
   1016         $allHistory = Get-WinGetConfiguration -All
   1017         $allHistory | Should -Not -BeNullOrEmpty
   1018 
   1019         $historySet | Remove-WinGetConfigurationHistory
   1020 
   1021         $historySetAfterRemove = Get-WinGetConfiguration -InstanceIdentifier $set.InstanceIdentifier
   1022         $historySetAfterRemove | Should -BeNullOrEmpty
   1023     }
   1024 }
   1025 
   1026 Describe 'Configuration Serialization' {
   1027 
   1028     It 'Basic Serialization' {
   1029         $testFile = GetConfigTestDataFile "Configure_TestRepo.yml"
   1030         $set = Get-WinGetConfiguration -File $testFile
   1031         $set | Should -Not -BeNullOrEmpty
   1032 
   1033         $result = ConvertTo-WinGetConfigurationYaml -Set $set
   1034         $result | Should -Not -BeNullOrEmpty
   1035 
   1036         $tempFile = New-TemporaryFile
   1037         Set-Content -Path $tempFile -Value $result
   1038 
   1039         $roundTripSet = Get-WinGetConfiguration -File $tempFile.VersionInfo.FileName
   1040         $roundTripSet | Should -Not -BeNullOrEmpty
   1041     }
   1042 }
   1043 
   1044 AfterAll {
   1045     CleanupGroupPolicies
   1046     CleanupGroupPolicyKeyIfExists
   1047     CleanupPsModulePath
   1048     DeleteConfigTxtFiles
   1049 }