Tests/Unit/Public/Connectors.Tests.ps1

BeforeAll {
    $moduleRoot = (Resolve-Path (Join-Path $PSScriptRoot '../../..')).Path
    Import-Module (Join-Path $moduleRoot 'psSIA.psd1') -Force
}

Describe 'Get-SIAConnector' {
    It 'unwraps the items array and follows continuation tokens' {
        InModuleScope psSIA {
            $script:callCount = 0
            Mock Invoke-SIARequest {
                $script:callCount++
                if ($script:callCount -eq 1) {
                    [pscustomobject]@{ items = @([pscustomobject]@{ id = 'conn-1' }); continuationToken = 'next' }
                } else {
                    [pscustomobject]@{ items = @([pscustomobject]@{ id = 'conn-2' }); continuationToken = $null }
                }
            }

            $result = Get-SIAConnector

            $result.Count | Should -Be 2
            $result[0].PSObject.TypeNames | Should -Contain 'psSIA.Connector'
            Should -Invoke Invoke-SIARequest -Times 2 -Exactly
        }
    }

    It 'stops after the first page with -NoAutoPaging' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                [pscustomobject]@{ items = @(@{ id = 'conn-1' }); continuationToken = 'next' }
            }

            $result = Get-SIAConnector -NoAutoPaging

            $result.Count | Should -Be 1
            Should -Invoke Invoke-SIARequest -Times 1 -Exactly
        }
    }
}

Describe 'Remove-SIAConnector' {
    It 'calls DELETE for the specified connector' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Method, $Path)
                $Method | Should -Be 'DELETE'
                $Path | Should -Be '/api/connectors/conn-1'
            }

            Remove-SIAConnector -Id 'conn-1' -Confirm:$false
            Should -Invoke Invoke-SIARequest -Times 1 -Exactly
        }
    }

    It 'does not call the API under -WhatIf' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {}
            Remove-SIAConnector -Id 'conn-1' -WhatIf
            Should -Invoke Invoke-SIARequest -Times 0 -Exactly
        }
    }

    It 'accepts pipeline input by property name' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {}
            [pscustomobject]@{ id = 'conn-2' } | Remove-SIAConnector -Confirm:$false
            Should -Invoke Invoke-SIARequest -ParameterFilter { $Path -eq '/api/connectors/conn-2' } -Times 1 -Exactly
        }
    }
}

Describe 'Update-SIAConnector' {
    It 'calls the upgrade endpoint with -Upgrade' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Path)
                $Path | Should -Be '/api/connectors/conn-1/upgrade'
            }

            Update-SIAConnector -Id 'conn-1' -Upgrade -Confirm:$false
        }
    }

    It 'calls the rotate endpoint with -Rotate' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Path)
                $Path | Should -Be '/api/connectors/conn-1/rotate'
            }

            Update-SIAConnector -Id 'conn-1' -Rotate -Confirm:$false
        }
    }

    It 'requires exactly one of -Upgrade or -Rotate' {
        { Update-SIAConnector -Id 'conn-1' } | Should -Throw
    }
}

Describe 'Test-SIAConnector' {
    It 'calls the reachability endpoint' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Method, $Path)
                $Method | Should -Be 'POST'
                $Path | Should -Be '/api/connectors/conn-1/reachability'
            }

            Test-SIAConnector -Id 'conn-1' | Out-Null
        }
    }
}

Describe 'Add-SIAConnectorPoolAssignment' {
    It 'wraps each connector ID as {connectorId: ...} in the connectors array' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Method, $Path, $Body)
                $Method | Should -Be 'POST'
                $Path | Should -Be '/api/connectors/connector-pools/pool-1'
                $Body.connectors.Count | Should -Be 2
                $Body.connectors[0].connectorId | Should -Be 'conn-1'
                $Body.connectors[1].connectorId | Should -Be 'conn-2'
            }

            Add-SIAConnectorPoolAssignment -ConnectorPoolId 'pool-1' -ConnectorId 'conn-1', 'conn-2' -Confirm:$false
        }
    }
}

