McpRepl.Tests.ps1
|
# Pester 5+ tests for the consolidated McpRepl module (canonical source). # Run from repo root: # pwsh -NoProfile -Command "Invoke-Pester 'tools/powershell/McpRepl/McpRepl.Tests.ps1'" # # These tests live with the module source in McpServer so they travel with the canonical bits # and can be executed in CI or locally before publishing to PSGallery. # Custom classes defined in the .psm1 are brought into scope via 'using module'. # Functions are exported via the manifest. using module .\McpRepl.psm1 BeforeAll { $moduleRoot = $PSScriptRoot Import-Module (Join-Path $moduleRoot 'McpRepl.psd1') -Force } Describe 'McpRepl Typed Entities' { It 'Creates McpRequest with correct properties' { $req = New-McpRequest -RequestId 'req-001' -Method 'workflow.todo.create' -Params @{ id = 'TODO-001' } $req.RequestId | Should -Be 'req-001' $req.Method | Should -Be 'workflow.todo.create' $req.Params.id | Should -Be 'TODO-001' } It 'McpError and McpResult can be created' { $err = [McpError]::new() $err.Code = 'validation_failed' $err.Message = 'missing condition' $err | Should -Not -BeNullOrEmpty } } Describe 'YAML Serialization (the core requirement)' { It 'Serializes a createTest request using the correct "condition" field' { $req = New-McpRequest -RequestId 'req-test-042' -Method 'workflow.requirements.createTest' -Params @{ id = 'TEST-MCP-042' title = 'Module produces valid YAML' condition = 'The serializer must emit "condition" not "description"' priority = 'high' area = 'PLUGIN' } $yaml = ConvertTo-McpYaml -InputObject $req $yaml | Should -Match 'type: request' $yaml | Should -Match 'method: workflow.requirements.createTest' $yaml | Should -Match 'condition:' $yaml | Should -Not -Match 'description:' # critical regression guard } It 'Uses literal block scalar for multi-line bodies' { $params = @{ body = "Line 1`nLine 2 with special: chars" } $req = New-McpRequest -RequestId 'r1' -Method 'test' -Params $params $yaml = ConvertTo-McpYaml -InputObject $req $yaml | Should -Match '\|' } It 'Round-trips a result envelope' { $sample = @" type: result payload: requestId: req-123 result: ok: true "@ $parsed = ConvertFrom-McpYaml $sample $parsed.RequestId | Should -Be 'req-123' } } Describe 'High-level Invoke-McpRepl API' { It 'Invoke-McpReplRaw returns a structured object even on failure (when binary missing)' { # This will fail because mcpserver-repl may not be in PATH in test env, but we test the structure try { $null = Invoke-McpReplRaw -Method 'client.Health.GetAsync' -TimeoutSeconds 2 -ErrorAction Stop } catch { $_.Exception.Message | Should -Match 'mcpserver-repl not found' } } } Describe 'Module Surface' { It 'Exports the expected functions and classes are loadable' { $funcs = Get-Command -Module McpRepl | Select-Object -ExpandProperty Name $funcs | Should -Contain 'ConvertTo-McpYaml' $funcs | Should -Contain 'Invoke-McpRepl' # Classes should be available [McpRequest] | Should -Not -BeNullOrEmpty [McpError] | Should -Not -BeNullOrEmpty } } |