Bookmarks.Tests.ps1

$config = [PesterConfiguration]::Default


# Set NUnit output
# $config.TestResult.Enabled = $true
# $config.TestResult.OutputPath = 'TestResults.xml'
# $config.TestResult.Format = 'NUnitXml'

$NoExport = $true
$ModuleDevelopment = $true
$DebugPreference = "Continue"

Write-Debug "Running tests for Bookmarks module"


Set-StrictMode -version Latest

Describe "Bookmark Operations" {

# Create a setup block that runs before all tests
BeforeAll {
    $script:here = Split-Path -Parent $PSCommandPath
    Write-Debug "Path set in BeforeAll: $script:here"

    # Load all cmdlets after path is properly set
    . "$script:here/cmdlets/Get-BookmarksDataFile.ps1"
    . "$script:here/cmdlets/Add-PSBookmark.ps1"
    . "$script:here/cmdlets/Get-PSBookmarks.ps1"
    . "$script:here/cmdlets/Import-PSBookmarks.ps1"
    . "$script:here/cmdlets/Open-PSBookmark.ps1"
    . "$script:here/cmdlets/Remove-AllPSBookmarks.ps1"
    . "$script:here/cmdlets/Remove-PSBookmark.ps1"
    . "$script:here/cmdlets/Save-PSBookmarks.ps1"
    . "$script:here/cmdlets/Update-PSBookmark.ps1"

    # Mock the Get-BookmarksDataFile function
    Mock -CommandName Get-BookmarksDataFile  -MockWith { 
        return '/BookmarksDataFile'
    }
}

BeforeEach {
    # Clear the script variable before each test
    $script:marks_to_save = @{}
    Write-Debug "Cleared script variable in BeforeEach"
}


# Get-BookmarksDataFile

Context "Get-BookmarksDataFile" {

    It "Return bookmarks data file" {
  
        # Use real function istead of alias
        Remove-Item -Path Alias:Get-BookmarksDataFile -Force

        . "$script:here/cmdlets/Get-BookmarksDataFile.ps1"

        # act
        
        $folder = Get-BookmarksDataFile 
    
        #assert
        $folder | Should -Not -Be $null
        $folder | Should -BeOfType [string]
        $folder | Should -Match "ScriptData/Bookmarks/bookmarks$"
        $folder | Should -Match "^$([Regex]::Escape([Environment]::GetFolderPath('UserProfile'))).+ScriptData/Bookmarks/bookmarks$"

    }
}

Context "Save-PSBookmarks" {

    It "save all bookmarks" {

        # mock

        Mock -CommandName Export-Csv -Verifiable -MockWith { 
            param (
            $InputObject,
            $Path,
            $NoTypeInformation
            )
            # Collect the objects from the pipeline
            foreach ($item in $InputObject) {
                $script:marks_to_save[$item.Key] = $item.Value
            }
            # Save to variables for assertion if needed
            $script:exportedPath = $Path
            Write-Debug "Saved bookmarks $($($script:marks_to_save).Count) to file: $($Path)"
        } 
 
        Mock -CommandName Get-BookmarksDataFile  -MockWith { 
            return 'this'
        }

        # arrange
        $_marks = @{ }
        $_marks["a"] = "A"
        $_marks["b"] = "B"
        $_marks.Count | Should -Not -Be 0

        # act
        Save-PSBookmarks $_marks

        # assert
        $script:marks_to_save.Count | Should -Be 2
        $script:marks_to_save["b"] | Should -Be "B"

        Assert-VerifiableMock

        Assert-MockCalled Get-BookmarksDataFile -Times 1
    }
}

Context "Remove-AllPSBookmarks" {

    It "clear all bookmarks" {

        # mock
        Mock -CommandName Save-PSBookmarks -MockWith {
            param (
                $marks
            )
            $script:marks_to_save = $marks
            Write-Debug "Saved bookmarks $($($script:marks_to_save).Count) to file: $($Path)"
            
        } -Verifiable

        # arrange
        $script:marks_to_save["a"]="A"
        $script:marks_to_save["b"]="B"

        $script:marks_to_save.Count | Should -Be 2

        # act

        Remove-AllPSBookmarks

        # assert
        $script:marks_to_save.Count | Should -Be 0
        Assert-VerifiableMock
    }
}

Context "Add-PSBookmark" {


    Mock -CommandName Save-PSBookmarks -MockWith {
            param (
                $marks
            )
            $script:marks_to_save = $marks
            Write-Debug "Saved bookmarks $($($script:marks_to_save).Count) to file"
            
        } -Verifiable

        Mock -CommandName Import-PSBookmarks -MockWith {
            param (
            )
            Write-Debug "Loded bookmarks $($($script:marks_to_save).Count) from file"
            
            return $script:marks_to_save
        } -Verifiable
        
    It "adds current folder to bookmarks" {

        # mock
        Mock -CommandName Save-PSBookmarks -MockWith {
            param (
                $marks
            )
            $script:marks_to_save = $marks
            Write-Debug "Saved bookmarks $($($script:marks_to_save).Count) to file: $($Path)"
            
        } -Verifiable

         Mock -CommandName Import-PSBookmarks -MockWith {
            param (
            )
            Write-Debug "Loded bookmarks $($($script:marks_to_save).Count) from file"
            
            return $script:marks_to_save
        } -Verifiable

        # act
        Set-Location $here
        Add-PSBookmark testDir1

        # assert
        $script:marks_to_save.Count | Should -Be 1
        $script:marks_to_save.Keys | Should -Be "testDir1"
        $script:marks_to_save.Values | Should -Be $here

        Assert-VerifiableMock
    }

    It "adds selected folder to bookmarks" {

        # mock
        Mock -CommandName Save-PSBookmarks -MockWith {
            param (
                $marks
            )
            $script:marks_to_save = $marks
            Write-Debug "Saved bookmarks $($($script:marks_to_save).Count) to file"
            
        } -Verifiable

        Mock -CommandName Import-PSBookmarks -MockWith {
            param (
            )
            Write-Debug "Loded bookmarks $($($script:marks_to_save).Count) from file"
            
            return $script:marks_to_save
        } -Verifiable

        # arrange

        $_marks = @{ }

        # act

        Add-PSBookmark testDir2 "c:"
        $_marks = Get-PSBookmarks 

        # assert
        $_marks.Count | Should -Be 1
        $_marks.Keys | Should -Be "testDir2"
        $_marks.Values | Should -Be "c:"

        Assert-VerifiableMock
        Assert-MockCalled Import-PSBookmarks -Times 2
    }

    It "adds path from pipeline to bookmarks" {

        # mock
        Mock -CommandName Save-PSBookmarks -MockWith {
            param (
                $marks
            )
            $script:marks_to_save = $marks
            Write-Debug "Saved bookmarks $($($script:marks_to_save).Count) to file"
            
        } -Verifiable

        Mock -CommandName Import-PSBookmarks -MockWith {
            param (
            )
            Write-Debug "Loded bookmarks $($($script:marks_to_save).Count) from file"
            
            return $script:marks_to_save
        } -Verifiable

        # arrange
        
        $_marks = @{ }

        # act

        "c:" |Add-PSBookmark testDir3 
        $_marks = Get-PSBookmarks 

        # assert
        $_marks.Count | Should -Be 1
        $_marks.Keys | Should -Be "testDir3"
        $_marks.Values | Should -Be "c:"
    }
}


Context "Remove-PSBookmark" {

    It "remove bookmark from list" {

        # mock
        Mock -CommandName Save-PSBookmarks -MockWith {
            param (
                $marks
            )
            $script:marks_to_save = $marks
            Write-Debug "Saved bookmarks $($($script:marks_to_save).Count) to file"
            
        } -Verifiable

        Mock -CommandName Import-PSBookmarks -MockWith {
            param (
            )
            Write-Debug "Loded bookmarks $($($script:marks_to_save).Count) from file"
            
            return $script:marks_to_save
        } -Verifiable

        # arrange

        Add-PSBookmark 'a' "A"

        # act
        Remove-PSBookmark  "a"

        # assert
        $script:marks_to_save.Count | Should -Be 0

        Assert-VerifiableMock
    }

}

Context "Open-PSBookmark" {

    It "open specific bookmark" {

        # mock
    
        Mock -CommandName Import-PSBookmarks -MockWith {
            param (
            )
            Write-Debug "Loded bookmarks $($($script:marks_to_save).Count) from file"
            
            return $script:marks_to_save
        } -Verifiable


        # arrange
        $script:marks_to_save["a"]="A";

        Mock -CommandName Set-Location -MockWith {} 
    
        # act
        Open-PSBookmark "a"

        # assert
        Assert-MockCalled Set-Location 1 
        Assert-VerifiableMock
    }
}
    
Context "Update-PSBookmark" {

    It "update current folder to bookmarks" {
        # mock
        Mock -CommandName Save-PSBookmarks -MockWith {
            param (
                $marks
            )
            $script:marks_to_save = $marks
            Write-Debug "Saved bookmarks $($($script:marks_to_save).Count) to file"
            
        } -Verifiable

        Mock -CommandName Import-PSBookmarks -MockWith {
            param (
            )
            Write-Debug "Loded bookmarks $($($script:marks_to_save).Count) from file"
            
            return $script:marks_to_save
        } -Verifiable

        Mock -CommandName Set-Location -MockWith {} -Verifiable

        # arrange


        # act
        Add-PSBookmark testDir1 "c:"

        Set-Location $here
        Update-PSBookmark testDir1

        # assert
        $script:marks_to_save.Count | Should -Be 1
        $script:marks_to_save.Keys | Should -Be "testDir1"
        $script:marks_to_save.Values | Should -Be $here

        Assert-VerifiableMock
    }

    It "Update selected folder in bookmarks list" {

        # mock
        Mock -CommandName Save-PSBookmarks -MockWith {
            param (
                $marks
            )
            $script:marks_to_save = $marks
            Write-Debug "Saved bookmarks $($($script:marks_to_save).Count) to file"
            
        } -Verifiable

        Mock -CommandName Import-PSBookmarks -MockWith {
            param (
            )
            Write-Debug "Loded bookmarks $($($script:marks_to_save).Count) from file"
            
            return $script:marks_to_save
        } -Verifiable

        # act

        Add-PSBookmark testDir2 "c:"
        Update-PSBookmark testDir2 "$pwd"
        $_marks = Get-PSBookmarks 

        # assert
        $_marks.Count | Should -Be 1
        $_marks.Keys | Should -Be "testDir2"
        $_marks.Values | Should -Be "$pwd"
    }

    It "Update path from pipeline to bookmarks" {

        # mock
        Mock -CommandName Save-PSBookmarks -MockWith {
            param (
                $marks
            )
            $script:marks_to_save = $marks
            Write-Debug "Saved bookmarks $($($script:marks_to_save).Count) to file"
            
        } -Verifiable

        Mock -CommandName Import-PSBookmarks -MockWith {
            param (
            )
            Write-Debug "Loded bookmarks $($($script:marks_to_save).Count) from file"
            
            return $script:marks_to_save
        } -Verifiable


        # arrange

        # act
        Add-PSBookmark testDir3 "$pwd"

        "c:" |Update-PSBookmark testDir3
        $_marks = Get-PSBookmarks 

        # assert
        $_marks.Count | Should -Be 1
        $_marks.Keys | Should -Be "testDir3"
        $_marks.Values | Should -Be "c:"
    }
}
}