functions/Get-EndjinGists.Tests.ps1

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

Describe "Get-EndjinGists" {

    BeforeAll {
        # Define stub for external module function to avoid dependency and ensure mocking works
        function ConvertFrom-Yaml { param([switch]$Ordered) }

        $sut = "$PSScriptRoot\Get-EndjinGists.ps1"
        . $sut

        # Mock Data
        $script:mockGistMap = @{
            'llm-kb' = @(
                @{
                    name = 'dotnet'
                    description = 'LLM knowledge base for .NET development'
                    source = 'https://github.com/endjin/dotnet-llm-knowledge-base.git'
                    ref = 'main'
                    includePaths = @('knowledge-base/**/*')
                }
                @{
                    name = 'powershell'
                    description = 'LLM knowledge base for PowerShell development'
                    source = 'https://github.com/endjin/powershell-llm-knowledge-base.git'
                    ref = 'main'
                    includePaths = @('knowledge-base/**/*')
                }
            )
            'devcontainer' = @(
                @{
                    name = 'ai-agent'
                    description = 'Development container for AI agents'
                    source = 'https://github.com/endjin/ai-agent-devcontainer.git'
                    ref = 'main'
                    includePaths = @('.devcontainer/**/*')
                }
            )
        }
    }

    Context "Default Output (PSCustomObject)" {
        BeforeAll {
            Mock Get-Content { return "yaml content" }
            Mock ConvertFrom-Yaml { return $script:mockGistMap }
        }

        It "Should return an array of PSCustomObjects" {
            $result = Get-EndjinGists -GistMapPath 'dummy'

            $result | Should -BeOfType [PSCustomObject]
            $result.Count | Should -Be 3
        }

        It "Should include correct properties on each object" {
            $result = Get-EndjinGists -GistMapPath 'dummy'

            $result[0].PSObject.Properties.Name | Should -Contain 'Group'
            $result[0].PSObject.Properties.Name | Should -Contain 'Name'
            $result[0].PSObject.Properties.Name | Should -Contain 'Description'
            $result[0].PSObject.Properties.Name | Should -Contain 'Source'
            $result[0].PSObject.Properties.Name | Should -Contain 'Ref'
        }

        It "Should return correct data for each gist" {
            $result = Get-EndjinGists -GistMapPath 'dummy'

            $dotnetGist = $result | Where-Object { $_.Name -eq 'dotnet' }
            $dotnetGist.Group | Should -Be 'llm-kb'
            $dotnetGist.Description | Should -Be 'LLM knowledge base for .NET development'
            $dotnetGist.Source | Should -Be 'https://github.com/endjin/dotnet-llm-knowledge-base.git'
            $dotnetGist.Ref | Should -Be 'main'
        }

        It "Should support pipeline filtering" {
            $result = Get-EndjinGists -GistMapPath 'dummy' | Where-Object { $_.Group -eq 'devcontainer' }

            $result.Count | Should -Be 1
            $result.Name | Should -Be 'ai-agent'
        }
    }

    Context "Summary Output" {
        BeforeAll {
            Mock Get-Content { return "yaml content" }
            Mock ConvertFrom-Yaml { return $script:mockGistMap }
        }

        It "Should output text when -Summary is specified" {
            $result = Get-EndjinGists -GistMapPath 'dummy' -Summary

            $result | Should -BeOfType [string]
        }

        It "Should include 'Available Gists:' header" {
            $result = Get-EndjinGists -GistMapPath 'dummy' -Summary

            $result | Should -Contain 'Available Gists:'
        }

        It "Should include group names in output" {
            $result = Get-EndjinGists -GistMapPath 'dummy' -Summary

            $result | Should -Contain ' llm-kb'
            $result | Should -Contain ' devcontainer'
        }

        It "Should include gist names and descriptions under groups" {
            $result = Get-EndjinGists -GistMapPath 'dummy' -Summary

            $result | Should -Contain ' - dotnet - LLM knowledge base for .NET development'
            $result | Should -Contain ' - powershell - LLM knowledge base for PowerShell development'
            $result | Should -Contain ' - ai-agent - Development container for AI agents'
        }
    }

    Context "Custom GistMapPath" {
        It "Should read from the specified path" {
            Mock Get-Content { return "yaml content" } -Verifiable
            Mock ConvertFrom-Yaml { return $script:mockGistMap }

            Get-EndjinGists -GistMapPath '/custom/path/gist-map.yml'

            Should -Invoke Get-Content -Times 1 -ParameterFilter { $Path -eq '/custom/path/gist-map.yml' }
        }
    }

    Context "Gists Without Description" {
        BeforeAll {
            Mock Get-Content { return "yaml content" }
            Mock ConvertFrom-Yaml {
                return @{
                    'test-group' = @(
                        @{
                            name = 'no-description-gist'
                            source = 'https://github.com/example/repo.git'
                            ref = 'main'
                        }
                    )
                }
            }
        }

        It "Should handle gists without description property" {
            $result = Get-EndjinGists -GistMapPath 'dummy'

            $result[0].Description | Should -BeNullOrEmpty
        }

        It "Should output gist name without description suffix in Summary" {
            $result = Get-EndjinGists -GistMapPath 'dummy' -Summary

            $result | Should -Contain ' - no-description-gist'
        }
    }

    Context "Empty Gist Map" {
        BeforeAll {
            Mock Get-Content { return "yaml content" }
        }

        It "Should return empty array when gist map is empty" {
            Mock ConvertFrom-Yaml { return @{} }

            $result = Get-EndjinGists -GistMapPath 'dummy'

            $result.Count | Should -Be 0
        }

        It "Should output only header when gist map is empty with -Summary" {
            Mock ConvertFrom-Yaml { return @{} }

            $result = Get-EndjinGists -GistMapPath 'dummy' -Summary

            $result | Should -Contain 'Available Gists:'
        }
    }
}