Tests/FirebirdDatabase.Tests.ps1

Import-Module "$PSScriptRoot/../PSFirebird.psd1" -Force
. "$PSScriptRoot/TestHelper.ps1"

BeforeAll {
    # Helper function to check if a database is locked
    function Get-FirebirdDatabaseLocked(
        [FirebirdDatabase]$Database,
        [FirebirdEnvironment]$Environment
    ) {
        $info = Read-FirebirdDatabase -Database $Database -Environment $Environment
        return $info['MON$BACKUP_STATE'] -ne 0
    }
}

Describe 'FirebirdDatabase' -Tag 'Integration' {
    BeforeAll {
        # Create a temporary folder for the test files
        $script:RootFolder = New-Item -ItemType Directory -Path ([System.IO.Path]::GetTempPath()) -Name (New-Guid)

        $script:TestEnvironment = New-FirebirdEnvironment -Version $FirebirdVersion
        $script:TestDatabasePath = "$RootFolder/$FirebirdVersion-tests.fdb"

        # Set up the environment variables for Firebird
        $env:ISC_USER = 'SYSDBA'
        $env:ISC_PASSWORD = 'masterkey'
    }

    AfterAll {
        # Remove the test folder
        Remove-Item -Path $RootFolder -Recurse -Force -ErrorAction SilentlyContinue
    }

    BeforeEach {
        # Ensure the test database does not exist before each test
        if (Test-Path $TestDatabasePath) {
            Remove-Item -Path $TestDatabasePath -Recurse -Force -ErrorAction SilentlyContinue
        }
    }

    It 'Create database with default parameters' {
        $TestDatabasePath | Should -Not -Exist
        $testDatabase = New-FirebirdDatabase -Database $TestDatabasePath -Environment $TestEnvironment
        $testDatabase.Path | Should -Be $TestDatabasePath
        $testDatabase.Path | Should -Exist
    }

    It 'Create database with context environment' {
        Use-FirebirdEnvironment -Environment $TestEnvironment {
            $TestDatabasePath | Should -Not -Exist
            $testDatabase = New-FirebirdDatabase -Database $TestDatabasePath
            $testDatabase.Path | Should -Be $TestDatabasePath
            $testDatabase.Path | Should -Exist
        }
    }

    It 'Read database information' {
        $TestDatabasePath | Should -Not -Exist
        $testDatabase = New-FirebirdDatabase -Database $TestDatabasePath -PageSize 4096 -Environment $TestEnvironment
        $TestDatabasePath | Should -Exist

        $info = Read-FirebirdDatabase -Database $testDatabase -Environment $TestEnvironment
        $info.Environment | Should -BeOfType FirebirdEnvironment
        $info.Database | Should -Be $TestDatabase
        $info['MON$PAGE_SIZE'] | Should -Be 4096
    }

    It 'Lock database' {
        $TestDatabasePath | Should -Not -Exist
        $testDatabase = New-FirebirdDatabase -Database $TestDatabasePath -Environment $TestEnvironment
        $TestDatabasePath | Should -Exist

        Get-FirebirdDatabaseLocked -Database $TestDatabase -Environment $TestEnvironment | Should -BeFalse
        Lock-FirebirdDatabase -Database $TestDatabase -Environment $TestEnvironment
        Get-FirebirdDatabaseLocked -Database $TestDatabase -Environment $TestEnvironment | Should -BeTrue

        { Lock-FirebirdDatabase -Database $TestDatabase -Environment $TestEnvironment } | Should -Throw 'Database is already locked for backup.'
    }


    It 'Unlock database' {
        $TestDatabasePath | Should -Not -Exist
        $testDatabase = New-FirebirdDatabase -Database $TestDatabasePath -Environment $TestEnvironment
        $TestDatabasePath | Should -Exist

        
        Lock-FirebirdDatabase -Database $TestDatabase -Environment $TestEnvironment
        Get-FirebirdDatabaseLocked -Database $TestDatabase -Environment $TestEnvironment | Should -BeTrue

        Unlock-FirebirdDatabase -Database $TestDatabase -Environment $TestEnvironment
        Get-FirebirdDatabaseLocked -Database $TestDatabase -Environment $TestEnvironment | Should -BeFalse

        { Unlock-FirebirdDatabase -Database $TestDatabase -Environment $TestEnvironment } | Should -Throw 'Database is not locked for backup.'
    }

    It 'Unlock fixes missing .delta file' {
        $TestDatabasePath | Should -Not -Exist
        $testDatabase = New-FirebirdDatabase -Database $TestDatabasePath -Environment $TestEnvironment
        $TestDatabasePath | Should -Exist

        Lock-FirebirdDatabase -Database $TestDatabase -Environment $TestEnvironment
        Get-FirebirdDatabaseLocked -Database $TestDatabase -Environment $TestEnvironment | Should -BeTrue

        # Simulate missing .delta file by removing it
        $deltaFile = "$($TestDatabasePath).delta"
        Remove-Item -Path $deltaFile -Force

        Unlock-FirebirdDatabase -Database $TestDatabase -Environment $TestEnvironment
        Get-FirebirdDatabaseLocked -Database $TestDatabase -Environment $TestEnvironment | Should -BeFalse

        { Unlock-FirebirdDatabase -Database $TestDatabase -Environment $TestEnvironment } | Should -Throw 'Database is not locked for backup.'
    }

    It 'Test a valid database returns true' {
        $TestDatabasePath | Should -Not -Exist
        $testDatabase = New-FirebirdDatabase -Database $TestDatabasePath -Environment $TestEnvironment
        $TestDatabasePath | Should -Exist

        Test-FirebirdDatabase -Database $testDatabase -Environment $TestEnvironment | Should -BeTrue
    }

    It 'Test a non-existent database returns false' {
        $fakePath = "$RootFolder/nonexistent-$FirebirdVersion.fdb"
        $fakePath | Should -Not -Exist

        $fakeDb = [FirebirdDatabase]::new($fakePath)
        Test-FirebirdDatabase -Database $fakeDb -Environment $TestEnvironment | Should -BeFalse
    }

    It 'Test an invalid file returns false' {
        $invalidPath = "$RootFolder/invalid-$FirebirdVersion.fdb"
        $invalidPath | Should -Not -Exist

        # Create a file with random content (not a valid database)
        Set-Content -Path $invalidPath -Value 'this is not a database'
        $invalidPath | Should -Exist

        $invalidDb = [FirebirdDatabase]::new($invalidPath)
        Test-FirebirdDatabase -Database $invalidDb -Environment $TestEnvironment | Should -BeFalse
    }

    It 'Remove a database with -Force' {
        $TestDatabasePath | Should -Not -Exist
        $testDatabase = New-FirebirdDatabase -Database $TestDatabasePath -Environment $TestEnvironment
        $TestDatabasePath | Should -Exist

        Remove-FirebirdDatabase -Database $testDatabase -Environment $TestEnvironment -Force
        $TestDatabasePath | Should -Not -Exist
    }

    It 'Remove a locked database throws' {
        $TestDatabasePath | Should -Not -Exist
        $testDatabase = New-FirebirdDatabase -Database $TestDatabasePath -Environment $TestEnvironment
        $TestDatabasePath | Should -Exist

        Lock-FirebirdDatabase -Database $testDatabase -Environment $TestEnvironment

        { Remove-FirebirdDatabase -Database $testDatabase -Environment $TestEnvironment -Force } | Should -Throw '*locked for backup*'

        # Clean up: unlock so AfterAll can remove the folder
        Unlock-FirebirdDatabase -Database $testDatabase -Environment $TestEnvironment
    }
}