Tests/Unit/MSFT_xWindowsOptionalFeature.Tests.ps1
Import-Module -Name "$PSScriptRoot\..\CommonTestHelper.psm1" $script:testEnvironment = Enter-DscResourceTestEnvironment ` -DscResourceModuleName 'xPSDesiredStateConfiguration' ` -DscResourceName 'MSFT_xWindowsOptionalFeature' ` -TestType 'Unit' try { InModuleScope 'MSFT_xWindowsOptionalFeature' { Describe 'xWindowsOptionalFeature Unit Tests' { BeforeAll { Import-Module -Name 'Dism' $script:testFeatureName = 'TestFeature' $script:fakeEnabledFeature = [PSCustomObject] @{ Name = $testFeatureName State = 'Enabled' } $script:fakeDisabledFeature = [PSCustomObject] @{ Name = $testFeatureName State = 'Disabled' } } Context 'Get-TargetResource - Feature Enabled' { Mock Assert-ResourcePrerequisitesValid -MockWith { } Mock Dism\Get-WindowsOptionalFeature { $FeatureName -eq $script:testFeatureName } -MockWith { return $script:fakeEnabledFeature } It 'Should return a Hashtable' { $getTargetResourceResult = Get-TargetResource -Name $script:testFeatureName $getTargetResourceResult -is [System.Collections.Hashtable] | Should Be $true } It 'Should call Assert-ResourcePrerequisitesValid with the feature name' { $getTargetResourceResult = Get-TargetResource -Name $script:testFeatureName Assert-MockCalled Dism\Get-WindowsOptionalFeature -ParameterFilter { $FeatureName -eq $script:testFeatureName } -Scope It } It 'Should return Ensure as Present' { $getTargetResourceResult = Get-TargetResource -Name $script:testFeatureName $getTargetResourceResult.Ensure | Should Be 'Present' } } Context 'Get-TargetResource - Feature Disabled' { Mock Assert-ResourcePrerequisitesValid -MockWith { } Mock Dism\Get-WindowsOptionalFeature { $FeatureName -eq $script:testFeatureName } -MockWith { return $script:fakeDisabledFeature } It 'Should return Ensure as Absent' { $getTargetResourceResult = Get-TargetResource -Name $script:testFeatureName $getTargetResourceResult.Ensure | Should Be 'Absent' } } Context 'Test-TargetResource - Feature Enabled' { Mock Assert-ResourcePrerequisitesValid -MockWith { } Mock Dism\Get-WindowsOptionalFeature { $FeatureName -eq $script:testFeatureName } -MockWith { return $script:fakeEnabledFeature } It 'Should return true when Ensure set to Present' { Test-TargetResource -Name $testFeatureName -Ensure 'Present' | Should Be $true } It 'Should return false when Ensure set to Absent' { Test-TargetResource -Name $testFeatureName -Ensure 'Absent' | Should Be $false } } Context 'Test-TargetResource - Feature Disabled' { Mock Assert-ResourcePrerequisitesValid -MockWith { } Mock Dism\Get-WindowsOptionalFeature { $FeatureName -eq $script:testFeatureName } -MockWith { return $script:fakeDisabledFeature } It 'Should return false when Ensure set to Present' { Test-TargetResource -Name $testFeatureName -Ensure 'Present' | Should Be $false } It 'Should return true when Ensure set to Absent' { Test-TargetResource -Name $testFeatureName -Ensure 'Absent' | Should Be $true } } Context 'Test-TargetResource - Feature Missing' { Mock Assert-ResourcePrerequisitesValid -MockWith { } Mock Dism\Get-WindowsOptionalFeature { $FeatureName -eq $script:testFeatureName } -MockWith { } It 'Should return false when Ensure set to Present' { Test-TargetResource -Name $testFeatureName -Ensure 'Present' | Should Be $false } It 'Should return true when Ensure set to Absent' { Test-TargetResource -Name $testFeatureName -Ensure 'Absent' | Should Be $true } } Context 'Set-TargetResource' { Mock Assert-ResourcePrerequisitesValid -MockWith { } It 'Should call Enable-WindowsOptionalFeature with NoRestart set to true by default when Ensure set to Present' { Mock Dism\Enable-WindowsOptionalFeature -ParameterFilter { $NoRestart -eq $true } -MockWith { } Set-TargetResource -Name $script:testFeatureName Assert-MockCalled Dism\Enable-WindowsOptionalFeature -ParameterFilter { $NoRestart -eq $true } -Scope It } It 'Should call Disable-WindowsOptionalFeature with NoRestart set to true by default when Ensure set to Absent' { Mock Dism\Disable-WindowsOptionalFeature -ParameterFilter { $NoRestart -eq $true } -MockWith { } Set-TargetResource -Name $script:testFeatureName -Ensure 'Absent' Assert-MockCalled Dism\Disable-WindowsOptionalFeature -ParameterFilter { $NoRestart -eq $true } -Scope It } It 'Should call Enable-WindowsOptionalFeature with Online by default as true when Ensure set to Present' { Mock Dism\Enable-WindowsOptionalFeature -ParameterFilter { $Online -eq $true } -MockWith { } Set-TargetResource -Name $script:testFeatureName Assert-MockCalled Dism\Enable-WindowsOptionalFeature -ParameterFilter { $Online -eq $true } -Scope It } It 'Should call Disable-WindowsOptionalFeature with Online set to true by default when Ensure set to Absent' { Mock Dism\Disable-WindowsOptionalFeature -ParameterFilter { $Online -eq $true } -MockWith { } Set-TargetResource -Name $script:testFeatureName -Ensure 'Absent' Assert-MockCalled Dism\Disable-WindowsOptionalFeature -ParameterFilter { $Online -eq $true } -Scope It } It 'Should call Enable-WindowsOptionalFeature with LogLevel set to WarningsInfo by default when Ensure set to Present' { Mock Dism\Enable-WindowsOptionalFeature -ParameterFilter { $LogLevel -eq 'WarningsInfo' } -MockWith { } Set-TargetResource -Name $script:testFeatureName Assert-MockCalled Dism\Enable-WindowsOptionalFeature -ParameterFilter { $LogLevel -eq 'WarningsInfo' } -Scope It } It 'Should call Enable-WindowsOptionalFeature with LogLevel set to Errors when Ensure set to Present and LogLevel set to ErrorsOnly' { Mock Dism\Enable-WindowsOptionalFeature -ParameterFilter { $LogLevel -eq 'Errors' } -MockWith { } Set-TargetResource -Name $script:testFeatureName -LogLevel 'ErrorsOnly' Assert-MockCalled Dism\Enable-WindowsOptionalFeature -ParameterFilter { $LogLevel -eq 'Errors' } -Scope It } It 'Should call Enable-WindowsOptionalFeature with LogLevel set to Warnings when Ensure set to Present and LogLevel set to ErrorsAndWarnings' { Mock Dism\Enable-WindowsOptionalFeature -ParameterFilter { $LogLevel -eq 'Warnings' } -MockWith { } Set-TargetResource -Name $script:testFeatureName -LogLevel 'ErrorsAndWarning' Assert-MockCalled Dism\Enable-WindowsOptionalFeature -ParameterFilter { $LogLevel -eq 'Warnings' } -Scope It } It 'Should call Disable-WindowsOptionalFeature with LogLevel set to WarningsInfo by default when Ensure set to Absent' { Mock Dism\Disable-WindowsOptionalFeature -ParameterFilter { $LogLevel -eq 'WarningsInfo' } -MockWith { } Set-TargetResource -Name $script:testFeatureName -Ensure 'Absent' Assert-MockCalled Dism\Disable-WindowsOptionalFeature -ParameterFilter { $LogLevel -eq 'WarningsInfo' } -Scope It } It 'Should call Enable-WindowsOptionalFeature without LimitAccess by default when Ensure set to Present' { Mock Dism\Enable-WindowsOptionalFeature -ParameterFilter { $LimitAccess -eq $null } -MockWith { } Set-TargetResource -Name $script:testFeatureName Assert-MockCalled Dism\Enable-WindowsOptionalFeature -ParameterFilter { $LimitAccess -eq $null } -Scope It } It 'Should call Enable-WindowsOptionalFeature with LimitAccess set to true when NoWindowsUpdateCheck is specified' { Mock Dism\Enable-WindowsOptionalFeature -ParameterFilter { $LimitAccess -eq $true } -MockWith { } Set-TargetResource -Name $script:testFeatureName -NoWindowsUpdateCheck $true Assert-MockCalled Dism\Enable-WindowsOptionalFeature -ParameterFilter { $LimitAccess -eq $true } -Scope It } It 'Should call Disable-WindowsOptionalFeature with Remove set to true when Ensure set to Absent and RemoveFilesOnDisable specified' { Mock Dism\Disable-WindowsOptionalFeature -ParameterFilter { $Remove -eq $true } -MockWith { } Set-TargetResource -Name $script:testFeatureName -Ensure 'Absent' -RemoveFilesOnDisable $true Assert-MockCalled Dism\Disable-WindowsOptionalFeature -ParameterFilter { $Remove -eq $true } -Scope It } } Context 'Convert-FeatureStateToEnsure' { It 'Should return Present when state is Enabled' { Convert-FeatureStateToEnsure -State 'Enabled' | Should Be 'Present' } It 'Should return Absent when state is Disabled' { Convert-FeatureStateToEnsure -State 'Disabled' | Should Be 'Absent' } It 'Should return the same state when state is not Enabled or Disabled' { $originalWarningPreference = $WarningPreference $WarningPreference = 'SilentlyContinue' try { Convert-FeatureStateToEnsure -State 'UnknownState' | Should Be 'UnknownState' } finally { $WarningPreference = $originalWarningPreference } } } Context 'Assert-ResourcePrerequisitesValid' { $fakeWin32OSObjects = @{ '7' = [PSCustomObject] @{ ProductType = 1 BuildNumber = 7601 } 'Server2008R2' = [PSCustomObject] @{ ProductType = 2 BuildNumber = 7601 } 'Server2012' = [PSCustomObject] @{ ProductType = 2 BuildNumber = 9200 } '8.1' = [PSCustomObject] @{ ProductType = 1 BuildNumber = 9600 } 'Server2012R2' = [PSCustomObject] @{ ProductType = 2 BuildNumber = 9600 } } It 'Should throw when the DISM module is not available' { Mock Import-Module -ParameterFilter { $Name -eq 'Dism' } -MockWith { Write-Error 'Cannot find module' } { Assert-ResourcePrerequisitesValid } | Should Throw $script:localizedData.DismNotAvailable } Mock Import-Module -ParameterFilter { $Name -eq 'Dism' } -MockWith { } It 'Should throw when operating system is Server 2008 R2' { Mock Get-CimInstance -ParameterFilter { $ClassName -eq 'Win32_OperatingSystem' } -MockWith { return $fakeWin32OSObjects['Server2008R2'] } { Assert-ResourcePrerequisitesValid } | Should Throw $script:localizedData.NotSupportedSku } It 'Should throw when operating system is Server 2012' { Mock Get-CimInstance -ParameterFilter { $ClassName -eq 'Win32_OperatingSystem' } -MockWith { return $fakeWin32OSObjects['Server2012'] } { Assert-ResourcePrerequisitesValid } | Should Throw $script:localizedData.NotSupportedSku } It 'Should not throw when operating system is Windows 7' { Mock Get-CimInstance -ParameterFilter { $ClassName -eq 'Win32_OperatingSystem' } -MockWith { return $fakeWin32OSObjects['7'] } { Assert-ResourcePrerequisitesValid } | Should Not Throw } It 'Should not throw when operating system is Windows 8.1' { Mock Get-CimInstance -ParameterFilter { $ClassName -eq 'Win32_OperatingSystem' } -MockWith { return $fakeWin32OSObjects['8.1'] } { Assert-ResourcePrerequisitesValid } | Should Not Throw } It 'Should not throw when operating system is Server 2012 R2' { Mock Get-CimInstance -ParameterFilter { $ClassName -eq 'Win32_OperatingSystem' } -MockWith { return $fakeWin32OSObjects['Server2012R2'] } { Assert-ResourcePrerequisitesValid } | Should Not Throw } } Context 'Convert-CustomPropertyArrayToStringArray' { [PSCustomObject[]] $psCustomObjects = @( [PSCustomObject] @{ Name = 'Object 1' Value = 'Value 1' Path = 'Path 1' }, [PSCustomObject] @{ Name = 'Object 2' Value = 'Value 2' Path = 'Path 2' }, [PSCustomObject] @{ Name = 'Object 3' Value = 'Value 3' Path = 'Path 3' }, $null ) It 'Should return 3 strings from 3 PSCustomObjects and a null object' { $propertiesAsStrings = Convert-CustomPropertyArrayToStringArray -CustomProperties $psCustomObjects $propertiesAsStrings.Length | Should Be 3 } It 'Should return the correct string for each object' { $propertiesAsStrings = Convert-CustomPropertyArrayToStringArray -CustomProperties $psCustomObjects foreach ($objectNumber in @(1, 2, 3)) { $propertiesAsStrings.Contains("Name = Object $objectNumber, Value = Value $objectNumber, Path = Path $objectNumber") | Should Be $true } } } } } } finally { Exit-DscResourceTestEnvironment -TestEnvironment $script:testEnvironment } |