Describe 'Set-SIAConnectorMaintenanceMode' {
    It 'calls PUT against the maintenance endpoint with the maintenance flag' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Method, $Path, $Body)
                $Method | Should -Be 'PUT'
                $Path | Should -Be '/api/connectors/conn-1/maintenance'
                $Body.maintenance | Should -Be $true
            }

            Set-SIAConnectorMaintenanceMode -Id 'conn-1' -Maintenance $true -Confirm:$false
        }
    }

    It 'does nothing under -WhatIf' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {}
            Set-SIAConnectorMaintenanceMode -Id 'conn-1' -Maintenance $true -WhatIf
            Should -Invoke Invoke-SIARequest -Times 0 -Exactly
        }
    }
}

Describe 'New-SIAConnectorInstallScript' {
    It 'defaults ConnectorOs to linux' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Method, $Path, $Body)
                $Method | Should -Be 'POST'
                $Path | Should -Be '/api/connectors/setup-script'
                $Body.connector_os | Should -Be 'linux'
                $Body.Keys | Should -Not -Contain 'connector_pool_id'
            }

            New-SIAConnectorInstallScript | Out-Null
        }
    }

    It 'includes only the parameters the caller supplied' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Body)
                $Body.connector_os | Should -Be 'windows'
                $Body.connector_pool_id | Should -Be 'pool-1'
                $Body.windows_installation_path | Should -Be 'D:\SIA'
                $Body.Keys | Should -Not -Contain 'proxy_host'
            }

            New-SIAConnectorInstallScript -ConnectorOs windows -ConnectorPoolId 'pool-1' -WindowsInstallationPath 'D:\SIA' | Out-Null
        }
    }
}

Describe 'Get-SIAHttpsRelay' {
    It 'unwraps the items array and follows continuation tokens' {
        InModuleScope psSIA {
            $script:callCount = 0
            Mock Invoke-SIARequest {
                $script:callCount++
                if ($script:callCount -eq 1) {
                    [pscustomobject]@{ items = @([pscustomobject]@{ id = 'relay-1' }); continuationToken = 'next' }
                } else {
                    [pscustomobject]@{ items = @([pscustomobject]@{ id = 'relay-2' }); continuationToken = $null }
                }
            }

            $result = Get-SIAHttpsRelay

            $result.Count | Should -Be 2
            $result[0].PSObject.TypeNames | Should -Contain 'psSIA.HttpsRelay'
        }
    }
}

Describe 'Remove-SIAHttpsRelay' {
    It 'calls DELETE for the specified relay' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Method, $Path)
                $Method | Should -Be 'DELETE'
                $Path | Should -Be '/api/https-relays/relay-1'
            }

            Remove-SIAHttpsRelay -Id 'relay-1' -Confirm:$false
        }
    }

    It 'does not call the API under -WhatIf' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {}
            Remove-SIAHttpsRelay -Id 'relay-1' -WhatIf
            Should -Invoke Invoke-SIARequest -Times 0 -Exactly
        }
    }
}

Describe 'New-SIAHttpsRelayInstallScript' {
    It 'defaults HttpsRelayOs to linux and includes only supplied fields' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Method, $Path, $Body)
                $Method | Should -Be 'POST'
                $Path | Should -Be '/api/https-relays/setup-script'
                $Body.https_relay_os | Should -Be 'linux'
                $Body.Keys | Should -Not -Contain 'protocol_port_map'
            }

            New-SIAHttpsRelayInstallScript | Out-Null
        }
    }

    It 'includes the protocol port map when supplied' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest {
                param($Body)
                $Body.protocol_port_map.SSH | Should -Be 2222
            }

            New-SIAHttpsRelayInstallScript -ProtocolPortMap @{ SSH = 2222 } | Out-Null
        }
    }
}

Describe 'Update-SIAHttpsRelay' {
    It 'calls the upgrade endpoint with -Upgrade' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest { param($Path) $Path | Should -Be '/api/https-relays/relay-1/upgrade' }
            Update-SIAHttpsRelay -Id 'relay-1' -Upgrade -Confirm:$false
        }
    }

    It 'calls the rotate endpoint with -Rotate' {
        InModuleScope psSIA {
            Mock Invoke-SIARequest { param($Path) $Path | Should -Be '/api/https-relays/relay-1/rotate' }
            Update-SIAHttpsRelay -Id 'relay-1' -Rotate -Confirm:$false
        }
    }
}