Tests/Lib/DscResource.Tests.ps1
#requires -RunAsAdministrator #requires -Version 4 $moduleName = 'Lability'; if (!$PSScriptRoot) { # $PSScriptRoot is not defined in 2.0 $PSScriptRoot = [System.IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Path) } $repoRoot = (Resolve-Path "$PSScriptRoot\..\..").Path; Import-Module (Join-Path -Path $RepoRoot -ChildPath "$moduleName.psm1") -Force; Describe 'DscResource' { InModuleScope $moduleName { Context 'Validates "ImportDscResource" method' { It 'Does not import module if command is already imported' { $testModuleName = 'TestLabModule'; $testResourceName = 'TestLabResource'; $testPrefixedCommandName = "Test-$($testResourceName)TargetResource"; Mock Get-Command -ParameterFilter { $Name -eq $testPrefixedCommandName } -MockWith { return $true; } ImportDscResource -ModuleName $testModuleName -ResourceName $testResourceName; Assert-MockCalled Get-Command -ParameterFilter { $Name -eq $testPrefixedCommandName } -Scope It; } It 'Does not call "GetDscModule" if "UseDefault" is not specified' { $testModuleName = 'TestLabModule'; $testResourceName = 'TestLabResource'; Mock Import-Module -MockWith { }; Mock Get-Command -MockWith { }; Mock GetDscModule -MockWith { } ImportDscResource -ModuleName $testModuleName -ResourceName $testResourceName; Assert-MockCalled GetDscModule -Scope It -Exactly 0; } It 'Calls "GetDscModule" if "UseDefault" is specified' { $testModuleName = 'TestLabModule'; $testResourceName = 'TestLabResource'; Mock Import-Module -MockWith { }; Mock Get-Command -MockWith { }; Mock GetDscModule -ParameterFilter { $ModuleName -eq $testModuleName -and $ResourceName -eq $testResourceName } -MockWith { return $env:TEMP; } ImportDscResource -ModuleName $testModuleName -ResourceName $testResourceName -UseDefault; Assert-MockCalled GetDscModule -ParameterFilter { $ModuleName -eq $testModuleName -and $ResourceName -eq $testResourceName } -Scope It; } } #end context Validates "ImportDscResource" method Context 'Validates "GetDscResource" method' { It 'Calls "Get-<ResourceName>TargetResource" method' { $testResourceName = 'TestLabResource'; ## Cannot dynamically generate function names :| $getPrefixedCommandName = "Get-TestLabResourceTargetResource"; function Get-TestLabResourceTargetResource { } Mock $getPrefixedCommandName -MockWith { } GetDscResource -ResourceName $testResourceName -Parameters @{}; Assert-MockCalled $getPrefixedCommandName -Scope It; } } #end context Validates "GetDscResource" method Context 'Validates "TestDscResource" method' { ## Cannot dynamically generate function names :| $testPrefixedCommandName = 'Test-TestLabResourceTargetResource'; function Test-TestLabResourceTargetResource { } It 'Calls "Test-<ResourceName>TargetResource" method' { $testResourceName = 'TestLabResource'; Mock $testPrefixedCommandName -MockWith { } TestDscResource -ResourceName $testResourceName -Parameters @{ TestParam = 1 }; Assert-MockCalled $testPrefixedCommandName -Scope It; } It 'Return $false when "Test-<ResourceName>TargetResource" throws (#104)' { $testResourceName = 'TestLabResource'; Mock $testPrefixedCommandName -MockWith { throw 'HideMe'; } $testResult = TestDscResource -ResourceName $testResourceName -Parameters @{ TestParam = 1 } -WarningAction SilentlyContinue; $testResult | Should Be $false; } } #end context Validates "TestDscResource" method Context 'Validates "SetDscResource" method' { It 'Calls "Set-<ResourceName>TargetResource" method' { $testResourceName = 'TestLabResource'; ## Cannot dynamically generate function names :| $setPrefixedCommandName = 'Set-TestLabResourceTargetResource'; function Set-TestLabResourceTargetResource { } Mock $setPrefixedCommandName -MockWith { } SetDscResource -ResourceName $testResourceName -Parameters @{ TestParam = 1 }; Assert-MockCalled $setPrefixedCommandName -Scope It; } } #end context Validates "SetDscResource" method Context 'Validates "InvokeDscResource" method' { It 'Does not call "Set-<ResourceName>TargetResource" if "TestDscResource" passes' { $testResourceName = 'TestLabResource'; Mock TestDscResource -ParameterFilter { $ResourceName -eq $testResourceName } -MockWith { return $true; } Mock SetDscResource -ParameterFilter { $ResourceName -eq $testResourceName } -MockWith { } InvokeDscResource -ResourceName $testResourceName -Parameters @{}; Assert-MockCalled SetDscResource -ParameterFilter { $ResourceName -eq $testResourceName } -Scope It -Exactly 0; } It 'Does call "Set-<ResourceName>TargetResource" if "TestDscResource" fails' { $testResourceName = 'TestLabResource'; Mock TestDscResource -ParameterFilter { $ResourceName -eq $testResourceName } -MockWith { return $false; } Mock SetDscResource -ParameterFilter { $ResourceName -eq $testResourceName } -MockWith { } InvokeDscResource -ResourceName $testResourceName -Parameters @{}; Assert-MockCalled SetDscResource -ParameterFilter { $ResourceName -eq $testResourceName } -Scope It; } It 'Throws when "TestDscResource" fails and "ResourceName" matches "PendingReboot"' { $testResourceName = 'TestLabResourcePendingReboot'; Mock TestDscResource -ParameterFilter { $ResourceName -eq $testResourceName } -MockWith { return $false; } { InvokeDscResource -ResourceName $testResourceName -Parameters @{} } | Should Throw; } } #end context Validates "InvokeDscResource" method Context 'Validates "GetDscResourcePSGalleryUri" method' { $testDscResourceName = 'TestPackage'; $testMinimumVersion = '1.2.3'; $testRequiredVersion = '3.2.1'; $testExplicitUri = 'http://testuri.com'; It 'Returns Uri when specified' { $result = GetDscResourcePSGalleryUri -Name $testDscResourceName -MinimumVersion $testMinimumVersion -Uri $testExplicitUri; $result | Should Be $testExplicitUri; } It 'Returns latest package Uri when "RequiredVersion" is not specified' { $result = GetDscResourcePSGalleryUri -Name $testDscResourceName; $result.EndsWith($testRequiredVersion) | Should Be $false; $result.EndsWith($testMinimumVersion) | Should Be $false; } It 'Returns "RequiredVersion" when "MinimumVersion" and "RequiredVersion" are specified' { $result = GetDscResourcePSGalleryUri -Name $testDscResourceName -MinimumVersion $testMinimumVersion -RequiredVersion $testRequiredVersion; $result.EndsWith($testRequiredVersion) | Should Be $true; } } #end context Validates "GetDscResourcePSGalleryUri" method Context 'Validates "InvokeDscResourceDownload" method' { $testModuleName = 'ExistingModule'; $testModuleManifest = New-Item -Path "TestDrive:\$testModuleName.psd1" -ItemType File -Force; $testPSGalleryResource = @{ Name = $testModuleName; } $testGitHubResource = @{ Name = $testModuleName; Provider = 'GitHub'; Owner = 'TestOwner'; } Mock InvokeDscResourceDownloadFromGitHub { } Mock InvokeDscResourceDownloadFromPSGallery { } Mock GetModule -ParameterFilter { $Name -eq $testModuleName } -MockWith { return @{ Path = $testModuleManifest.FullName; }; } It 'Returns "System.IO.DirectoryInfo" object type' { Mock TestModule { return $true; } $result = InvokeDscResourceDownload -DSCResource $testPSGalleryResource; $result -is [System.IO.DirectoryInfo] | Should Be $true; } It 'Does not call "InvokeDscResourceDownloadFromPSGallery" when PSGallery module exists' { Mock TestModule { return $true; } $result = InvokeDscResourceDownload -DSCResource $testPSGalleryResource; Assert-MockCalled InvokeDscResourceDownloadFromPSGallery -Exactly 0 -Scope It; } It 'Calls "InvokeDscResourceDownloadFromPSGallery" when PSGallery module exists and "Force" is specified' { Mock TestModule { return $true; } $result = InvokeDscResourceDownload -DSCResource $testPSGalleryResource -Force; Assert-MockCalled InvokeDscResourceDownloadFromPSGallery -Scope It; } It 'Calls "InvokeDscResourceDownloadFromPSGallery" when PSGallery module does not exist' { Mock TestModule { return $false; } $result = InvokeDscResourceDownload -DSCResource $testPSGalleryResource; Assert-MockCalled InvokeDscResourceDownloadFromPSGallery -Scope It; } It 'Does not call "InvokeDscResourceDownloadFromGitHub" when GitHub module exists' { Mock TestModule { return $true; } $result = InvokeDscResourceDownload -DSCResource $testGitHubResource; Assert-MockCalled InvokeDscResourceDownloadFromGitHub -Exactly 0 -Scope It; } It 'Calls "InvokeDscResourceDownloadFromGitHub" when GitHub module exists and "Force" is specified' { Mock TestModule { return $true; } $result = InvokeDscResourceDownload -DSCResource $testGitHubResource -Force; Assert-MockCalled InvokeDscResourceDownloadFromGitHub -Scope It; } It 'Calls "InvokeDscResourceDownloadFromGitHub" when GitHub module does not exist' { Mock TestModule { return $false; } $result = InvokeDscResourceDownload -DSCResource $testGitHubResource; Assert-MockCalled InvokeDscResourceDownloadFromGitHub -Scope It; } } #end context Validates "InvokeDscResourceDownload" method Context 'Validates "InvokeDscResourceDownloadFromPSGallery" method' { $testModuleName = 'TestModule'; $testTemporaryFile = New-Item -Path "TestDrive:\$testModuleName.zip" -ItemType File -Force; $windowsPowerShellModules = Join-Path -Path $env:ProgramFiles -ChildPath '\WindowsPowerShell\Modules'; Mock SetResourceDownload { return $testTemporaryFile; } Mock ExpandZipArchive -ParameterFilter { $Path -eq $testTemporaryFile } -MockWith { } Mock Join-Path -ParameterFilter { $Path -eq $windowsPowerShellModules } { return 'TestDrive:\'} It 'Returns "System.IO.DirectoryInfo" object type' { $result = InvokeDscResourceDownloadFromPSGallery -Name $testModuleName; $result -is [System.IO.DirectoryInfo] | Should Be $true; } It 'Calls "SetResourceDownload" to download module' { $result = InvokeDscResourceDownloadFromPSGallery -Name $testModuleName; Assert-MockCalled SetResourceDownload -Scope It; } It 'Calls "ExpandZipArchive" to extract module' { $result = InvokeDscResourceDownloadFromPSGallery -Name $testModuleName; Assert-MockCalled ExpandZipArchive -ParameterFilter { $Path -eq $testTemporaryFile } -Scope It; } It 'Calls "ExpandZipArchive" with "Force" when specified' { Mock ExpandZipArchive -ParameterFilter { $Force -eq $true } -MockWith { } $result = InvokeDscResourceDownloadFromPSGallery -Name $testModuleName -Force; Assert-MockCalled ExpandZipArchive -ParameterFilter { $Force -eq $true } -Scope It; } } #end context Validates "InvokeDscResourceDownloadFromPSGallery" method Context 'Validates "InvokeDscResourceDownloadFromGitHub" method' { $gitHubRepositoryModuleName = 'GitHubRepository'; $testModuleName = 'TestModule'; $testModuleOwner = 'TestOwner'; function Install-GitHubRepository { param ( $Force )} Mock Import-Module -ParameterFilter { $Name -eq $gitHubRepositoryModuleName } -MockWith { } Mock InvokeDscResourceDownloadFromPSGallery -ParameterFilter { $Name -eq $gitHubRepositoryModuleName } -MockWith { } Mock Install-GitHubRepository { return Get-Item -Path 'TestDrive:\'; } It 'Calls "InvokeDscResourceDownloadFromPSGallery" when GitHubRepository module is not found' { Mock TestModule -ParameterFilter { $Name -eq $gitHubRepositoryModuleName } { return $false; } $result = InvokeDscResourceDownloadFromGitHub -Name $testModuleName -Owner $testModuleOwner; Assert-MockCalled InvokeDscResourceDownloadFromPSGallery -ParameterFilter { $Name -eq $gitHubRepositoryModuleName } -Scope It; } It 'Imports "GitHubRepository" module ' { Mock TestModule -ParameterFilter { $Name -eq $gitHubRepositoryModuleName } { return $true; } $result = InvokeDscResourceDownloadFromGitHub -Name $testModuleName -Owner $testModuleOwner; Assert-MockCalled Import-Module -ParameterFilter { $Name -eq $gitHubRepositoryModuleName } -Scope It; } It 'Calls "Install-GitHubRepository"' { Mock TestModule -ParameterFilter { $Name -eq $gitHubRepositoryModuleName } { return $true; } $result = InvokeDscResourceDownloadFromGitHub -Name $testModuleName -Owner $testModuleOwner; Assert-MockCalled Install-GitHubRepository -Scope It; } It 'Calls "Install-GitHubRepository" with "Force" when specified' { Mock TestModule -ParameterFilter { $Name -eq $gitHubRepositoryModuleName } { return $true; } Mock Install-GitHubRepository -ParameterFilter { $Force -eq $true } { return Get-Item -Path 'TestDrive:\'; } $result = InvokeDscResourceDownloadFromGitHub -Name $testModuleName -Owner $testModuleOwner -Force; Assert-MockCalled Install-GitHubRepository -ParameterFilter { $Force -eq $true } -Scope It; } } #end context Validates "InvokeDscResourceDownloadFromGitHub" method } #end InModuleScope } #end describe DscResource |