Tests/Unit/MSFT_xSQLServerAlwaysOnAvailabilityGroup.Tests.ps1

$script:DSCModuleName      = 'xSQLServer'
$script:DSCResourceName    = 'MSFT_xSQLServerAlwaysOnAvailabilityGroup'

# Unit Test Template Version: 1.1.0
[String] $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 (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force
$TestEnvironment = Initialize-TestEnvironment `
    -DSCModuleName $script:DSCModuleName `
    -DSCResourceName $script:DSCResourceName `
    -TestType Unit

# Loading stub cmdlets
Import-Module -Name ( Join-Path -Path ( Join-Path -Path $PSScriptRoot -ChildPath Stubs ) -ChildPath SQLPSStub.psm1 ) -Force -Global
Add-Type -Path ( Join-Path -Path ( Join-Path -Path $PSScriptRoot -ChildPath Stubs ) -ChildPath SMO.cs )



# Begin Testing
try
{
    InModuleScope $script:DSCResourceName {
        $defaultAbsentParameters = @{
            Name = 'AbsentAG'
            SQLInstanceName = 'MSSQLSERVER'
            SQLServer = 'Server1'
            Ensure = 'Present'
            AutomatedBackupPreference = 'Secondary'
            AvailabilityMode = 'AsynchronousCommit'
            BackupPriority = 50
            BasicAvailabilityGroup = $false
            ConnectionModeInPrimaryRole = 'AllowAllConnections'
            ConnectionModeInSecondaryRole = 'AllowNoConnections'
            FailureConditionLevel = 'OnServerDown'
            FailoverMode = 'Manual'
            HealthCheckTimeout = '30000'
            EndpointHostName = 'Server1'
        }

        $defaultPresentParameters = @{
            Name = 'PresentAG'
            SQLInstanceName = 'MSSQLSERVER'
            SQLServer = 'Server1'
            Ensure = 'Present'
            AutomatedBackupPreference = 'Secondary'
            AvailabilityMode = 'AsynchronousCommit'
            BackupPriority = 50
            BasicAvailabilityGroup = $false
            ConnectionModeInPrimaryRole = 'AllowAllConnections'
            ConnectionModeInSecondaryRole = 'AllowNoConnections'
            FailureConditionLevel = 'OnServerDown'
            FailoverMode = 'Manual'
            HealthCheckTimeout = '30000'
            EndpointHostName = 'Server1'
        }

        #region Login mocks

            $mockLogins = @{} # Will be dynamically set during tests

            $mockNtServiceClusSvcName = 'NT SERVICE\ClusSvc'
            $mockNtAuthoritySystemName = 'NT AUTHORITY\SYSTEM'

            $mockAllLoginsAbsent = @{}

            $mockNtServiceClusSvcPresent = @{
                $mockNtServiceClusSvcName = ( New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login($mockSqlServer,$mockNtServiceClusSvcName) )
            }

            $mockNtAuthoritySystemPresent = @{
                $mockNtAuthoritySystemName = ( New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login($mockSqlServer,$mockNtAuthoritySystemName) )
            }

            $mockAllLoginsPresent = @{
                $mockNtServiceClusSvcName = ( New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login($mockSqlServer,$mockNtServiceClusSvcName) )
                $mockNtAuthoritySystemName = ( New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login($mockSqlServer,$mockNtAuthoritySystemName) )
            }

        #endregion

        foreach ( $sqlVersion in @(12,13) )
        {
            # Create the availability replica
            $mockAvailabilityReplica = New-Object Microsoft.SqlServer.Management.Smo.AvailabilityReplica
            $mockAvailabilityReplica.Name = 'Server1'
            $mockAvailabilityReplica.AvailabilityMode = 'AsynchronousCommit'
            $mockAvailabilityReplica.BackupPriority = 50
            $mockAvailabilityReplica.ConnectionModeInPrimaryRole = 'AllowAllConnections'
            $mockAvailabilityReplica.ConnectionModeInSecondaryRole = 'AllowNoConnections'
            $mockAvailabilityReplica.EndpointUrl = 'TCP://Server1:5022'
            $mockAvailabilityReplica.FailoverMode = 'Manual'

            # Create the availability replica collection to store the availability replicas in
            $mockAvailabilityReplicaCollection = New-Object Microsoft.SqlServer.Management.Smo.AvailabilityReplicaCollection
            $mockAvailabilityReplicaCollection.Add($mockAvailabilityReplica)

            # Create the Availability Group
            $mockAvailabilityGroup = New-Object Microsoft.SqlServer.Management.Smo.AvailabilityGroup
            $mockAvailabilityGroup.Name = 'PresentAG'
            $mockAvailabilityGroup.AutomatedBackupPreference = 'Secondary'
            $mockAvailabilityGroup.FailureConditionLevel = 'OnServerDown'
            $mockAvailabilityGroup.HealthCheckTimeout = 30000
            $mockAvailabilityGroup.PrimaryReplicaServerName = 'Server1'
            $mockAvailabilityGroup.LocalReplicaRole = 'Primary'
            $mockAvailabilityGroup.AvailabilityReplicas = $mockAvailabilityReplicaCollection

            # Create the availability group collectionto store the availability groups in
            $mockAvailabilityGroupCollection = New-Object Microsoft.SqlServer.Management.Smo.AvailabilityGroupCollection
            $mockAvailabilityGroupCollection.Add($mockAvailabilityGroup)

            # Create the master database
            $mockMasterDatabaseObject = New-Object Microsoft.SqlServer.Management.Smo.Database
            $mockMasterDatabaseObject.ID = 1
            $mockMasterDatabaseObject.Name = 'master'

            # Create the databases collection
            $mockDatabaseCollection = New-Object Microsoft.SqlServer.Management.Smo.DatabaseCollection
            $mockDatabaseCollection.Add($mockMasterDatabaseObject)

            # Create the database mirroring endpoint
            $mockDatabaseMirroringEndpoint = New-Object Microsoft.SqlServer.Management.Smo.Endpoint
            $mockDatabaseMirroringEndpoint.Name = 'Hadr_endpoint'
            $mockDatabaseMirroringEndpoint.EndpointType = 'DatabaseMirroring'
            $mockDatabaseMirroringEndpoint.Protocol = @{
                TCP = @{
                    ListenerPort = 5022
                }
            }

            # Create the endpointcollection object
            $mockEndpointCollection = New-Object Microsoft.SqlServer.Management.Smo.EndpointCollection
            $mockEndpointCollection.Add($mockDatabaseMirroringEndpoint)

            # Create the server object
            $mockServerObject = New-Object Microsoft.SqlServer.Management.Smo.Server
            $mockServerObject.AvailabilityGroups = $mockAvailabilityGroupCollection
            $mockServerObject.Databases = $mockDatabaseCollection
            $mockServerObject.Endpoints = $mockEndpointCollection
            $mockServerObject.IsHadrEnabled = $true
            $mockServerObject.Logins = $mockLogins
            $mockServerObject.Name = 'Server1'
            $mockServerObject.NetName = 'Server1'
            $mockServerObject.Roles = @{}
            $mockServerObject.Version = @{
                Major = $sqlVersion
            }

            # Clone the server object to a version specific variable
            $mockConnectSqlServerObjectVariableName = "mockConnectSqlVersion$($sqlVersion)ServerObject"
            New-Variable -Name $mockConnectSqlServerObjectVariableName
            Set-Variable -Name $mockConnectSqlServerObjectVariableName -Value $mockServerObject.Clone()
        }

        $mockConnectSqlVersion12 = { $mockConnectSqlVersion12ServerObject }
        $mockConnectSqlVersion13 = { $mockConnectSqlVersion13ServerObject }

        $mockConnectSqlVersion12IncorrectEndpointProtocol = {
            $mock = New-Object PSObject -Property @{
                AvailabilityGroups = @{
                    PresentAG = @{
                        AutomatedBackupPreference = 'Secondary'
                        FailureConditionLevel = 'OnServerDown'
                        HealthCheckTimeout = 30000
                        Name = 'AvailabilityGroup1'
                        PrimaryReplicaServerName = 'Server1'
                        LocalReplicaRole = 'Primary'
                        AvailabilityReplicas = @{
                            Server1 = @{
                                AvailabilityMode = 'AsynchronousCommit'
                                BackupPriority = 50
                                ConnectionModeInPrimaryRole = 'AllowAllConnections'
                                ConnectionModeInSecondaryRole = 'AllowNoConnections'
                                EndpointUrl = 'UDP://Server1:5022'
                                FailoverMode = 'Manual'
                            }
                        }
                    }
                }
                Databases = @{
                    'master' = @{
                        Name = 'master'
                    }
                }
                Endpoints = @(
                    New-Object PSObject -Property @{
                        EndpointType = 'DatabaseMirroring'
                        Protocol = @{
                            TCP = @{
                                ListenerPort = 5022
                            }
                        }
                    }
                )
                IsHadrEnabled = $true
                Logins = $mockLogins
                Name = 'Server1'
                NetName = 'Server1'
                Roles = @{}
                Version = @{
                    Major = 12
                }
            }

            # Add the ExecuteWithResults method
            $mock.Databases['master'] | Add-Member -MemberType ScriptMethod -Name ExecuteWithResults -Value {
                return New-Object PSObject -Property @{
                    Tables = @{
                        Rows = @{
                            permission_name = @(
                                'testing'
                            )
                        }
                    }
                }
            }

            # Type the mock as a server object
            $mock.PSObject.TypeNames.Insert(0,'Microsoft.SqlServer.Management.Smo.Server')

            return $mock
        }

        $mockConnectSqlVersion12IncorrectEndpointPort = {
            $mock = New-Object PSObject -Property @{
                AvailabilityGroups = @{
                    PresentAG = @{
                        AutomatedBackupPreference = 'Secondary'
                        FailureConditionLevel = 'OnServerDown'
                        HealthCheckTimeout = 30000
                        Name = 'AvailabilityGroup1'
                        PrimaryReplicaServerName = 'Server1'
                        LocalReplicaRole = 'Primary'
                        AvailabilityReplicas = @{
                            Server1 = @{
                                AvailabilityMode = 'AsynchronousCommit'
                                BackupPriority = 50
                                ConnectionModeInPrimaryRole = 'AllowAllConnections'
                                ConnectionModeInSecondaryRole = 'AllowNoConnections'
                                EndpointUrl = 'TCP://Server1:1000'
                                FailoverMode = 'Manual'
                            }
                        }
                    }
                }
                Databases = @{
                    'master' = @{
                        Name = 'master'
                    }
                }
                Endpoints = @(
                    New-Object PSObject -Property @{
                        EndpointType = 'DatabaseMirroring'
                        Protocol = @{
                            TCP = @{
                                ListenerPort = 5022
                            }
                        }
                    }
                )
                IsHadrEnabled = $true
                Logins = $mockLogins
                Name = 'Server1'
                NetName = 'Server1'
                Roles = @{}
                Version = @{
                    Major = 12
                }
            }

            # Add the ExecuteWithResults method
            $mock.Databases['master'] | Add-Member -MemberType ScriptMethod -Name ExecuteWithResults -Value {
                return New-Object PSObject -Property @{
                    Tables = @{
                        Rows = @{
                            permission_name = @(
                                'testing'
                            )
                        }
                    }
                }
            }

            # Type the mock as a server object
            $mock.PSObject.TypeNames.Insert(0,'Microsoft.SqlServer.Management.Smo.Server')

            return $mock
        }

        $mockNewSqlAvailabilityReplica = {
            $mock = New-Object Microsoft.SqlServer.Management.Smo.AvailabilityReplica
            $mock.AvailabilityMode = 'AsynchronousCommit'
            $mock.BackupPriority = 50
            $mock.ConnectionModeInPrimaryRole = 'AllowAllConnections'
            $mock.ConnectionModeInSecondaryRole = 'AllowNoConnections'
            $mock.EndpointUrl = 'TCP://Server1:5022'
            $mock.FailoverMode = 'Manual'
            $mock.Name = 'Server1'

            return $mock
        }

        $mockAvailabilityGroupProperty = '' # Set dynamically during runtime
        $mockAvailabilityGroupPropertyValue = '' # Set dynamically during runtime

        $mockUpdateAvailabilityGroup = {
            Param
            (
                [Parameter()]
                [Microsoft.SqlServer.Management.Smo.AvailabilityGroup]
                $AvailabilityGroup
            )

            if ( $mockAvailabilityGroupPropertyValue -ne $AvailabilityGroup.$mockAvailabilityGroupProperty )
            {
                foreach ( $property in ( $AvailabilityGroup | Get-Member -MemberType Property | Select-Object -ExpandProperty Name ) )
                {
                    New-VerboseMessage -Message "$($property): $($AvailabilityGroup.$property) ($($defaultPresentParameters.$property))"
                }

                throw "Update-AvailabilityGroup should be setting the property '$($mockAvailabilityGroupProperty)' to '$($mockAvailabilityGroupPropertyValue)'"
            }
        }

        $mockAvailabilityGroupReplicaProperty = '' # Set dynamically during runtime
        $mockAvailabilityGroupReplicaPropertyValue = '' # Set dynamically during runtime

        $mockUpdateAvailabilityGroupReplica = {
            Param
            (
                [Parameter()]
                [Microsoft.SqlServer.Management.Smo.AvailabilityReplica]
                $AvailabilityGroupReplica
            )

            if ( [string]::IsNullOrEmpty($mockAvailabilityGroupReplicaProperty) -and [string]::IsNullOrEmpty($mockAvailabilityGroupReplicaPropertyValue) )
            {
                return
            }

            if ( $mockAvailabilityGroupReplicaPropertyValue -ne $AvailabilityGroupReplica.$mockAvailabilityGroupReplicaProperty )
            {
                foreach ( $property in ( $AvailabilityGroupReplica | Get-Member -MemberType Property | Select-Object -ExpandProperty Name ) )
                {
                    New-VerboseMessage -Message "$($property): $($AvailabilityGroupReplica.$property) ($($defaultPresentParameters.$property))"
                }

                throw "Update-AvailabilityGroupReplica should be setting the property '$($mockAvailabilityGroupReplicaProperty)' to '$($mockAvailabilityGroupReplicaPropertyValue)'"
            }
        }

        Describe "xSQLServerAlwaysOnAvailabilityGroup\Get-TargetResource" {

            BeforeEach {
                $mockLogins = $mockAllLoginsPresent
            }

            Context 'When the Availability Group is Absent'{

                It 'Should not return an Availability Group when Ensure is set to Present and the version is 12' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable

                    $getParams = @{
                        Name = $defaultAbsentParameters.Name
                        SQLServer = $defaultAbsentParameters.SQLServer
                        SQLInstanceName = $defaultAbsentParameters.SQLInstanceName
                    }

                    # Get the current state
                    $result = Get-TargetResource @getParams

                    $result.Ensure | Should Be 'Absent'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should not return an Availability Group when Ensure is set to Present and the version is 13' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable

                    $getParams = @{
                        Name = $defaultAbsentParameters.Name
                        SQLServer = $defaultAbsentParameters.SQLServer
                        SQLInstanceName = $defaultAbsentParameters.SQLInstanceName
                    }

                    # Get the current state
                    $result = Get-TargetResource @getParams

                    $result.Ensure | Should Be 'Absent'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }
            }

            Context 'When the Availability Group is Present'{

                It 'Should return the correct Availability Group properties when Ensure is set to Present and the SQL version is 12' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable

                    $getParams = @{
                        Name = $defaultPresentParameters.Name
                        SQLServer = $defaultPresentParameters.SQLServer
                        SQLInstanceName = $defaultPresentParameters.SQLInstanceName
                    }

                    # Get the current state
                    $result = Get-TargetResource @getParams

                    $result.Name | Should Be $defaultPresentParameters.Name
                    $result.SQLServer | Should Be $defaultPresentParameters.SQLServer
                    $result.SQLInstanceName | Should Be $defaultPresentParameters.SQLInstanceName
                    $result.Ensure | Should Be 'Present'
                    $result.AutomatedBackupPreference | Should Be 'Secondary'
                    $result.AvailabilityMode | Should Be 'AsynchronousCommit'
                    $result.BackupPriority | Should Be 50
                    $result.ConnectionModeInPrimaryRole | Should Be 'AllowAllConnections'
                    $result.ConnectionModeInSecondaryRole | Should Be 'AllowNoConnections'
                    $result.FailureConditionLevel | Should Be 'OnServerDown'
                    $result.FailoverMode | Should Be 'Manual'
                    $result.HealthCheckTimeout | Should Be 30000
                    $result.BasicAvailabilityGroup | Should BeNullOrEmpty

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should return the correct Availability Group properties when Ensure is set to Absent and the SQL version is 12' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable

                    $getParams = @{
                        Name = $defaultPresentParameters.Name
                        SQLServer = $defaultPresentParameters.SQLServer
                        SQLInstanceName = $defaultPresentParameters.SQLInstanceName
                    }

                    # Get the current state
                    $result = Get-TargetResource @getParams

                    $result.Name | Should Be $defaultPresentParameters.Name
                    $result.SQLServer | Should Be $defaultPresentParameters.SQLServer
                    $result.SQLInstanceName | Should Be $defaultPresentParameters.SQLInstanceName
                    $result.Ensure | Should Be 'Present'
                    $result.AutomatedBackupPreference | Should Be 'Secondary'
                    $result.AvailabilityMode | Should Be 'AsynchronousCommit'
                    $result.BackupPriority | Should Be 50
                    $result.ConnectionModeInPrimaryRole | Should Be 'AllowAllConnections'
                    $result.ConnectionModeInSecondaryRole | Should Be 'AllowNoConnections'
                    $result.FailureConditionLevel | Should Be 'OnServerDown'
                    $result.FailoverMode | Should Be 'Manual'
                    $result.HealthCheckTimeout | Should Be 30000
                    $result.BasicAvailabilityGroup | Should BeNullOrEmpty

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should return the correct Availability Group properties when Ensure is set to Present and the SQL version is 13' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable

                    $getParams = @{
                        Name = $defaultPresentParameters.Name
                        SQLServer = $defaultPresentParameters.SQLServer
                        SQLInstanceName = $defaultPresentParameters.SQLInstanceName
                    }

                    # Get the current state
                    $result = Get-TargetResource @getParams

                    $result.Name | Should Be $defaultPresentParameters.Name
                    $result.SQLServer | Should Be $defaultPresentParameters.SQLServer
                    $result.SQLInstanceName | Should Be $defaultPresentParameters.SQLInstanceName
                    $result.Ensure | Should Be 'Present'
                    $result.AutomatedBackupPreference | Should Be 'Secondary'
                    $result.AvailabilityMode | Should Be 'AsynchronousCommit'
                    $result.BackupPriority | Should Be 50
                    $result.ConnectionModeInPrimaryRole | Should Be 'AllowAllConnections'
                    $result.ConnectionModeInSecondaryRole | Should Be 'AllowNoConnections'
                    $result.FailureConditionLevel | Should Be 'OnServerDown'
                    $result.FailoverMode | Should Be 'Manual'
                    $result.HealthCheckTimeout | Should Be 30000
                    $result.BasicAvailabilityGroup | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should return the correct Availability Group properties when Ensure is set to Absent and the SQL version is 13' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable

                    $getParams = @{
                        Name = $defaultPresentParameters.Name
                        SQLServer = $defaultPresentParameters.SQLServer
                        SQLInstanceName = $defaultPresentParameters.SQLInstanceName
                    }

                    # Get the current state
                    $result = Get-TargetResource @getParams

                    $result.Name | Should Be $defaultPresentParameters.Name
                    $result.SQLServer | Should Be $defaultPresentParameters.SQLServer
                    $result.SQLInstanceName | Should Be $defaultPresentParameters.SQLInstanceName
                    $result.Ensure | Should Be 'Present'
                    $result.AutomatedBackupPreference | Should Be 'Secondary'
                    $result.AvailabilityMode | Should Be 'AsynchronousCommit'
                    $result.BackupPriority | Should Be 50
                    $result.ConnectionModeInPrimaryRole | Should Be 'AllowAllConnections'
                    $result.ConnectionModeInSecondaryRole | Should Be 'AllowNoConnections'
                    $result.FailureConditionLevel | Should Be 'OnServerDown'
                    $result.FailoverMode | Should Be 'Manual'
                    $result.HealthCheckTimeout | Should Be 30000
                    $result.BasicAvailabilityGroup | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }
            }
        }

        Describe "xSQLServerAlwaysOnAvailabilityGroup\Set-TargetResource" {

            BeforeEach {
                $mockLogins = $mockAllLoginsPresent # Need this for legacy purposes
                $mockConnectSqlVersion12ServerObject.Logins = $mockAllLoginsPresent
                $mockConnectSqlVersion13ServerObject.Logins = $mockAllLoginsPresent
            }

            Mock -CommandName Invoke-Query -MockWith {} -Verifiable
            Mock -CommandName Import-SQLPSModule -MockWith {} -Verifiable
            Mock -CommandName New-TerminatingError { $ErrorType } -Verifiable

            Context 'When the Availability Group is Absent' {

                Mock -CommandName Remove-SqlAvailabilityGroup -MockWith {} -Verifiable
                Mock -CommandName Update-AvailabilityGroup -MockWith {} -Verifiable
                Mock -CommandName Update-AvailabilityGroupReplica -MockWith {} -Verifiable

                It 'Should create the Availability Group when Ensure is set to Present and the SQL version is 12' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith $mockNewSqlAvailabilityReplica -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $false } -Verifiable -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }

                    $defaultAbsentParameters.Ensure = 'Present'

                    { Set-TargetResource @defaultAbsentParameters } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should create the Availability Group when Ensure is set to Present and the SQL version is 13' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith $mockNewSqlAvailabilityReplica -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $false } -Verifiable -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }

                    $defaultAbsentParameters.Ensure = 'Present'
                    $defaultAbsentParameters.BasicAvailabilityGroup = $true

                    { Set-TargetResource @defaultAbsentParameters } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error, HadrNotEnabled, when Ensure is set to Present, but Always On is not enabled' {
                    Mock -CommandName Connect-SQL -MockWith {
                        return New-Object PSObject -Property @{
                            IsHadrEnabled = $false
                        }
                    } -Verifiable
                    Mock -CommandName Invoke-Query -MockWith {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith $mockNewSqlAvailabilityReplica -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $false } -Verifiable -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }

                    $defaultAbsentParameters.Ensure = 'Present'

                    { Set-TargetResource @defaultAbsentParameters } | Should Throw 'HadrNotEnabled'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error (ClusterPermissionsMissing) when the logins "NT SERVICE\ClusSvc" or "NT AUTHORITY\SYSTEM" are absent' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith $mockNewSqlAvailabilityReplica -Verifiable

                    $defaultAbsentParameters.Ensure = 'Present'
                    $mockConnectSqlVersion12ServerObject.Logins = $mockAllLoginsAbsent.Clone()

                    { Set-TargetResource @defaultAbsentParameters } | Should Throw 'ClusterPermissionsMissing'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should create the Availability Group when Ensure is set to Present and NT AUTHORITY\SYSTEM has the correct permissions' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith $mockNewSqlAvailabilityReplica -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $false } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }

                    $defaultAbsentParameters.Ensure = 'Present'

                    { Set-TargetResource @defaultAbsentParameters } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error, ClusterPermissionsMissing, when Ensure is set to Present, but the cluster does not have the correct permissions' {
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith $mockNewSqlAvailabilityReplica -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $false } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $false } -Verifiable -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }

                    $defaultAbsentParameters.Ensure = 'Present'

                    { Set-TargetResource @defaultAbsentParameters } | Should Throw 'ClusterPermissionsMissing'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT AUTHORITY\SYSTEM' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error, DatabaseMirroringEndpointNotFound, when Ensure is set to Present, but no DatabaseMirroring endpoints are present' {
                    Mock -CommandName Connect-SQL -MockWith {
                        return New-Object PSObject -Property @{
                            AvailabilityGroups = @()
                            Endpoints = @()
                            IsHadrEnabled = $true
                            Logins = $mockNtServiceClusSvcPresent
                        }
                    } -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith $mockNewSqlAvailabilityReplica -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultAbsentParameters.Ensure = 'Present'

                    { Set-TargetResource @defaultAbsentParameters } | Should Throw 'DatabaseMirroringEndpointNotFound'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error, CreateAvailabilityGroupReplicaFailed, when Ensure is set to Present, but the Availability Group Replica failed to create and the SQL version is 12' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith { throw 'CreateAvailabilityGroupReplicaFailed' } -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultAbsentParameters.Ensure = 'Present'

                    { Set-TargetResource @defaultAbsentParameters } | Should Throw 'CreateAvailabilityGroupReplicaFailed'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error, CreateAvailabilityGroupReplicaFailed, when Ensure is set to Present, but the Availability Group Replica failed to create and the SQL version is 13' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith { throw 'CreateAvailabilityGroupReplicaFailed' } -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultAbsentParameters.Ensure = 'Present'

                    { Set-TargetResource @defaultAbsentParameters } | Should Throw 'CreateAvailabilityGroupReplicaFailed'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error "CreateAvailabilityGroupFailed" when Ensure is set to Present, but the Availability Group failed to create and the SQL version is 12' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith $mockNewSqlAvailabilityReplica -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup -MockWith { throw 'CreateAvailabilityGroupFailed' } -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Mock -CommandName Test-TargetResource -MockWith { $false } -Verifiable

                    $defaultAbsentParameters.Ensure = 'Present'

                    { Set-TargetResource @defaultAbsentParameters } | Should Throw 'CreateAvailabilityGroupFailed'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error "CreateAvailabilityGroupFailed" when Ensure is set to Present, but the Availability Group failed to create and the SQL version is 13' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith $mockNewSqlAvailabilityReplica -Verifiable
                    Mock -CommandName New-SqlAvailabilityGroup -MockWith { throw 'CreateAvailabilityGroupFailed' } -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Mock -CommandName Test-TargetResource -MockWith {$false}

                    $defaultAbsentParameters.Ensure = 'Present'

                    { Set-TargetResource @defaultAbsentParameters } | Should Throw 'CreateAvailabilityGroupFailed'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }
            }

            Context 'When the Availability Group is Present' {
                BeforeEach {
                    Mock -CommandName New-SqlAvailabilityGroup {} -Verifiable
                    Mock -CommandName New-SqlAvailabilityReplica -MockWith $mockNewSqlAvailabilityReplica -Verifiable
                    Mock -CommandName Update-AvailabilityGroup -MockWith $mockUpdateAvailabilityGroup -Verifiable
                    Mock -CommandName Update-AvailabilityGroupReplica -MockWith $mockUpdateAvailabilityGroupReplica -Verifiable
                }

                It 'Should remove the Availability Group when Ensure is set to Absent and the SQL version is 12' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName Remove-SqlAvailabilityGroup -MockWith {} -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith {} -Verifiable

                    $defaultPresentParameters.Ensure = 'Absent'

                    { Set-TargetResource @defaultPresentParameters } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should remove the Availability Group when Ensure is set to Absent and the SQL version is 13' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable
                    Mock -CommandName Remove-SqlAvailabilityGroup -MockWith {} -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith {} -Verifiable

                    $defaultPresentParameters.Ensure = 'Absent'

                    { Set-TargetResource @defaultPresentParameters } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Invoke-Query -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error message, InstanceNotPrimaryReplica, when Ensure is set to Absent and the primary replica is not on the current instance' {

                    Mock -CommandName Connect-SQL -MockWith {
                        return New-Object PSObject -Property @{
                            AvailabilityGroups = @{
                                PresentAG = @{
                                    AutomatedBackupPreference = 'Secondary'
                                    FailureConditionLevel = 'OnServerDown'
                                    HealthCheckTimeout = 30000
                                    Name = 'AvailabilityGroup1'
                                    PrimaryReplicaServerName = 'Server1'
                                    AvailabilityReplicas = @{
                                        Server1 = @{
                                            AvailabilityMode = 'AsynchronousCommit'
                                            BackupPriority = 50
                                            ConnectionModeInPrimaryRole = 'AllowAllConnections'
                                            ConnectionModeInSecondaryRole = 'AllowNoConnections'
                                            EndpointUrl = 'TCP://Server1:5022'
                                            FailoverMode = 'Manual'
                                        }
                                    }
                                }
                            }
                            IsHadrEnabled = $true
                            NetName = 'Server2'
                        }
                    } -Verifiable

                    Mock -CommandName Remove-SqlAvailabilityGroup -MockWith {} -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith {} -Verifiable

                    $defaultPresentParameters.Ensure = 'Absent'

                    { Set-TargetResource @defaultPresentParameters } | Should Throw 'InstanceNotPrimaryReplica'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error message when Ensure is set to Absent but the Availability Group remove fails, and the SQL version is 12' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName Remove-SqlAvailabilityGroup -MockWith { throw 'RemoveAvailabilityGroupFailed' } -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith {} -Verifiable

                    $defaultPresentParameters.Ensure = 'Absent'

                    { Set-TargetResource @defaultPresentParameters } | Should Throw 'RemoveAvailabilityGroupFailed'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error message when Ensure is set to Absent but the Availability Group remove fails, and the SQL version is 13' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable
                    Mock -CommandName Remove-SqlAvailabilityGroup -MockWith { throw 'RemoveAvailabilityGroupFailed' } -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith {} -Verifiable

                    $defaultPresentParameters.Ensure = 'Absent'

                    { Set-TargetResource @defaultPresentParameters } | Should Throw 'RemoveAvailabilityGroupFailed'

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly
                }

                It 'Should connect to the instance hosting the primary replica when the LocalReplicaRole is not Primary' {

                    Mock -CommandName Connect-SQL -MockWith {
                        $mock = New-Object PSObject -Property @{
                            AvailabilityGroups = @{
                                PresentAG = @{
                                    AutomatedBackupPreference = 'Secondary'
                                    FailureConditionLevel = 'OnServerDown'
                                    HealthCheckTimeout = 30000
                                    Name = 'AvailabilityGroup1'
                                    PrimaryReplicaServerName = 'Server2'
                                    LocalReplicaRole = 'Secondary'
                                    AvailabilityReplicas = @{
                                        Server1 = @{
                                            AvailabilityMode = 'AsynchronousCommit'
                                            BackupPriority = 50
                                            ConnectionModeInPrimaryRole = 'AllowAllConnections'
                                            ConnectionModeInSecondaryRole = 'AllowNoConnections'
                                            EndpointUrl = 'TCP://Server1:5022'
                                            FailoverMode = 'Manual'
                                        }
                                    }
                                }
                            }
                            Databases = @{
                                'master' = @{
                                    Name = 'master'
                                }
                            }
                            Endpoints = @(
                                New-Object PSObject -Property @{
                                    EndpointType = 'DatabaseMirroring'
                                    Protocol = @{
                                        TCP = @{
                                            ListenerPort = 5022
                                        }
                                    }
                                }
                            )
                            IsHadrEnabled = $true
                            Logins = $mockLogins
                            Name = 'Server1'
                            NetName = 'Server1'
                            Roles = @{}
                            Version = @{
                                Major = 12
                            }
                        }

                        # Add the ExecuteWithResults method
                        $mock.Databases['master'] | Add-Member -MemberType ScriptMethod -Name ExecuteWithResults -Value {
                            return New-Object PSObject -Property @{
                                Tables = @{
                                    Rows = @{
                                        permission_name = @(
                                            'testing'
                                        )
                                    }
                                }
                            }
                        }

                        # Type the mock as a server object
                        $mock.PSObject.TypeNames.Insert(0,'Microsoft.SqlServer.Management.Smo.Server')

                        return $mock
                    } -Verifiable -ParameterFilter { $SQLServer -eq 'Server1' }

                    Mock -CommandName Connect-SQL -MockWith {
                        $mock = New-Object PSObject -Property @{
                            AvailabilityGroups = @{
                                PresentAG = @{
                                    AutomatedBackupPreference = 'Secondary'
                                    FailureConditionLevel = 'OnServerDown'
                                    HealthCheckTimeout = 30000
                                    Name = 'AvailabilityGroup1'
                                    PrimaryReplicaServerName = 'Server2'
                                    LocalReplicaRole = 'Primary'
                                    AvailabilityReplicas = @{
                                        Server1 = @{
                                            AvailabilityMode = 'AsynchronousCommit'
                                            BackupPriority = 50
                                            ConnectionModeInPrimaryRole = 'AllowAllConnections'
                                            ConnectionModeInSecondaryRole = 'AllowNoConnections'
                                            EndpointUrl = 'TCP://Server2:5022'
                                            FailoverMode = 'Manual'
                                        }
                                    }
                                }
                            }
                            Databases = @{
                                'master' = @{
                                    Name = 'master'
                                }
                            }
                            Endpoints = @(
                                New-Object PSObject -Property @{
                                    EndpointType = 'DatabaseMirroring'
                                    Protocol = @{
                                        TCP = @{
                                            ListenerPort = 5022
                                        }
                                    }
                                }
                            )
                            IsHadrEnabled = $true
                            Logins = $mockLogins
                            Name = 'Server1'
                            NetName = 'Server1'
                            Roles = @{}
                            Version = @{
                                Major = 12
                            }
                        }

                        # Add the ExecuteWithResults method
                        $mock.Databases['master'] | Add-Member -MemberType ScriptMethod -Name ExecuteWithResults -Value {
                            return New-Object PSObject -Property @{
                                Tables = @{
                                    Rows = @{
                                        permission_name = @(
                                            'testing'
                                        )
                                    }
                                }
                            }
                        }

                        # Type the mock as a server object
                        $mock.PSObject.TypeNames.Insert(0,'Microsoft.SqlServer.Management.Smo.Server')

                        return $mock
                    } -Verifiable -ParameterFilter { $SQLServer -eq 'Server2' }

                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $mockAvailabilityGroupReplicaProperty = ''
                    $mockAvailabilityGroupReplicaPropertyValue = ''

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly -ParameterFilter { $SQLServer -eq 'Server2' }
                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 0 -Exactly -ParameterFilter { $Query -match 'NT SERVICE\\ClusSvc' }
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 1 -Exactly
                }

                It 'Should set the AutomatedBackupPreference to the desired state' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable -ParameterFilter { $SQLServer -eq 'Server1' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.AutomatedBackupPreference = 'Primary'
                    $mockAvailabilityGroupProperty = 'AutomatedBackupPreference'
                    $mockAvailabilityGroupPropertyValue = 'Primary'

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].AutomatedBackupPreference = $defaultPresentParameters.AutomatedBackupPreference
                }

                It 'Should set the AvailabilityMode to the desired state' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.AvailabilityMode = 'SynchronousCommit'
                    $mockAvailabilityGroupReplicaProperty = 'AvailabilityMode'
                    $mockAvailabilityGroupReplicaPropertyValue = 'SynchronousCommit'

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 1 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].AvailabilityReplicas['Server1'].AvailabilityMode = $defaultPresentParameters.AvailabilityMode
                }

                It 'Should set the BackupPriority to the desired state' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.BackupPriority = 42
                    $mockAvailabilityGroupReplicaProperty = 'BackupPriority'
                    $mockAvailabilityGroupReplicaPropertyValue = 42

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 1 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].AvailabilityReplicas['Server1'].BackupPriority = $defaultPresentParameters.BackupPriority
                }

                It 'Should set the BasicAvailabilityGroup to the desired state' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable -ParameterFilter { $SQLServer -eq 'Server1' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.BasicAvailabilityGroup = $true
                    $mockAvailabilityGroupProperty = 'BasicAvailabilityGroup'
                    $mockAvailabilityGroupPropertyValue = $true

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly

                    $mockConnectSqlVersion13ServerObject.AvailabilityGroups['PresentAG'].BasicAvailabilityGroup = $defaultPresentParameters.BasicAvailabilityGroup
                }

                It 'Should set the ConnectionModeInPrimaryRole to the desired state' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.ConnectionModeInPrimaryRole = 'AllowReadWriteConnections'
                    $mockAvailabilityGroupReplicaProperty = 'ConnectionModeInPrimaryRole'
                    $mockAvailabilityGroupReplicaPropertyValue = 'AllowReadWriteConnections'

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 1 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].AvailabilityReplicas['Server1'].ConnectionModeInPrimaryRole = $defaultPresentParameters.ConnectionModeInPrimaryRole
                    $mockConnectSqlVersion13ServerObject.AvailabilityGroups['PresentAG'].AvailabilityReplicas['Server1'].ConnectionModeInPrimaryRole = $defaultPresentParameters.ConnectionModeInPrimaryRole
                }

                It 'Should set the ConnectionModeInSecondaryRole to the desired state' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable -ParameterFilter { $SQLServer -eq 'Server1' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.ConnectionModeInSecondaryRole = 'AllowReadIntentConnectionsOnly'
                    $mockAvailabilityGroupReplicaProperty = 'ConnectionModeInSecondaryRole'
                    $mockAvailabilityGroupReplicaPropertyValue = 'AllowReadIntentConnectionsOnly'

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 1 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].AvailabilityReplicas['Server1'].ConnectionModeInSecondaryRole = $defaultPresentParameters.ConnectionModeInSecondaryRole
                }

                It 'Should set the EndpointUrl to the desired state when the endpoint port is changed' {

                    Mock -CommandName Connect-SQL -MockWith {
                        $mock = New-Object PSObject -Property @{
                            AvailabilityGroups = @{
                                PresentAG = @{
                                    AutomatedBackupPreference = 'Secondary'
                                    FailureConditionLevel = 'OnServerDown'
                                    HealthCheckTimeout = 30000
                                    Name = 'AvailabilityGroup1'
                                    PrimaryReplicaServerName = 'Server1'
                                    LocalReplicaRole = 'Primary'
                                    AvailabilityReplicas = @{
                                        Server1 = @{
                                            AvailabilityMode = 'AsynchronousCommit'
                                            BackupPriority = 50
                                            ConnectionModeInPrimaryRole = 'AllowAllConnections'
                                            ConnectionModeInSecondaryRole = 'AllowNoConnections'
                                            EndpointUrl = 'TCP://Server1:5021'
                                            FailoverMode = 'Manual'
                                        }
                                    }
                                }
                            }
                            Databases = @{
                                'master' = @{
                                    Name = 'master'
                                }
                            }
                            Endpoints = @(
                                New-Object PSObject -Property @{
                                    EndpointType = 'DatabaseMirroring'
                                    Protocol = @{
                                        TCP = @{
                                            ListenerPort = 5022
                                        }
                                    }
                                }
                            )
                            IsHadrEnabled = $true
                            Logins = $mockLogins
                            Name = 'Server1'
                            NetName = 'Server1'
                            Roles = @{}
                            Version = @{
                                Major = 12
                            }
                        }

                        # Add the ExecuteWithResults method
                        $mock.Databases['master'] | Add-Member -MemberType ScriptMethod -Name ExecuteWithResults -Value {
                            return New-Object PSObject -Property @{
                                Tables = @{
                                    Rows = @{
                                        permission_name = @(
                                            'testing'
                                        )
                                    }
                                }
                            }
                        }

                        # Type the mock as a server object
                        $mock.PSObject.TypeNames.Insert(0,'Microsoft.SqlServer.Management.Smo.Server')

                        return $mock
                    } -Verifiable -ParameterFilter { $SQLServer -eq 'Server1' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $mockAvailabilityGroupReplicaProperty = 'EndpointUrl'
                    $mockAvailabilityGroupReplicaPropertyValue = 'TCP://Server1:5022'

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 1 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].AvailabilityReplicas['Server1'].EndpointUrl = $mockAvailabilityReplica.EndpointUrl
                }

                It 'Should set the EndpointUrl to the desired state when the EndpointHostName is specified' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable -ParameterFilter { $SQLServer -eq 'Server1' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.EndpointHostName = 'TestServer.Contoso.com'
                    $mockAvailabilityGroupReplicaProperty = 'EndpointUrl'
                    $mockAvailabilityGroupReplicaPropertyValue = 'TCP://TestServer.Contoso.com:5022'

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 1 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].AvailabilityReplicas['Server1'].EndpointUrl = $mockAvailabilityReplica.EndpointUrl
                }

                It 'Should set the EndpointUrl to the desired state when the EndpointHostName is not specified' {

                    Mock -CommandName Connect-SQL -MockWith {
                        $mock = New-Object PSObject -Property @{
                            AvailabilityGroups = @{
                                PresentAG = @{
                                    AutomatedBackupPreference = 'Secondary'
                                    FailureConditionLevel = 'OnServerDown'
                                    HealthCheckTimeout = 30000
                                    Name = 'AvailabilityGroup1'
                                    PrimaryReplicaServerName = 'Server1'
                                    LocalReplicaRole = 'Primary'
                                    AvailabilityReplicas = @{
                                        Server1 = @{
                                            AvailabilityMode = 'AsynchronousCommit'
                                            BackupPriority = 50
                                            ConnectionModeInPrimaryRole = 'AllowAllConnections'
                                            ConnectionModeInSecondaryRole = 'AllowNoConnections'
                                            EndpointUrl = 'TCP://Server1.contoso.com:5022'
                                            FailoverMode = 'Manual'
                                        }
                                    }
                                }
                            }
                            Databases = @{
                                'master' = @{
                                    Name = 'master'
                                }
                            }
                            Endpoints = @(
                                New-Object PSObject -Property @{
                                    EndpointType = 'DatabaseMirroring'
                                    Protocol = @{
                                        TCP = @{
                                            ListenerPort = 5022
                                        }
                                    }
                                }
                            )
                            IsHadrEnabled = $true
                            Logins = $mockLogins
                            Name = 'Server1'
                            NetName = 'Server1'
                            Roles = @{}
                            Version = @{
                                Major = 12
                            }
                        }

                        # Add the ExecuteWithResults method
                        $mock.Databases['master'] | Add-Member -MemberType ScriptMethod -Name ExecuteWithResults -Value {
                            return New-Object PSObject -Property @{
                                Tables = @{
                                    Rows = @{
                                        permission_name = @(
                                            'testing'
                                        )
                                    }
                                }
                            }
                        }

                        # Type the mock as a server object
                        $mock.PSObject.TypeNames.Insert(0,'Microsoft.SqlServer.Management.Smo.Server')

                        return $mock
                    } -Verifiable -ParameterFilter { $SQLServer -eq 'Server1' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.Remove('EndpointHostName')
                    $mockAvailabilityGroupReplicaProperty = 'EndpointUrl'
                    $mockAvailabilityGroupReplicaPropertyValue = 'TCP://Server1:5022'

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 1 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].AvailabilityReplicas['Server1'].EndpointUrl = $mockAvailabilityReplica.EndpointUrl
                }

                It 'Should set the EndpointUrl to the desired state when the endpoint protocol is changed' {

                    Mock -CommandName Connect-SQL -MockWith {
                        $mock = New-Object PSObject -Property @{
                            AvailabilityGroups = @{
                                PresentAG = @{
                                    AutomatedBackupPreference = 'Secondary'
                                    FailureConditionLevel = 'OnServerDown'
                                    HealthCheckTimeout = 30000
                                    Name = 'AvailabilityGroup1'
                                    PrimaryReplicaServerName = 'Server1'
                                    LocalReplicaRole = 'Primary'
                                    AvailabilityReplicas = @{
                                        Server1 = @{
                                            AvailabilityMode = 'AsynchronousCommit'
                                            BackupPriority = 50
                                            ConnectionModeInPrimaryRole = 'AllowAllConnections'
                                            ConnectionModeInSecondaryRole = 'AllowNoConnections'
                                            EndpointUrl = 'HTTP://Server1:5022'
                                            FailoverMode = 'Manual'
                                        }
                                    }
                                }
                            }
                            Databases = @{
                                'master' = @{
                                    Name = 'master'
                                }
                            }
                            Endpoints = @(
                                New-Object PSObject -Property @{
                                    EndpointType = 'DatabaseMirroring'
                                    Protocol = @{
                                        TCP = @{
                                            ListenerPort = 5022
                                        }
                                    }
                                }
                            )
                            IsHadrEnabled = $true
                            Logins = $mockLogins
                            Name = 'Server1'
                            NetName = 'Server1'
                            Roles = @{}
                            Version = @{
                                Major = 12
                            }
                        }

                        # Add the ExecuteWithResults method
                        $mock.Databases['master'] | Add-Member -MemberType ScriptMethod -Name ExecuteWithResults -Value {
                            return New-Object PSObject -Property @{
                                Tables = @{
                                    Rows = @{
                                        permission_name = @(
                                            'testing'
                                        )
                                    }
                                }
                            }
                        }

                        # Type the mock as a server object
                        $mock.PSObject.TypeNames.Insert(0,'Microsoft.SqlServer.Management.Smo.Server')

                        return $mock
                    } -Verifiable -ParameterFilter { $SQLServer -eq 'Server1' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $mockAvailabilityGroupReplicaProperty = 'EndpointUrl'
                    $mockAvailabilityGroupReplicaPropertyValue = 'TCP://Server1:5022'

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 1 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].AvailabilityReplicas['Server1'].EndpointUrl = $mockAvailabilityReplica.EndpointUrl
                }

                It 'Should set the FailureConditionLevel to the desired state' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable -ParameterFilter { $SQLServer -eq 'Server1' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.FailureConditionLevel = 'OnAnyQualifiedFailureCondition'
                    $mockAvailabilityGroupProperty = 'FailureConditionLevel'
                    $mockAvailabilityGroupPropertyValue = 'OnAnyQualifiedFailureCondition'

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].FailureConditionLevel = $defaultPresentParameters.FailureConditionLevel
                }

                It 'Should set the FailoverMode to the desired state' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable -ParameterFilter { $SQLServer -eq 'Server1' }
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.FailoverMode = 'Automatic'
                    $mockAvailabilityGroupReplicaProperty = 'FailoverMode'
                    $mockAvailabilityGroupReplicaPropertyValue = 'Automatic'

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 1 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].AvailabilityReplicas['Server1'].FailoverMode = $defaultPresentParameters.FailoverMode
                }

                It 'Should set the HealthCheckTimeout to the desired state' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable
                    Mock -CommandName Test-LoginEffectivePermissions -MockWith { $true } -Verifiable -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }

                    $defaultPresentParametersIncorrectProperties = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectProperties.Ensure = 'Present'
                    $defaultPresentParametersIncorrectProperties.HealthCheckTimeout = 42
                    $mockAvailabilityGroupProperty = 'HealthCheckTimeout'
                    $mockAvailabilityGroupPropertyValue = 42

                    { Set-TargetResource @defaultPresentParametersIncorrectProperties } | Should Not Throw

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Import-SQLPSModule -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityReplica -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Remove-SqlAvailabilityGroup -Scope It -Times 0 -Exactly
                    Assert-MockCalled -CommandName Test-LoginEffectivePermissions -Scope It -Times 1 -Exactly -ParameterFilter { $LoginName -eq 'NT SERVICE\ClusSvc' }
                    Assert-MockCalled -CommandName Update-AvailabilityGroup -Scope It -Times 1 -Exactly
                    Assert-MockCalled -CommandName Update-AvailabilityGroupReplica -Scope It -Times 0 -Exactly

                    $mockConnectSqlVersion12ServerObject.AvailabilityGroups['PresentAG'].HealthCheckTimeout = $defaultPresentParameters.HealthCheckTimeout
                }
            }
        }

        Describe "xSQLServerAlwaysOnAvailabilityGroup\Test-TargetResource" {

            BeforeEach {
                $mockLogins = $mockAllLoginsPresent
            }

            Context 'When the Availability Group is Absent' {

                It 'Should be $false when the desired state is Present and the SQL version is 12' {

                    $defaultAbsentParameters.Ensure = 'Present'
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable

                    Test-TargetResource @defaultAbsentParameters | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $true when the desired state is Absent and the SQL version is 12' {

                    $defaultAbsentParameters.Ensure = 'Absent'
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable

                    Test-TargetResource @defaultAbsentParameters | Should Be $true

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $false when the desired state is Present and the SQL version is 13' {

                    $defaultAbsentParameters.Ensure = 'Present'
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable

                    Test-TargetResource @defaultAbsentParameters | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $true when the desired state is Absent and the SQL version is 13' {

                    $defaultAbsentParameters.Ensure = 'Absent'
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable

                    Test-TargetResource @defaultAbsentParameters | Should Be $true

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }
            }

            Context 'When the Availability Group is Present' {

                It 'Should be $false when the desired state is Absent and the SQL version is 12' {

                    $defaultPresentParameters.Ensure = 'Absent'
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable

                    Test-TargetResource @defaultPresentParameters | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $true when the desired state is Present and the SQL version is 12' {

                    $defaultPresentParameters.Ensure = 'Present'
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable

                    Test-TargetResource @defaultPresentParameters | Should Be $true

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $false when the desired state is Present, there is a parameter not correctly set, and the SQL version is 12' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable

                    $defaultPresentParametersIncorrectParameter = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectParameter.Ensure = 'Present'
                    $defaultPresentParametersIncorrectParameter.AvailabilityMode = 'SynchronousCommit'

                    Test-TargetResource @defaultPresentParametersIncorrectParameter | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $false when the desired state is Absent and the SQL version is 13' {

                    $defaultPresentParameters.Ensure = 'Absent'
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable

                    Test-TargetResource @defaultPresentParameters | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $true when the desired state is Present and the SQL version is 13' {

                    $defaultPresentParameters.Ensure = 'Present'
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable

                    Test-TargetResource @defaultPresentParameters | Should Be $true

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $false when the desired state is Present, there is a parameter not correctly set, and the SQL version is 13' {

                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion13 -Verifiable

                    $defaultPresentParametersIncorrectParameter = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectParameter.Ensure = 'Present'
                    $defaultPresentParametersIncorrectParameter.AvailabilityMode = 'SynchronousCommit'
                    $defaultPresentParametersIncorrectParameter.BasicAvailabilityGroup = $true

                    Test-TargetResource @defaultPresentParametersIncorrectParameter | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $true when the desired state is Present and the Endpoint Host Name is not specified' {
                    $defaultPresentParametersEndpointHostNameNotSpecified = $defaultPresentParameters.Clone()
                    $defaultPresentParametersEndpointHostNameNotSpecified.Ensure = 'Present'
                    $defaultPresentParametersEndpointHostNameNotSpecified.Remove('EndpointHostName')
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable

                    Test-TargetResource @defaultPresentParametersEndpointHostNameNotSpecified | Should Be $true

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $false when the desired state is Present and the Endpoint Hostname is incorrectly configured' {
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12 -Verifiable

                    $defaultPresentParametersIncorrectParameter = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectParameter.Ensure = 'Present'
                    $defaultPresentParametersIncorrectParameter.EndpointHostName = 'server1.contoso.com'

                    Test-TargetResource @defaultPresentParametersIncorrectParameter | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $false when the desired state is Present and the Endpoint Protocol is incorrectly configured' {
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12IncorrectEndpointProtocol -Verifiable

                    $defaultPresentParametersIncorrectParameter = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectParameter.Ensure = 'Present'

                    Test-TargetResource @defaultPresentParametersIncorrectParameter | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }

                It 'Should be $false when the desired state is Present and the Endpoint Port is incorrectly configured' {
                    Mock -CommandName Connect-SQL -MockWith $mockConnectSqlVersion12IncorrectEndpointPort -Verifiable

                    $defaultPresentParametersIncorrectParameter = $defaultPresentParameters.Clone()
                    $defaultPresentParametersIncorrectParameter.Ensure = 'Present'

                    Test-TargetResource @defaultPresentParametersIncorrectParameter | Should Be $false

                    Assert-MockCalled -CommandName Connect-SQL -Scope It -Times 1 -Exactly
                }
            }
        }

        Describe "xSQLServerAlwaysOnAvailabilityGroup\Update-AvailabilityGroup" {
            Mock -CommandName New-TerminatingError -MockWith { $ErrorType }

            Context 'When the Availability Group is altered' {
                It 'Should silently alter the Availability Group' {
                    $ag = New-Object Microsoft.SqlServer.Management.Smo.AvailabilityGroup

                    { Update-AvailabilityGroup -AvailabilityGroup $ag } | Should Not Throw

                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 0 -Exactly
                }

                It 'Should throw the correct error, AlterAvailabilityGroupFailed, when altering the Availaiblity Group fails' {
                    $ag = New-Object Microsoft.SqlServer.Management.Smo.AvailabilityGroup
                    $ag.Name = 'AlterFailed'

                    { Update-AvailabilityGroup -AvailabilityGroup $ag } | Should Throw 'AlterAvailabilityGroupFailed'

                    Assert-MockCalled -CommandName New-TerminatingError -Scope It -Times 1 -Exactly
                }
            }
        }
    }
}
finally
{
    Restore-TestEnvironment -TestEnvironment $TestEnvironment
}