endjin-gists.completers.tests.ps1

# <copyright file="endjin-gists.completers.tests.ps1" company="Endjin Limited">
# Copyright (c) Endjin Limited. All rights reserved.
# </copyright>

Describe "Argument Completers" {

    BeforeAll {
        # Define stubs for external module functions
        function ConvertTo-Yaml { param($Data, $OutFile, [switch]$Force) }
        function ConvertFrom-Yaml { param([switch]$Ordered) }

        # Dot-source the helper function used by the completers
        . "$PSScriptRoot/functions/_Get-GistMapData.ps1"

        $mockMapData = @{
            'azure' = @(
                @{ name = 'deploy-script' }
                @{ name = 'dns-config' }
            )
            'aws' = @(
                @{ name = 'lambda-template' }
            )
            'common' = @(
                @{ name = 'logging' }
                @{ name = 'ci-pipeline' }
            )
        }

        # Reconstruct the completer blocks (matching the logic in endjin-gists.psm1)
        $groupCompleter = {
            param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
            try {
                $map = _Get-GistMapData -ScriptRoot $PSScriptRoot
                if ($map) {
                    $map.Keys | Where-Object { $_ -like "$wordToComplete*" }
                }
            }
            catch { }
        }

        $nameCompleter = {
            param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
            try {
                $map = _Get-GistMapData -ScriptRoot $PSScriptRoot
                if ($map) {
                    $group = $fakeBoundParameters['Group']
                    if ($group -and $map.ContainsKey($group)) {
                        $map[$group] | ForEach-Object { $_.name } | Where-Object { $_ -like "$wordToComplete*" }
                    }
                }
            }
            catch { }
        }
    }

    Context "Group Completer" {
        It "Should return all group names when no filter typed" {
            Mock _Get-GistMapData { return $mockMapData }

            $results = & $groupCompleter 'Get-EndjinGist' 'Group' '' $null @{}

            $results | Should -HaveCount 3
            $results | Should -Contain 'azure'
            $results | Should -Contain 'aws'
            $results | Should -Contain 'common'
        }

        It "Should filter groups by prefix" {
            Mock _Get-GistMapData { return $mockMapData }

            $results = & $groupCompleter 'Get-EndjinGist' 'Group' 'a' $null @{}

            $results | Should -Contain 'azure'
            $results | Should -Contain 'aws'
            $results | Should -Not -Contain 'common'
        }

        It "Should return nothing when map is null" {
            Mock _Get-GistMapData { return $null }

            $results = & $groupCompleter 'Get-EndjinGist' 'Group' '' $null @{}

            $results | Should -BeNullOrEmpty
        }

        It "Should return nothing when _Get-GistMapData throws" {
            Mock _Get-GistMapData { throw "Unexpected error" }

            $results = & $groupCompleter 'Get-EndjinGist' 'Group' '' $null @{}

            $results | Should -BeNullOrEmpty
        }
    }

    Context "Name Completer" {
        It "Should return names for the selected group" {
            Mock _Get-GistMapData { return $mockMapData }

            $fakeBound = @{ 'Group' = 'azure' }
            $results = & $nameCompleter 'Get-EndjinGist' 'Name' '' $null $fakeBound

            $results | Should -HaveCount 2
            $results | Should -Contain 'deploy-script'
            $results | Should -Contain 'dns-config'
        }

        It "Should filter names by prefix" {
            Mock _Get-GistMapData { return $mockMapData }

            $fakeBound = @{ 'Group' = 'azure' }
            $results = & $nameCompleter 'Get-EndjinGist' 'Name' 'd' $null $fakeBound

            $results | Should -Contain 'deploy-script'
            $results | Should -Contain 'dns-config'
        }

        It "Should return nothing when Group parameter is not set" {
            Mock _Get-GistMapData { return $mockMapData }

            $fakeBound = @{}
            $results = & $nameCompleter 'Get-EndjinGist' 'Name' '' $null $fakeBound

            $results | Should -BeNullOrEmpty
        }

        It "Should return nothing when Group is invalid" {
            Mock _Get-GistMapData { return $mockMapData }

            $fakeBound = @{ 'Group' = 'nonexistent' }
            $results = & $nameCompleter 'Get-EndjinGist' 'Name' '' $null $fakeBound

            $results | Should -BeNullOrEmpty
        }

        It "Should return nothing when _Get-GistMapData throws" {
            Mock _Get-GistMapData { throw "Unexpected error" }

            $fakeBound = @{ 'Group' = 'azure' }
            $results = & $nameCompleter 'Get-EndjinGist' 'Name' '' $null $fakeBound

            $results | Should -BeNullOrEmpty
        }
    }
}