functions/_Get-VendirPath.Tests.ps1

# <copyright file="_Get-VendirPath.Tests.ps1" company="Endjin Limited">
# Copyright (c) Endjin Limited. All rights reserved.
# </copyright>

Describe "_Get-VendirPath" {

    BeforeAll {
        # Define stub for internal helper function
        function _Install-Vendir { }

        $sut = "$PSScriptRoot\_Get-VendirPath.ps1"
        . $sut
    }

    Context "Priority 1 - System PATH" {
        BeforeAll {
            Mock Get-Command { return [PSCustomObject]@{ Source = '/usr/local/bin/vendir' } }
            Mock Test-Path { return $false }
            Mock _Install-Vendir { }
            Mock Write-Verbose { }
        }

        It "Should return path from Get-Command when vendir is in PATH" {
            $result = _Get-VendirPath

            $result | Should -Be '/usr/local/bin/vendir'
        }

        It "Should not check local bin directory when found in PATH" {
            _Get-VendirPath

            Should -Invoke Test-Path -Times 0
        }

        It "Should not call _Install-Vendir when found in PATH" {
            _Get-VendirPath

            Should -Invoke _Install-Vendir -Times 0
        }

        It "Should write verbose message about using system PATH" {
            _Get-VendirPath -Verbose

            Should -Invoke Write-Verbose -ParameterFilter { $Message -like '*system PATH*' }
        }
    }

    Context "Priority 2 - Module bin/ directory" {
        BeforeAll {
            Mock Get-Command { return $null }
            Mock Test-Path { return $true }
            Mock _Install-Vendir { }
            Mock Write-Verbose { }
        }

        It "Should return local path when vendir exists in bin/ directory" {
            $result = _Get-VendirPath

            $result | Should -Match 'bin[/\\]vendir'
        }

        It "Should not call _Install-Vendir when found in bin/ directory" {
            _Get-VendirPath

            Should -Invoke _Install-Vendir -Times 0
        }

        It "Should write verbose message about using module bin/" {
            _Get-VendirPath -Verbose

            Should -Invoke Write-Verbose -ParameterFilter { $Message -like '*module bin/*' }
        }
    }

    Context "Priority 3 - Auto-download" {
        BeforeAll {
            Mock Get-Command { return $null }
            Mock Test-Path { return $false }
            Mock _Install-Vendir { return '/downloaded/path/vendir' }
            Mock Write-Verbose { }
        }

        It "Should call _Install-Vendir when vendir not found anywhere" {
            _Get-VendirPath

            Should -Invoke _Install-Vendir -Times 1
        }

        It "Should return path from _Install-Vendir" {
            $result = _Get-VendirPath

            $result | Should -Be '/downloaded/path/vendir'
        }

        It "Should write verbose message about downloading" {
            _Get-VendirPath -Verbose

            Should -Invoke Write-Verbose -ParameterFilter { $Message -like '*Downloading*' }
        }
    }

    Context "Error Handling" {
        BeforeAll {
            Mock Get-Command { return $null }
            Mock Test-Path { return $false }
            Mock Write-Verbose { }
        }

        It "Should propagate exceptions from _Install-Vendir" {
            Mock _Install-Vendir { throw "Failed to download vendir from https://github.com/carvel-dev/vendir: Network error" }

            { _Get-VendirPath } | Should -Throw "*Failed to download vendir*"
        }
    }
}