tests/functions/configuration/Export-PSFConfig.Tests.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
Describe "Export-PSFConfig Unit Tests" -Tag "CI", "Pipeline", "Unit" {
    BeforeAll {
        Get-PSFConfig -Module Export-PSFConfig -Force | ForEach-Object {
            $null = [PSFramework.Configuration.ConfigurationHost]::Configurations.Remove($_.FullName)
        }
        Remove-Item -Path "TestDrive:\Export-PSFConfig*" -Force -Recurse
    }
    AfterAll {
        Get-PSFConfig -Module Export-PSFConfig -Force | ForEach-Object {
            $null = [PSFramework.Configuration.ConfigurationHost]::Configurations.Remove($_.FullName)
        }
        Remove-Item -Path "TestDrive:\Export-PSFConfig*" -Force -Recurse
    }
    
    # Catch any signature changes to force revisiting the command
    It "Should have the designed for parameters & sets" {
        (Get-Command Export-PSFConfig).ParameterSets.Name | Should -Be 'FullName', 'Module', 'Config', 'ModuleName'
        foreach ($key in (Get-Command Export-PSFConfig).Parameters.Keys)
        {
            $key | Should -BeIn 'FullName', 'Module', 'Name', 'Config', 'ModuleName', 'ModuleVersion', 'Scope', 'OutPath', 'SkipUnchanged', 'EnableException', 'Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction', 'ErrorVariable', 'WarningVariable', 'InformationVariable', 'OutVariable', 'OutBuffer', 'PipelineVariable'
        }
    }
    
    # Export 1 Configuration Item to file
    # Export 3 Configuration Items to file
    # Export all configuration items of a module to file
    # Export all (and only) unchanged items of a module to file
    Describe "Testing core export integrity" {
        BeforeAll {
            $configItems = @()
            $configItems += Set-PSFConfig -FullName Export-PSFConfig.TestPhase1.Settings1 -Value 42 -PassThru -Initialize
            $configItems += Set-PSFConfig -FullName Export-PSFConfig.TestPhase1.Settings2 -Value 23 -PassThru -Initialize
            $configItems += Set-PSFConfig -FullName Export-PSFConfig.TestPhase1.Settings3 -Value "foo" -PassThru -Initialize
        }
        
        It "Should correctly export a single configuration item" {
            $configItems[0] | Export-PSFConfig -OutPath "TestDrive:\Export-PSFConfig.test1.json"
            Test-Path "TestDrive:\Export-PSFConfig.test1.json" | Should -Be $true
            $item = Get-Content "TestDrive:\Export-PSFConfig.test1.json" | ConvertFrom-Json
            $item.FullName | Should -Be 'Export-PSFConfig.TestPhase1.Settings1'
            $item.Type | Should -Be 3
            $item.Version | Should -Be 1
            $item.Value | Should -Be "42"
            $item.Style | Should -Be "Default"
        }
        It "Should correctly export multiple configuration items" {
            $configItems | Export-PSFConfig -OutPath "TestDrive:\Export-PSFConfig.test2.json"
            Test-Path "TestDrive:\Export-PSFConfig.test2.json" | Should -Be $true
            $items = Get-Content "TestDrive:\Export-PSFConfig.test2.json" | ConvertFrom-Json
            foreach ($name in ('Export-PSFConfig.TestPhase1.Settings1', 'Export-PSFConfig.TestPhase1.Settings2', 'Export-PSFConfig.TestPhase1.Settings3'))
            {
                $name | Should -BeIn $items.FullName
            }
            (($items.Type | Group-Object | Sort-Object Count) | Where-Object Name -EQ 3).Count | Should -Be 2
            (($items.Type | Group-Object | Sort-Object Count) | Where-Object Name -EQ 6).Count | Should -Be 1
            $items.Version | Should -Be 1, 1, 1
            $items.Value | Should -Be "foo", "42", "23"
            $items.Style | Should -Be "Default", "Default", "Default"
        }
        It "Should export all settings belonging to the specified module" {
            Export-PSFConfig -Module Export-PSFConfig -OutPath "TestDrive:\Export-PSFConfig.test3.json"
            Test-Path "TestDrive:\Export-PSFConfig.test3.json" | Should -Be $true
            (Get-Content "TestDrive:\Export-PSFConfig.test3.json" | ConvertFrom-Json | Remove-PSFNull -Enumerate | Measure-Object).Count | Should -Be 3
        }
        It "Should only export changed settings if so directed" {
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase1.Settings2 -Value 23
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase1.Settings3 -Value "bar"
            Export-PSFConfig -Module Export-PSFConfig -OutPath "TestDrive:\Export-PSFConfig.test4.json" -SkipUnchanged
            Test-Path "TestDrive:\Export-PSFConfig.test4.json" | Should -Be $true
            (Get-Content "TestDrive:\Export-PSFConfig.test4.json" | ConvertFrom-Json | Remove-PSFNull -Enumerate | Measure-Object).Count | Should -Be 2
        }
    }
    
    # Determine file integrity
    # - Simple Export
    # - Complex Export
    # - Simple/Complex in hybrid export
    Describe "Ensuring all export styles are correctly created" {
        BeforeAll {
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase2.Settings1 -Value 42 -SimpleExport
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase2.Settings2 -Value 23
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase2.Settings3 -Value (Get-Date) -SimpleExport
        }
        
        It "Should create a simple export" {
            Export-PSFConfig -FullName Export-PSFConfig.TestPhase2.Settings1 -OutPath "TestDrive:\Export-PSFConfig.testB1.json"
            Test-Path "TestDrive:\Export-PSFConfig.testB1.json" | Should -Be $true
            $item = Get-Content "TestDrive:\Export-PSFConfig.testB1.json" | ConvertFrom-Json
            $item.FullName | Should -Be 'Export-PSFConfig.TestPhase2.Settings1'
            $item.Version | Should -Be 1
            $item.Data | Should -Be 42
            $item.Data.GetType().FullName | Should -Be "System.Int32"
            
            # Properties that only exist on non-simple export items
            $item.Style | Should -BeNullOrEmpty
            $item.Type | Should -BeNullOrEmpty
            $item.Value | Should -BeNullOrEmpty
        }
        It "Should create a complex export" {
            Export-PSFConfig -FullName Export-PSFConfig.TestPhase2.Settings2 -OutPath "TestDrive:\Export-PSFConfig.testB2.json"
            Test-Path "TestDrive:\Export-PSFConfig.testB2.json" | Should -Be $true
            $item = Get-Content "TestDrive:\Export-PSFConfig.testB2.json" | ConvertFrom-Json
            $item.FullName | Should -Be 'Export-PSFConfig.TestPhase2.Settings2'
            $item.Type | Should -Be 3
            $item.Version | Should -Be 1
            $item.Value | Should -Be "23"
            $item.Style | Should -Be "Default"
        }
        It "Should create a hybrid export" {
            Export-PSFConfig -Module Export-PSFConfig -Name TestPhase2.* -OutPath "TestDrive:\Export-PSFConfig.testB3.json"
            Test-Path "TestDrive:\Export-PSFConfig.testB3.json" | Should -Be $true
            $items = Get-Content "TestDrive:\Export-PSFConfig.testB3.json" | ConvertFrom-Json
            ($items | Measure-Object).Count | Should -Be 3
            
            #region Simple Export
            $item = $items | Where-Object FullName -EQ 'Export-PSFConfig.TestPhase2.Settings1'
            $item.Version | Should -Be 1
            $item.Data | Should -Be 42
            $item.Data.GetType().FullName | Should -Be "System.Int32"
            
            # Properties that only exist on non-simple export items
            $item.Style | Should -BeNullOrEmpty
            $item.Type | Should -BeNullOrEmpty
            $item.Value | Should -BeNullOrEmpty
            #endregion Simple Export
            
            #region Complex Export
            $item = $items | Where-Object FullName -EQ 'Export-PSFConfig.TestPhase2.Settings2'
            $item.Type | Should -Be 3
            $item.Version | Should -Be 1
            $item.Value | Should -Be "23"
            $item.Style | Should -Be "Default"
            #endregion Complex Export
        }
    }
    
    # Export under the ModuleName parameterset
    # - Only exports configuration items marked for module export
    # - Exports to the correct scopes' files
    # - Throws on a registry scope
    Describe "Ensuring Module Cache functionality works as designed" {
        BeforeAll {
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase3.Settings1 -Value 42 -ModuleExport -Initialize
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase3.Settings2 -Value 23
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase3.Settings3 -Value (Get-Date) -ModuleExport -Hidden -Initialize
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase3.Settings4 -Value "foo" -ModuleExport -Hidden -Initialize
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase3.Settings1 -Value 42
            Set-PSFConfig -FullName Export-PSFConfig.TestPhase3.Settings3 -Value (Get-Date)
            
            $module = Get-Module PSFramework | Sort-Object Version -Descending | Select-Object -First 1
            $pathFileUserLocal = & $module { $path_FileUserLocal }
            $pathFileUserShared = & $module { $path_FileUserShared }
            $pathFileSystem = & $module { $path_FileSystem }
        }
        
        It "Should only export configuration settings marked for export in the module cache" {
            Export-PSFConfig -ModuleName Export-PSFConfig
            Test-Path "$($pathFileUserShared)\export-psfconfig-1.json" | Should -Be $true
            
            $items = Get-Content "$($pathFileUserShared)\export-psfconfig-1.json" | ConvertFrom-Json
            ($items | Measure-Object).Count | Should -Be 2 # Setting2 is not part of the cache, Setting4 has not yet been updated from default
            
            Remove-Item "$($pathFileUserShared)\export-psfconfig-1.json"
        }
        It "Should export to the scopes specified" {
            Test-Path "$($pathFileUserShared)\export-psfconfig-1.json" | Should -Be $false
            Export-PSFConfig -ModuleName Export-PSFConfig -Scope FileUserShared
            Test-Path "$($pathFileUserShared)\export-psfconfig-1.json" | Should -Be $true
            Remove-Item "$($pathFileUserShared)\export-psfconfig-1.json"
            
            Test-Path "$($pathFileUserLocal)\export-psfconfig-1.json" | Should -Be $false
            Export-PSFConfig -ModuleName Export-PSFConfig -Scope FileUserLocal
            Test-Path "$($pathFileUserLocal)\export-psfconfig-1.json" | Should -Be $true
            Remove-Item "$($pathFileUserLocal)\export-psfconfig-1.json"
            
            Test-Path "$($pathFileUserShared)\export-psfconfig-1.json" | Should -Be $false
            Test-Path "$($pathFileUserLocal)\export-psfconfig-1.json" | Should -Be $false
            Export-PSFConfig -ModuleName Export-PSFConfig -Scope FileUserShared, FileUserLocal
            Test-Path "$($pathFileUserShared)\export-psfconfig-1.json" | Should -Be $true
            Test-Path "$($pathFileUserLocal)\export-psfconfig-1.json" | Should -Be $true
            Remove-Item "$($pathFileUserShared)\export-psfconfig-1.json"
            Remove-Item "$($pathFileUserLocal)\export-psfconfig-1.json"
        }
        It "Should throw on registry scope" {
            { Export-PSFConfig -ModuleName Export-PSFConfig -Scope UserDefault -EnableException } | Should -Throw
        }
    }
}