Tests/Unit/MSFT_xExchAntiMalwareScanning.tests.ps1

#region HEADER
$script:DSCModuleName = 'xExchange'
$script:DSCResourceName = 'MSFT_xExchAntiMalwareScanning'

# Unit Test Template Version: 1.2.3
$script:moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
if ( (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests'))) -or `
     (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) )
{
    & git @('clone', 'https://github.com/PowerShell/DscResource.Tests.git', (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests'))
}

Import-Module -Name (Join-Path -Path $script:moduleRoot -ChildPath (Join-Path -Path 'DSCResource.Tests' -ChildPath 'TestHelper.psm1')) -Force
Import-Module -Name (Join-Path -Path $script:moduleRoot -ChildPath (Join-Path -Path 'Tests' -ChildPath (Join-Path -Path 'TestHelpers' -ChildPath 'xExchangeTestHelper.psm1'))) -Global -Force

$TestEnvironment = Initialize-TestEnvironment `
    -DSCModuleName $script:DSCModuleName `
    -DSCResourceName $script:DSCResourceName `
    -ResourceType 'Mof' `
    -TestType Unit

#endregion HEADER

function Invoke-TestSetup
{

}

function Invoke-TestCleanup
{
    Restore-TestEnvironment -TestEnvironment $TestEnvironment
}

# Begin Testing
try
{
    Invoke-TestSetup

    InModuleScope $script:DSCResourceName {
        <#
            Define an empty function for Get-TransportAgent, so pester has something to Mock
            This cmdlet is normally loaded as part of Get-RemoteExchangeSession.
        #>

        function Get-TransportAgent {}

        $fakeCredentials       = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'fakeuser', (New-Object -TypeName System.Security.SecureString)
        $mockEnableScriptPath  = 'C:\Program Files\Microsoft\Exchange Server\V15\Scripts\Enable-AntimalwareScanning.ps1'
        $mockDisableScriptPath = 'C:\Program Files\Microsoft\Exchange Server\V15\Scripts\Disable-AntimalwareScanning.ps1'

        Describe 'MSFT_xExchAntiMalwareScanning\Get-TargetResource' -Tag 'Get' {
            AfterEach {
                Assert-VerifiableMock
            }

            $getTargetResourceParams = @{
                Enabled    = $true
                Credential = $fakeCredentials
            }

            $getTransportAgentStandardOutput = @{
                Enabled = $true
            }

            Context 'When Get-TargetResource is called' {
                Mock -CommandName Get-RemoteExchangeSession -Verifiable
                Mock -CommandName Get-TransportAgent -Verifiable -MockWith { return $getTransportAgentStandardOutput }

                Test-CommonGetTargetResourceFunctionality -GetTargetResourceParams $getTargetResourceParams

                It 'Should return Enabled set to True if Get-TransportAgent returns Enabled set to True' {
                    $getResults = Get-TargetResource @getTargetResourceParams

                    $getResults.Enabled | Should -Be $true
                }

                It 'Should return Enabled set to False if Get-TransportAgent returns Enabled set to False' {
                    $defaultValue = $getTransportAgentStandardOutput.Enabled
                    $getTransportAgentStandardOutput.Enabled = $false

                    Mock -CommandName Get-TransportAgent -Verifiable -MockWith { return $getTransportAgentStandardOutput }

                    $getResults = Get-TargetResource @getTargetResourceParams

                    $getResults.Enabled | Should -Be $false

                    $getTransportAgentStandardOutput.Enabled = $defaultValue
                }
            }
        }

        Describe 'MSFT_xExchAntiMalwareScanning\Set-TargetResource' -Tag 'Set' {
            AfterEach {
                Assert-VerifiableMock
            }

            Context 'When Enabled is set to True and AllowServiceRestart is set to False' {
                It 'Should run Enable-AntimalwareScanning.ps1 but not attempt a service restart' {
                    Mock -CommandName Write-Warning -Verifiable
                    Mock -CommandName Get-ItemProperty -Verifiable -MockWith {
                        return @{
                            MsiInstallPath = 'C:\Program Files\Microsoft\Exchange Server\V15\'
                        }
                    }
                    Mock -CommandName Invoke-DotSourcedScript -Verifiable -ParameterFilter {$ScriptPath -eq $mockEnableScriptPath -and $ScriptParams.Count -eq 0}

                    Set-TargetResource -Enabled $true -Credential $fakeCredentials -AllowServiceRestart $false
                }
            }

            Context 'When Enabled is set to True and AllowServiceRestart is set to True' {
                It 'Should run Enable-AntimalwareScanning.ps1 and attempt a service restart' {
                    Mock -CommandName Get-ItemProperty -Verifiable -MockWith {
                        return @{
                            MsiInstallPath = 'C:\Program Files\Microsoft\Exchange Server\V15\'
                        }
                    }
                    Mock -CommandName Invoke-DotSourcedScript -Verifiable -ParameterFilter {$ScriptPath -eq $mockEnableScriptPath -and $ScriptParams.ContainsKey('ForceRestart') -and $ScriptParams.ForceRestart -eq $true}

                    Set-TargetResource -Enabled $true -Credential $fakeCredentials -AllowServiceRestart $true
                }
            }

            Context 'When Enabled is set to False and AllowServiceRestart is set to False' {
                It 'Should run Disable-AntimalwareScanning.ps1 but not attempt a service restart' {
                    Mock -CommandName Write-Warning -Verifiable
                    Mock -CommandName Get-ItemProperty -Verifiable -MockWith {
                        return @{
                            MsiInstallPath = 'C:\Program Files\Microsoft\Exchange Server\V15\'
                        }
                    }
                    Mock -CommandName Invoke-DotSourcedScript -Verifiable -ParameterFilter {$ScriptPath -eq $mockDisableScriptPath -and $ScriptParams.Count -eq 0}

                    Set-TargetResource -Enabled $false -Credential $fakeCredentials -AllowServiceRestart $false
                }
            }

            Context 'When Enabled is set to False and AllowServiceRestart is set to True' {
                It 'Should run Disable-AntimalwareScanning.ps1 and attempt a service restart' {
                    Mock -CommandName Get-ItemProperty -Verifiable -MockWith {
                        return @{
                            MsiInstallPath = 'C:\Program Files\Microsoft\Exchange Server\V15\'
                        }
                    }
                    Mock -CommandName Invoke-DotSourcedScript -Verifiable -ParameterFilter {$ScriptPath -eq $mockDisableScriptPath -and $ScriptParams.ContainsKey('ForceRestart') -and $ScriptParams.ForceRestart -eq $true}

                    Set-TargetResource -Enabled $false -Credential $fakeCredentials -AllowServiceRestart $true
                }
            }
        }

        Describe 'MSFT_xExchAntiMalwareScanning\Test-TargetResource' -Tag 'Test' {
            AfterEach {
                Assert-VerifiableMock
            }

            Context 'When Enabled is set to True' {
                It 'Should return True when Get-TransportAgent returns Enabled set to True' {
                    Mock -CommandName Get-RemoteExchangeSession -Verifiable -MockWith { return $null }
                    Mock -CommandName Get-TransportAgent -Verifiable -MockWith {
                        return @{
                            Enabled = $true
                        }
                    }

                    $testResults = Test-TargetResource -Enabled $true -Credential $fakeCredentials

                    $testResults | Should -Be $true
                }

                It 'Should return False when Get-TransportAgent returns Enabled set to False' {
                    Mock -CommandName Get-RemoteExchangeSession -Verifiable -MockWith { return $null }
                    Mock -CommandName Get-TransportAgent -Verifiable -MockWith {
                        return @{
                            Enabled = $false
                        }
                    }

                    $testResults = Test-TargetResource -Enabled $true -Credential $fakeCredentials

                    $testResults | Should -Be $false
                }
            }

            Context 'When Enabled is set to False' {
                It 'Should return False when Get-TransportAgent returns Enabled set to True' {
                    Mock -CommandName Get-RemoteExchangeSession -Verifiable -MockWith { return $null }
                    Mock -CommandName Get-TransportAgent -Verifiable -MockWith {
                        return @{
                            Enabled = $true
                        }
                    }

                    $testResults = Test-TargetResource -Enabled $false -Credential $fakeCredentials

                    $testResults | Should -Be $false
                }

                It 'Should return True when Get-TransportAgent returns Enabled set to False' {
                    Mock -CommandName Get-RemoteExchangeSession -Verifiable -MockWith { return $null }
                    Mock -CommandName Get-TransportAgent -Verifiable -MockWith {
                        return @{
                            Enabled = $false
                        }
                    }

                    $testResults = Test-TargetResource -Enabled $false -Credential $fakeCredentials

                    $testResults | Should -Be $true
                }
            }

            Context 'When Get-TransportAgent does not return an agent status' {
                It 'Should return False' {
                    Mock -CommandName Get-RemoteExchangeSession -Verifiable -MockWith { return $null }
                    Mock -CommandName Get-TransportAgent -Verifiable -MockWith { return $null}

                    $testResults = Test-TargetResource -Enabled $false -Credential $fakeCredentials

                    $testResults | Should -Be $false
                }
            }
        }
    }
}
finally
{
    Invoke-TestCleanup
}