tests/Publish-DosDacPac.tests.ps1

. "$PSScriptRoot\Utilities\TestUtilities.ps1"
$testConfiguration = Initialize-Test

Describe "Validate Publish-DosDacPac functionality"{

    Context "Mock function used by publish-dosdacpac" {

        #Todo - implement. Trying to close pull request, will implement this with more testing.
    }
}

Describe "Publish-DosDacpac with valid and invalid parameter scenarios" -Tag "Integration"{

    BeforeAll {
        # Arrange
        [string] $coreDacPacFilePath = "$PSScriptRoot\SampleFiles\Core.dacpac"
        [string] $publishOptionsFilePath = "$PSScriptRoot\SampleFiles\CoreDeploymentIncludingTables.publish.xml"
    }

    Context "Core DacPac scenario with valid options" {
        # Act
        [string] $targetDb = "a" + $(Get-Random)

        Publish-DosDacPac -DacPacFilePath $coreDacPacFilePath -TargetSqlInstance $testConfiguration.SqlServerMachineName -TargetDb $targetDb -PublishOptionsFilePath $publishOptionsFilePath
        $dacPacDeployDb = Find-DbaDatabase -SqlServer $testConfiguration.SqlServerMachineName -Pattern $targetDb

        # Assert
        It "Database exists" {
            $dacPacDeployDb | Should -Not -Be $null
        }
        It "Database has correct name" {
            $dacPacDeployDb.Name | Should -Be $targetDb
        }

        # Cleanup
        Remove-DbaDatabase -SqlInstance $testConfiguration.SqlServerMachineName -Databases $targetDb -Confirm:$false
    }

    Context "DacPacFilePath not found" {
        # Act
        [string] $targetDb = "a" + $(Get-Random)
        [string] $missingDacPacFilePath = "InvalidFilePath.dacpac"

        try {
            Publish-DosDacPac -DacPacFilePath $missingDacPacFilePath -TargetSqlInstance $testConfiguration.SqlServerMachineName -TargetDb $targetDb -PublishOptionsFilePath $publishOptionsFilePath -ErrorAction Stop
        }
        catch {
            $errorObject = $_.Exception
        }
        
        $dacPacDeployDb = Find-DbaDatabase -SqlServer $testConfiguration.SqlServerMachineName -Pattern $targetDb

        It "Database does not exist" {
            $dacPacDeployDb | Should -Be $null
        }
        It "Exception should be correct" {
            $errorObject.Message | Should -BeLike "* $missingDacPacFilePath not found!"
        }
        It "Exception is of type Exception" {
            $exceptionType = $errorObject.GetType()
            $exceptionType.Name | Should -Be "WriteErrorException"
        }

        # Cleanup
        if ($dacPacDeployDb -ne $null) {
            Remove-DbaDatabase -SqlInstance $testConfiguration.SqlServerMachineName -Databases $targetDb -Confirm:$false
        }
    }

    Context "Deploy incorrect DacPac file" {
        # Act
        [string] $targetDb = "a" + $(Get-Random)
        [string] $invalidDacPacFilePath = "$PSScriptRoot\SampleFiles\InvalidDacDeployOptions.xml"

        try {
            Publish-DosDacPac -DacPacFilePath $invalidDacPacFilePath -TargetSqlInstance $testConfiguration.SqlServerMachineName -TargetDb $targetDb -PublishOptionsFilePath $publishOptionsFilePath -ErrorAction Stop
        }
        catch {
            $errorObject = $_.Exception
        }
        
        $dacPacDeployDb = Find-DbaDatabase -SqlServer $testConfiguration.SqlServerMachineName -Pattern $targetDb

        It "Database does not exist" {
            $dacPacDeployDb | Should -Be $null
        }
        It "Exception should be correct" {
            $errorObject.Message | Should -BeLike "*Could not load package from '$invalidDacPacFilePath'*"
        }
        It "Exception is of type Exception" {
            $exceptionType = $errorObject.GetType()
            $exceptionType.Name | Should -Be "WriteErrorException"
        }

        # Cleanup
        if ($dacPacDeployDb -ne $null) {
            Remove-DbaDatabase -SqlInstance $testConfiguration.SqlServerMachineName -Databases $targetDb -Confirm:$false
        }
    }

    Context "Invalid TargetSqlInstance" {
        # Act
        [string] $targetDb = "a" + $(Get-Random)
        [string] $invalidSqlInstance = "invalidSqlInstance"

        try {
            Publish-DosDacPac -DacPacFilePath $coreDacPacFilePath -TargetSqlInstance $invalidSqlInstance -TargetDb $targetDb -PublishOptionsFilePath $publishOptionsFilePath -ErrorAction Stop
        }
        catch {
            $errorObject = $_.Exception
        }

        $dacPacDeployDb = Find-DbaDatabase -SqlServer $testConfiguration.SqlServerMachineName -Pattern $targetDb

        It "Database does not exist" {
            $dacPacDeployDb | Should -Be $null
        }
        It "Exception should be correct" {
            $errorObject.Message | Should -BeLike "* Can't connect to ${invalidSqlInstance}: *"
        }
        It "Exception is of type Exception" {
            $exceptionType = $errorObject.GetType()
            $exceptionType.Name | Should -Be "WriteErrorException"
        }

        # Cleanup
        if ($dacPacDeployDb -ne $null) {
            Remove-DbaDatabase -SqlInstance $testConfiguration.SqlServerMachineName -Databases $targetDb -Confirm:$false
        }
    }

    Context "Invalid TargetDb" {
        # Act
        [string] $invalidTargetDb = "'invalidTargetDb"

        try {
            Publish-DosDacPac -DacPacFilePath $coreDacPacFilePath -TargetSqlInstance $testConfiguration.SqlServerMachineName -TargetDb $invalidTargetDb -PublishOptionsFilePath $publishOptionsFilePath -ErrorAction Stop
        }
        catch {
            $errorObject = $_.Exception
        }

        $dacPacDeployDb = Find-DbaDatabase -SqlServer $testConfiguration.SqlServerMachineName -Pattern $invalidTargetDb

        It "Database does not exist" {
            $dacPacDeployDb | Should -Be $null
        }
        It "Exception should be correct" {
            $errorObject.Message | Should -BeLike "* initialization string does not conform *"
        }
        It "Exception is of type Exception" {
            $exceptionType = $errorObject.GetType()
            $exceptionType.Name | Should -Be "WriteErrorException"
        }

        # Cleanup
        if ($dacPacDeployDb -ne $null) {
            Remove-DbaDatabase -SqlInstance $testConfiguration.SqlServerMachineName -Databases $targetDb -Confirm:$false
        }
    }

    Context "Invalid PublishOptionsFilePath" {
        # Act
        [string] $targetDb = "a" + $(Get-Random)
        $publishOptionsFilePath = "$PSScriptRoot\SampleFiles\InvalidDacDeployOptions.xml"

        try {
            Publish-DosDacPac -DacPacFilePath $coreDacPacFilePath -TargetSqlInstance $testConfiguration.SqlServerMachineName -TargetDb $targetDb -PublishOptionsFilePath $publishOptionsFilePath -ErrorAction Stop
        }
        catch {
            $errorObject = $_.Exception
        }

        $dacPacDeployDb = Find-DbaDatabase -SqlServer $testConfiguration.SqlServerMachineName -Pattern $targetDb

        It "Database does not exist" {
            $dacPacDeployDb | Should -Be $null
        }
        It "Exception should be correct" {
            $errorObject.Message | Should -BeLike '* "Could not read profile properties: *'
        }
        It "Exception is of type Exception" {
            $exceptionType = $errorObject.GetType()
            $exceptionType.Name | Should -Be "WriteErrorException"
        }

        # Cleanup
        if ($dacPacDeployDb -ne $null) {
            Remove-DbaDatabase -SqlInstance $testConfiguration.SqlServerMachineName -Databases $targetDb -Confirm:$false
        }
    }

    Context "PublishOptionsFilePath not found" {
        # Act
        [string] $targetDb = "a" + $(Get-Random)
        $publishOptionsFilePath = "$PSScriptRoot\SampleFiles\filenotfound.xml"

        try {
            Publish-DosDacPac -DacPacFilePath $coreDacPacFilePath -TargetSqlInstance $testConfiguration.SqlServerMachineName -TargetDb $targetDb -PublishOptionsFilePath $publishOptionsFilePath -ErrorAction Stop
        }
        catch {
            $errorObject = $_.Exception
        }

        $dacPacDeployDb = Find-DbaDatabase -SqlServer $testConfiguration.SqlServerMachineName -Pattern $targetDb

        It "Database does not exist" {
            $dacPacDeployDb | Should -Be $null
        }
        It "Exception should be correct" {
            $errorObject.Message | Should -BeLike "* $publishOptionsFilePath not found!"
        }
        It "Exception is of type Exception" {
            $exceptionType = $errorObject.GetType()
            $exceptionType.Name | Should -Be "WriteErrorException"
        }

        # Cleanup
        if ($dacPacDeployDb -ne $null) {
            Remove-DbaDatabase -SqlInstance $testConfiguration.SqlServerMachineName -Databases $targetDb -Confirm:$false
        }
    }
    
    AfterAll {
        
    }
}