. $PSScriptRoot\..\..\Load-PesterModules.ps1 $here = Split-Path -Parent $MyInvocation.MyCommand.Path $sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.xml\.tests\.', '.' $functionPath = Join-Path -Path $here -ChildPath $sut Write-Host "Overriding SUT: $functionPath" Get-Module $sut | Remove-Module -Force # Have to do this to use the private function for Set-AppSettingPrivate # Write-Host "Overriding SUT: $functionPath" # Import-Module $functionPath -Force $moduleForMock = "Alkami.PowerShell.Configuration" $moduleForMock2 = "Alkami.PowerShell.Common" Describe "Set-AppSetting - xml" { #TODO: Refactor - mock Get-AppSetting, mock Read-XmlFile, mock Save-XmlFile # Mock all the things - See "Get-AppSetting" tests for faking Read-XmlFile results # Temp file to write content to $tempFile = [System.IO.Path]::GetTempFileName() $tempPath = $tempFile.Split(".") | Select-Object -First 1 $fakeConfigFile = Join-Path $tempPath "fake.config" New-Item -ItemType Directory $tempPath -ErrorAction SilentlyContinue | Out-Null Write-Host ("Using temp path: $tempPath for tests") Mock -ModuleName $moduleForMock2 -CommandName Write-Host -MockWith {} Context "Reports an error when two appSettings sections are present" { $appSettingsTestContents = @" "@ Mock -ModuleName $moduleForMock -CommandName Write-Error -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Host -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Warning -MockWith {} $appSettingsTestContents | Out-File $fakeConfigFile -Force Set-AppSetting -Path $fakeConfigFile -Key "aspnet:MaxJsonDeserializerMembers" -Value 50000 $value = Get-AppSetting -Path $fakeConfigFile -key "aspnet:MaxJsonDeserializerMembers" It "still got the right value" { $value | Should Be "50000" } It "did throw an error" { # Once in Get-AppSetting and once in Set-AppSetting because of the duplicate block Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Error -Exactly -Times 2 -Scope Context } It "wrote two warnings to the console" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Warning -Exactly -Times 3 -Scope Context } It "wrote four found paths" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Host -Exactly -Times 8 -Scope Context } } Context "Writes a warning and updates all values if more than one setting exists" { $appSettingsTestContents = @" "@ Mock -ModuleName $moduleForMock -CommandName Write-Error -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Host -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Warning -MockWith {} $appSettingsTestContents | Out-File $fakeConfigFile -Force Set-AppSetting -Path $fakeConfigFile -Key "FakeSetting" -Value "DuplicateResolved" It "the file looks accurate" { ## The reason for this joins shenanigans is because Get-Content returns an array of lines, and I don't want a wrapping construct here. This is fine. thisisfine.gif ((Get-Content $fakeConfigFile) -join ' ') | Should -Be ' ' } $value = Get-AppSetting -Path $fakeConfigFile -key "FakeSetting" It "still got the right value" { $value | Should -Be "DuplicateResolved" } It "did not throw an error" { # Once in Get-AppSetting and once in Set-AppSetting because of the duplicate block Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Error -Exactly -Times 2 -Scope Context } It "wrote a warning to the console" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Warning -Exactly -Times 1 -Scope Context } It "wrote two paths" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Host -Exactly -Times 4 -Scope Context } } Context "Writes a Warning and Returns Null if the appSettings Node Doesn't Exist" { $appSettingsTestContents = @" "@ Mock -ModuleName $moduleForMock -CommandName Write-Error -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Host -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Warning -MockWith {} $appSettingsTestContents | Out-File $fakeConfigFile -Force Set-AppSetting -Path $fakeConfigFile -Key "FakeSetting" -Value 'test' $value = Get-AppSetting -Path $fakeConfigFile -key "FakeSetting" It "still got the right value" { $value | Should -Be 'test' } It "did not throw an error" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Error -Exactly -Times 0 -Scope Context } It "wrote a warning to the console" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Warning -Exactly -Times 1 -Scope Context } It "did not output useless information" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Host -Exactly -Times 1 -Scope Context } } Context "App Setting Key Does Not Exist" { $appSettingsTestContents = @" "@ Mock -ModuleName $moduleForMock -CommandName Write-Error -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Host -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Warning -MockWith {} $appSettingsTestContents | Out-File $fakeConfigFile -Force Set-AppSetting -Path $fakeConfigFile -Key "FakeSetting" -Value 'test' $value = Get-AppSetting -Path $fakeConfigFile -key "FakeSetting" It "creates a missing AppSetting key." { $value | Should -Be 'test' } It "did not throw an error" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Error -Exactly -Times 0 -Scope Context } It "wrote a warning to the console" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Warning -Exactly -Times 0 -Scope Context } It "did not output useless information" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Host -Exactly -Times 1 -Scope Context } } Context "App Setting Key Does Not Exist with -UpdateOnly" { $appSettingsTestContents = @" "@ Mock -ModuleName $moduleForMock -CommandName Write-Error -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Host -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Warning -MockWith {} $appSettingsTestContents | Out-File $fakeConfigFile -Force Set-AppSetting -Path $fakeConfigFile -Key "MissingSetting" -Value 'test' -UpdateOnly $value = Get-AppSetting -Path $fakeConfigFile -key "MissingSetting" It "does not create a missing AppSetting key with -UpdateOnly" { $value | Should -Be $null } It "did not throw an error" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Error -Exactly -Times 0 -Scope Context } It "wrote a warning to the console" { # The one warning is from Get-AppSetting and not Set-AppSetting Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Warning -Exactly -Times 1 -Scope Context } It "did not output useless information" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Host -Exactly -Times 1 -Scope Context } } Context "Does a happy path" { $appSettingsTestContents = @" "@ Mock -ModuleName $moduleForMock -CommandName Write-Error -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Host -MockWith {} Mock -ModuleName $moduleForMock -CommandName Write-Warning -MockWith {} $appSettingsTestContents | Out-File $fakeConfigFile -Force Set-AppSetting -Path $fakeConfigFile -Key "FakeSetting" -Value 'test' $value = Get-AppSetting -Path $fakeConfigFile -key "FakeSetting" It "still got the right value" { $value | Should -Be 'test' } It "did not throw an error" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Error -Exactly -Times 0 -Scope Context } It "wrote a warning to the console" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Warning -Exactly -Times 0 -Scope Context } It "did not output useless information" { Assert-MockCalled -ModuleName $moduleForMock -CommandName Write-Host -Exactly -Times 1 -Scope Context } } Remove-Item $fakeConfigFile -Force Remove-Item $tempPath -Force }