<#
    .SYNOPSIS
        Automated unit test for MSFT_SqlServerSecureConnection DSC resource.

    .NOTES
        To run this script locally, please make sure to first run the bootstrap
        script. Read more at
        https://github.com/PowerShell/SqlServerDsc/blob/dev/CONTRIBUTING.md#bootstrap-script-assert-testenvironment
#>

Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath '..\TestHelpers\CommonTestHelper.psm1')

if (Test-SkipContinuousIntegrationTask -Type 'Unit')
{
    return
}

$script:dscModuleName = 'SqlServerDsc'
$script:dscResourceName = 'MSFT_SqlServerSecureConnection'

#region HEADER

# Unit Test Template Version: 1.2.0
$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 'DSCResource.Tests\TestHelper.psm1') -Force

$TestEnvironment = Initialize-TestEnvironment `
    -DSCModuleName $script:dscModuleName   `
    -DSCResourceName $script:dscResourceName  `
    -TestType Unit

#endregion HEADER

function Invoke-TestSetup
{
    # Importing SQLPS stubs
    Import-Module -Name (Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath 'Stubs') -ChildPath 'SQLPSStub.psm1') -Force -Global
}

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

# Begin Testing
try
{
    Invoke-TestSetup

    InModuleScope $script:dscResourceName {
        class MockedAccessControl
        {
            [hashtable]$Access = @{
                IdentityReference = 'Everyone'
                FileSystemRights  = @{
                    value__ = '131209'
                }
            }

            [void] AddAccessRule([System.Security.AccessControl.FileSystemAccessRule] $object)
            {

            }
        }

        class MockedGetItem
        {
            [string] $Thumbprint = '12345678'
            [string] $PSPath = 'PathToItem'
            [string] $Path = 'PathToItem'
            [MockedAccessControl]$ACL = [MockedAccessControl]::new()
            [hashtable]$PrivateKey = @{
                CspKeyContainerInfo = @{
                    UniqueKeyContainerName = 'key'
                }
            }

            [MockedGetItem] GetAccessControl()
            {
                return $this
            }
        }

        $mockNamedInstanceName = 'INSTANCE'
        $mockDefaultInstanceName = 'MSSQLSERVER'
        $mockThumbprint = '123456789'
        $mockServiceAccount = 'SqlSvc'

        Describe 'SqlServerSecureConnection\Get-TargetResource' -Tag 'Get' {
            BeforeAll {
                $mockDynamic_SqlBuildVersion = '13.0.4001.0'

                $defaultParameters = @{
                    InstanceName    = $mockNamedInstanceName
                    Thumbprint      = $mockThumbprint
                    ServiceAccount  = $mockServiceAccount
                    ForceEncryption = $true
                    Ensure          = 'Present'
                }
            }

            Context 'When the system is in the desired state and Ensure is Present' {
                Mock -CommandName Get-EncryptedConnectionSetting -MockWith {
                    return @{
                        ForceEncryption = $true
                        Certificate     = $mockThumbprint
                    }
                } -Verifiable
                Mock -CommandName Test-CertificatePermission -MockWith { return $true }

                It 'Should return the the state of present' {
                    $resultGetTargetResource = Get-TargetResource @defaultParameters
                    $resultGetTargetResource.InstanceName | Should -Be $mockNamedInstanceName
                    $resultGetTargetResource.Thumbprint | Should -Be $mockThumbprint
                    $resultGetTargetResource.ServiceAccount | Should -Be $mockServiceAccount
                    $resultGetTargetResource.ForceEncryption | Should -Be $true
                    $resultGetTargetResource.Ensure | Should -Be 'Present'

                    Assert-MockCalled -CommandName Get-EncryptedConnectionSetting -Exactly -Times 1 -Scope It
                }

            }

            Context 'When the system is not in the desired state and Ensure is Present' {
                Mock -CommandName Get-EncryptedConnectionSetting -MockWith {
                    return @{
                        ForceEncryption = $false
                        Certificate     = '987654321'
                    }
                } -Verifiable
                Mock -CommandName Test-CertificatePermission -MockWith { return $false }

                It "Should return the state of absent when certificate thumbprint and certificate permissions don't match." {
                    $resultGetTargetResource = Get-TargetResource @defaultParameters
                    $resultGetTargetResource.InstanceName | Should -Be $mockNamedInstanceName
                    $resultGetTargetResource.Thumbprint | Should -Not -Be $mockThumbprint
                    $resultGetTargetResource.ServiceAccount | Should -Be $mockServiceAccount
                    $resultGetTargetResource.ForceEncryption | Should -Be $false
                    $resultGetTargetResource.Ensure | Should -Be 'Absent'

                    Assert-MockCalled -CommandName Get-EncryptedConnectionSetting -Exactly -Times 1 -Scope It
                }
            }

            Context 'When the system is not in the desired state and Ensure is Present' {
                Mock -CommandName Get-EncryptedConnectionSetting -MockWith {
                    return @{
                        ForceEncryption = $true
                        Certificate     = '987654321'
                    }
                } -Verifiable
                Mock -CommandName Test-CertificatePermission -MockWith { return $true }

                It 'Should return the state of absent when certificate permissions match but encryption settings dont' {
                    $resultGetTargetResource = Get-TargetResource @defaultParameters
                    $resultGetTargetResource.InstanceName | Should -Be $mockNamedInstanceName
                    $resultGetTargetResource.Thumbprint | Should -Not -Be $mockThumbprint
                    $resultGetTargetResource.ServiceAccount | Should -Be $mockServiceAccount
                    $resultGetTargetResource.ForceEncryption | Should -Be $true
                    $resultGetTargetResource.Ensure | Should -Be 'Absent'

                    Assert-MockCalled -CommandName Get-EncryptedConnectionSetting -Exactly -Times 1 -Scope It
                }
            }

            Context 'When the system is not in the desired state and Ensure is Present' {
                Mock -CommandName Get-EncryptedConnectionSetting -MockWith {
                    return @{
                        ForceEncryption = $true
                        Certificate     = $mockThumbprint
                    }
                } -Verifiable
                Mock -CommandName Test-CertificatePermission -MockWith { return $false }

                It 'Should return the state of absent when certificate permissions dont match but encryption settings do' {
                    $resultGetTargetResource = Get-TargetResource @defaultParameters
                    $resultGetTargetResource.InstanceName | Should -Be $mockNamedInstanceName
                    $resultGetTargetResource.Thumbprint | Should -Be $mockThumbprint
                    $resultGetTargetResource.ServiceAccount | Should -Be $mockServiceAccount
                    $resultGetTargetResource.ForceEncryption | Should -Be $true
                    $resultGetTargetResource.Ensure | Should -Be 'Absent'

                    Assert-MockCalled -CommandName Get-EncryptedConnectionSetting -Exactly -Times 1 -Scope It
                }
            }

            $defaultParameters.Ensure = 'Absent'

            Context 'When the system is in the desired state and Ensure is Absent' {
                Mock -CommandName Get-EncryptedConnectionSetting -MockWith {
                    return @{
                        ForceEncryption = $false
                        Certificate     = ''
                    }
                } -Verifiable
                Mock -CommandName Test-CertificatePermission -MockWith { return $true }

                It 'Should return the the state of absent' {
                    $resultGetTargetResource = Get-TargetResource @defaultParameters
                    $resultGetTargetResource.InstanceName | Should -Be $mockNamedInstanceName
                    $resultGetTargetResource.Thumbprint | Should -BeNullOrEmpty
                    $resultGetTargetResource.ServiceAccount | Should -Be $mockServiceAccount
                    $resultGetTargetResource.ForceEncryption | Should -Be $false
                    $resultGetTargetResource.Ensure | Should -Be 'Absent'

                    Assert-MockCalled -CommandName Get-EncryptedConnectionSetting -Exactly -Times 1 -Scope It
                }
            }

            Context 'When the system is not in the desired state and Ensure is Absent' {
                Mock -CommandName Get-EncryptedConnectionSetting -MockWith {
                    return @{
                        ForceEncryption = $true
                        Certificate     = $mockThumbprint
                    }
                } -Verifiable
                Mock -CommandName Test-CertificatePermission -MockWith { return $true }

                It 'Should return the the state of present' {
                    $resultGetTargetResource = Get-TargetResource @defaultParameters
                    $resultGetTargetResource.InstanceName | Should -Be $mockNamedInstanceName
                    $resultGetTargetResource.Thumbprint | Should -Be $mockThumbprint
                    $resultGetTargetResource.ServiceAccount | Should -Be $mockServiceAccount
                    $resultGetTargetResource.ForceEncryption | Should -Be $true
                    $resultGetTargetResource.Ensure | Should -Be 'Present'

                    Assert-MockCalled -CommandName Get-EncryptedConnectionSetting -Exactly -Times 1 -Scope It
                }
            }

            Context 'When the system is not in the desired state and Ensure is Absent' {
                Mock -CommandName Get-EncryptedConnectionSetting -MockWith {
                    return @{
                        ForceEncryption = $false
                        Certificate     = $mockThumbprint
                    }
                } -Verifiable
                Mock -CommandName Test-CertificatePermission -MockWith { return $true }

                It 'Should return the the state of present when ForceEncryption is False but a thumbprint exist.' {
                    $resultGetTargetResource = Get-TargetResource @defaultParameters
                    $resultGetTargetResource.InstanceName | Should -Be $mockNamedInstanceName
                    $resultGetTargetResource.Thumbprint | Should -Be $mockThumbprint
                    $resultGetTargetResource.ServiceAccount | Should -Be $mockServiceAccount
                    $resultGetTargetResource.ForceEncryption | Should -Be $false
                    $resultGetTargetResource.Ensure | Should -Be 'Present'

                    Assert-MockCalled -CommandName Get-EncryptedConnectionSetting -Exactly -Times 1 -Scope It
                }
            }

            Context 'When the system is not in the desired state and Ensure is Absent' {
                Mock -CommandName Get-EncryptedConnectionSetting -MockWith {
                    return @{
                        ForceEncryption = $true
                        Certificate     = ''
                    }
                } -Verifiable
                Mock -CommandName Test-CertificatePermission -MockWith { return $true }

                It 'Should return the the state of present when Certificate is null but ForceEncryption is True.' {
                    $resultGetTargetResource = Get-TargetResource @defaultParameters
                    $resultGetTargetResource.InstanceName | Should -Be $mockNamedInstanceName
                    $resultGetTargetResource.Thumbprint | Should -BeNullOrEmpty
                    $resultGetTargetResource.ServiceAccount | Should -Be $mockServiceAccount
                    $resultGetTargetResource.ForceEncryption | Should -Be $true
                    $resultGetTargetResource.Ensure | Should -Be 'Present'

                    Assert-MockCalled -CommandName Get-EncryptedConnectionSetting -Exactly -Times 1 -Scope It
                }
            }
        }

        Describe 'SqlServerSecureConnection\Set-TargetResource' -Tag 'Set' {
            BeforeAll {
                $defaultParameters = @{
                    InstanceName    = $mockNamedInstanceName
                    Thumbprint      = $mockThumbprint
                    ServiceAccount  = $mockServiceAccount
                    ForceEncryption = $true
                    Ensure          = 'Present'
                }

                $defaultAbsentParameters = @{
                    InstanceName    = $mockNamedInstanceName
                    Thumbprint      = $mockThumbprint
                    ServiceAccount  = $mockServiceAccount
                    ForceEncryption = $true
                    Ensure          = 'Absent'
                }

                Mock -CommandName Set-EncryptedConnectionSetting -Verifiable
                Mock -CommandName Set-CertificatePermission -Verifiable
                Mock -CommandName Restart-SqlService -Verifiable
            }

            Context 'When the system is not in the desired state' {

                Context 'When only certificate permissions are set' {
                    Mock -CommandName Get-TargetResource -MockWith {
                        return @{
                            InstanceName    = $mockNamedInstanceName
                            Thumbprint      = '987654321'
                            ServiceAccount  = $mockServiceAccount
                            ForceEncryption = $false
                            Ensure          = 'Present'
                        }
                    }
                    Mock -CommandName Test-CertificatePermission -MockWith { return $true }

                    It 'Should configure only ForceEncryption and Certificate thumbprint' {
                        { Set-TargetResource @defaultParameters } | Should -Not -Throw

                        Assert-MockCalled -CommandName Set-EncryptedConnectionSetting -Exactly -Times 1 -Scope It

                        Assert-MockCalled -CommandName Set-CertificatePermission -Exactly -Times 0 -Scope It

                        Assert-MockCalled -CommandName Restart-SqlService -Exactly -Times 1 -Scope It
                    }
                }

                Context 'When there is no certificate permissions set' {
                    Mock -CommandName Get-TargetResource -MockWith {
                        return @{
                            InstanceName    = $mockNamedInstanceName
                            Thumbprint      = $mockThumbprint
                            ServiceAccount  = $mockServiceAccount
                            ForceEncryption = $true
                            Ensure          = 'Present'
                        }
                    }
                    Mock -CommandName Test-CertificatePermission -MockWith { return $false }
                    It 'Should configure only certificate permissions' {
                        { Set-TargetResource @defaultParameters } | Should -Not -Throw

                        Assert-MockCalled -CommandName Set-EncryptedConnectionSetting -Exactly -Times 0 -Scope It

                        Assert-MockCalled -CommandName Set-CertificatePermission -Exactly -Times 1 -Scope It

                        Assert-MockCalled -CommandName Restart-SqlService -Exactly -Times 1 -Scope It
                    }
                }

                Context 'When no settings are configured' {
                    Mock -CommandName Get-TargetResource -MockWith {
                        return @{
                            InstanceName    = $mockNamedInstanceName
                            Thumbprint      = '987654321'
                            ServiceAccount  = $mockServiceAccount
                            ForceEncryption = $false
                            Ensure          = 'Present'
                        }
                    }
                    Mock -CommandName Test-CertificatePermission -MockWith { return $false }

                    It 'Should configure Encryption settings and certificate permissions' {
                        { Set-TargetResource @defaultParameters } | Should -Not -Throw

                        Assert-MockCalled -CommandName Set-EncryptedConnectionSetting -Exactly -Times 1 -Scope It

                        Assert-MockCalled -CommandName Set-CertificatePermission -Exactly -Times 1 -Scope It

                        Assert-MockCalled -CommandName Restart-SqlService -Exactly -Times 1 -Scope It
                    }
                }

                Context 'When ensure is absent' {
                    Mock -CommandName Get-TargetResource -MockWith {
                        return @{
                            InstanceName    = $mockNamedInstanceName
                            Thumbprint      = $mockThumbprint
                            ServiceAccount  = $mockServiceAccount
                            ForceEncryption = $true
                            Ensure          = 'Absent'
                        }
                    }
                    Mock -CommandName Test-CertificatePermission -MockWith { return $false }

                    It 'Should configure Encryption settings setting certificate to empty string' {
                        { Set-TargetResource @defaultAbsentParameters } | Should -Not -Throw

                        Assert-MockCalled -CommandName Set-EncryptedConnectionSetting -Exactly -Times 1 -Scope It

                        Assert-MockCalled -CommandName Set-CertificatePermission -Exactly -Times 0 -Scope It

                        Assert-MockCalled -CommandName Restart-SqlService -Exactly -Times 1 -Scope It
                    }
                }
            }
        }

        Describe 'SqlServerSecureConnection\Test-TargetResource' -Tag 'Test' {
            Context 'When the system is not in the desired state' {
                Context 'When ForceEncryption is not configured properly' {
                    BeforeAll {
                        Mock -CommandName Get-TargetResource -MockWith {
                            return @{
                                InstanceName    = $mockNamedInstanceName
                                Thumbprint      = $mockThumbprint
                                ServiceAccount  = $mockServiceAccount
                                ForceEncryption = $false
                                Ensure          = 'Absent'
                            }
                        } -Verifiable

                        $testParameters = @{
                            InstanceName    = $mockNamedInstanceName
                            Thumbprint      = $mockThumbprint
                            ServiceAccount  = $mockServiceAccount
                            ForceEncryption = $true
                            Ensure          = 'Present'
                        }
                    }

                    It 'Should return state as not in desired state' {
                        $resultTestTargetResource = Test-TargetResource @testParameters
                        $resultTestTargetResource | Should -Be $false
                    }
                }

                Context 'When Thumbprint is not configured properly' {
                    BeforeAll {
                        Mock -CommandName Get-TargetResource -MockWith {
                            return @{
                                InstanceName    = $mockNamedInstanceName
                                Thumbprint      = '987654321'
                                ServiceAccount  = $mockServiceAccount
                                ForceEncryption = $true
                                Ensure          = 'Absent'
                            }
                        } -Verifiable

                        $testParameters = @{
                            InstanceName    = $mockNamedInstanceName
                            Thumbprint      = $mockThumbprint
                            ServiceAccount  = $mockServiceAccount
                            ForceEncryption = $true
                            Ensure          = 'Present'
                        }
                    }

                    It 'Should return state as not in desired state' {
                        $resultTestTargetResource = Test-TargetResource @testParameters
                        $resultTestTargetResource | Should -Be $false
                    }
                }

                Context 'When certificate permission is not set' {
                    BeforeAll {
                        Mock -CommandName Get-TargetResource -MockWith {
                            return @{
                                InstanceName    = $mockNamedInstanceName
                                Thumbprint      = $mockThumbprint
                                ServiceAccount  = $mockServiceAccount
                                ForceEncryption = $true
                                Ensure          = 'Absent'
                            }
                        } -Verifiable

                        Mock -CommandName Test-CertificatePermission -MockWith { return $false }

                        $testParameters = @{
                            InstanceName    = $mockNamedInstanceName
                            Thumbprint      = $mockThumbprint
                            ServiceAccount  = $mockServiceAccount
                            ForceEncryption = $true
                            Ensure          = 'Present'
                        }
                    }

                    It 'Should return state as not in desired state' {
                        $resultTestTargetResource = Test-TargetResource @testParameters
                        $resultTestTargetResource | Should -Be $false
                    }
                }

                Context 'When Ensure is Absent' {
                    BeforeAll {
                        Mock -CommandName Get-TargetResource -MockWith {
                            return @{
                                InstanceName    = $mockNamedInstanceName
                                Thumbprint      = $mockThumbprint
                                ServiceAccount  = $mockServiceAccount
                                ForceEncryption = $true
                                Ensure          = 'Absent'
                            }
                        } -Verifiable

                        $testParameters = @{
                            InstanceName    = $mockNamedInstanceName
                            Thumbprint      = $mockThumbprint
                            ServiceAccount  = $mockServiceAccount
                            ForceEncryption = $true
                            Ensure          = 'Present'
                        }
                    }

                    It 'Should return state as not in desired state' {
                        $resultTestTargetResource = Test-TargetResource @testParameters
                        $resultTestTargetResource | Should -Be $false
                    }
                }
            }

            Context 'When the system is in the desired state' {
                BeforeAll {
                    Mock -CommandName Get-TargetResource -MockWith {
                        return @{
                            InstanceName    = $mockNamedInstanceName
                            Thumbprint      = $mockThumbprint
                            ServiceAccount  = $mockServiceAccount
                            ForceEncryption = $true
                            Ensure          = 'Present'
                        }
                    } -Verifiable

                    Mock -CommandName Test-CertificatePermission -MockWith { return $true }

                    $testParameters = @{
                        InstanceName    = $mockNamedInstanceName
                        Thumbprint      = $mockThumbprint
                        ServiceAccount  = $mockServiceAccount
                        ForceEncryption = $true
                        Ensure          = 'Present'
                    }
                }

                It 'Should return state as in desired state' {
                    $resultTestTargetResource = Test-TargetResource @testParameters
                    $resultTestTargetResource | Should -Be $true
                }
            }
        }

        Describe 'SqlServerSecureConnection\Get-EncryptedConnectionSetting' -Tag 'Helper' {

            Mock -CommandName 'Get-ItemProperty' -MockWith {
                return @{
                    ForceEncryption = '1'
                }
            } -ParameterFilter { $Name -eq 'ForceEncryption' } -Verifiable
            Mock -CommandName 'Get-ItemProperty' -MockWith {
                return @{
                    Certificate = '12345678'
                }
            } -ParameterFilter { $Name -eq 'Certificate' } -Verifiable

            Context 'When calling a method that execute successfully' {
                BeforeAll {
                    Mock -CommandName 'Get-SqlEncryptionValue' -MockWith {
                        return [MockedGetItem]::new()
                    } -Verifiable
                }

                It 'Should return hashtable with ForceEncryption and Certificate' {
                    $result = Get-EncryptedConnectionSetting -InstanceName 'NamedInstance'
                    $result.Certificate | Should -Be '12345678'
                    $result.ForceEncryption | Should -Be 1
                    $result | Should -BeOfType [Hashtable]
                    Assert-VerifiableMock
                }
            }

            Context 'When calling a method that executes unsuccesfuly' {
                BeforeAll {
                    Mock -CommandName 'Get-SqlEncryptionValue' -MockWith {
                        return $null
                    }
                }

                It 'Should return null' {
                    $result = Get-EncryptedConnectionSetting -InstanceName 'NamedInstance'
                    $result | Should -BeNullOrEmpty
                    Assert-VerifiableMock
                }
            }
        }

        Describe 'SqlServerSecureConnection\Set-EncryptedConnectionSetting' -Tag 'Helper' {
            Context 'When calling a method that execute successfully' {
                BeforeAll {
                    Mock -CommandName 'Get-SqlEncryptionValue' -MockWith {
                        return [MockedGetItem]::new()
                    }
                    Mock -CommandName 'Set-ItemProperty' -Verifiable
                }

                It 'Should not throw' {
                    { Set-EncryptedConnectionSetting -InstanceName 'NamedInstance' -Thumbprint '12345678' -ForceEncryption $true } | Should -Not -Throw
                    Assert-VerifiableMock
                }
            }

            Context 'When calling a method that executes unsuccesfuly' {
                BeforeAll {
                    Mock -CommandName 'Get-SqlEncryptionValue' -MockWith {
                        return $null
                    } -Verifiable
                    Mock -CommandName 'Set-ItemProperty'
                }

                It 'Should throw' {
                    { Set-EncryptedConnectionSetting -InstanceName 'NamedInstance' -Thumbprint '12345678' -ForceEncryption $true } | Should -Throw
                    Assert-MockCalled -CommandName 'Set-ItemProperty' -Times 0
                    Assert-VerifiableMock
                }
            }
        }

        Describe 'SqlServerSecureConnection\Test-CertificatePermission' -Tag 'Helper' {
            Context 'When calling a method that execute successfully' {
                BeforeAll {
                    Mock -CommandName 'Get-CertificateAcl' -MockWith {
                        return [MockedGetItem]::new()
                    } -Verifiable
                }

                It 'Should return True' {
                    $result = Test-CertificatePermission -Thumbprint '12345678' -ServiceAccount 'Everyone'
                    $result | Should -be $true
                    Assert-VerifiableMock
                }
            }

            Context 'When calling a method that execute successfully' {
                BeforeAll {
                    Mock -CommandName 'Get-CertificateAcl' -MockWith {
                        $mockedItem = [MockedGetItem]::new()
                        $mockedItem.ACL = $null
                        return $mockedItem
                    } -Verifiable
                }

                It 'Should return False when no permissions were found' {
                    $result = Test-CertificatePermission -Thumbprint '12345678' -ServiceAccount 'Everyone'
                    $result | Should -be $false
                    Assert-VerifiableMock
                }
            }

            Context 'When calling a method that execute successfully' {
                BeforeAll {
                    Mock -CommandName 'Get-CertificateAcl' -MockWith {
                        $mockedItem = [MockedGetItem]::new()
                        $mockedItem.ACL.FileSystemRights.Value__ = 1
                        return $mockedItem
                    } -Verifiable
                }

                It 'Should return False when the wrong permissions are added' {
                    $result = Test-CertificatePermission -Thumbprint '12345678' -ServiceAccount 'Everyone'
                    $result | Should -be $false
                    Assert-VerifiableMock
                }
            }

            Context 'When calling a method that executes unsuccesfuly' {
                BeforeAll {
                    Mock -CommandName 'Get-CertificateAcl' -MockWith {
                        return $null
                    } -Verifiable
                }

                It 'Should return False' {
                    $result = Test-CertificatePermission -Thumbprint '12345678' -ServiceAccount 'Everyone'
                    $result | Should -be $false
                    Assert-VerifiableMock
                }
            }
        }

        Describe 'SqlServerSecureConnection\Set-CertificatePermission' -Tag 'Helper' {
            Context 'When calling a method that execute successfully' {
                BeforeAll {
                    Mock -CommandName 'Get-CertificateAcl' -MockWith {
                        return [MockedGetItem]::new()
                    } -Verifiable
                    Mock -CommandName 'Set-Acl' -Verifiable
                }

                It 'Should not throw' {
                    { Set-CertificatePermission -Thumbprint '12345678' -ServiceAccount 'Everyone' } | Should -Not -Throw
                    Assert-VerifiableMock
                }
            }

            Context 'When calling a method that executes unsuccesfuly' {
                BeforeAll {
                    Mock -CommandName 'Get-Item' -MockWith {
                        return $null
                    } -Verifiable
                    Mock -CommandName 'Get-ChildItem' -MockWith {
                        return $null
                    } -Verifiable
                }

                It 'Should throw' {
                    { Set-CertificatePermission -Thumbprint '12345678' -ServiceAccount 'Everyone' } | Should -Throw
                    Assert-VerifiableMock
                }
            }
        }

        Describe 'SqlServerSecureConnection\Get-CertificateAcl' -Tag 'Helper' {
            Context 'When calling a method that execute successfully' {
                BeforeAll {
                    Mock -CommandName 'Get-ChildItem' -MockWith {
                        return [MockedGetItem]::new()
                    } -Verifiable

                    Mock -CommandName 'Get-Item' -MockWith {
                        return [MockedGetItem]::new()
                    } -Verifiable
                }

                It 'Should not throw' {
                    { Get-CertificateAcl -Thumbprint '12345678' } | Should -Not -Throw
                    Assert-VerifiableMock
                }
            }
        }

        Describe 'SqlServerSecureConnection\Get-SqlEncryptionValue' -Tag 'Helper' {
            Context 'When calling a method that execute successfully' {
                BeforeAll {
                    Mock -CommandName 'Get-ItemProperty' -MockWith {
                        return [MockedGetItem]::new()
                    } -Verifiable
                    Mock -CommandName 'Get-Item' -MockWith {
                        return [MockedGetItem]::new()
                    } -Verifiable
                }

                It 'Should not throw' {
                    { Get-SqlEncryptionValue -InstanceName $mockNamedInstanceName } | Should -Not -Throw
                    Assert-VerifiableMock
                }
            }

            Context 'When calling a method that execute unsuccessfully' {
                BeforeAll {
                    Mock -CommandName 'Get-ItemProperty' -MockWith {
                        throw "Error"
                    } -Verifiable
                    Mock -CommandName 'Get-Item' -MockWith {
                        return [MockedGetItem]::new()
                    } -Verifiable
                }

                It 'Should throw with expected message' {
                    { Get-SqlEncryptionValue -InstanceName $mockNamedInstanceName } | Should -Throw -ExpectedMessage "SQL instance '$mockNamedInstanceName' not found on SQL Server."
                    Assert-VerifiableMock
                }
            }
        }
    }
}
finally
{
    Invoke-TestCleanup
}
