tests/unit/Public/Get-KlippyUsbDevice.Tests.ps1

#Requires -Modules Pester

BeforeAll {
    $modulePath = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
    Import-Module "$modulePath/KlippyCLI.psd1" -Force
}

Describe "Get-KlippyUsbDevice" -Tag Unit {
    BeforeEach {
        $script:testPrinter = [PSCustomObject]@{
            Id          = "11111111-1111-1111-1111-111111111111"
            PrinterName = "TestPrinter"
            Uri         = "http://127.0.0.1"
            ApiKey      = $null
        }

        Mock -CommandName Resolve-KlippyPrinterTarget -ModuleName KlippyCLI -MockWith {
            return $script:testPrinter
        }
    }

    It "Should return USB devices from JSON-RPC peripherals endpoint when available" {
        Mock -CommandName Invoke-KlippyJsonRpcMethod -ModuleName KlippyCLI -ParameterFilter { $Method -eq "machine.peripherals.usb" } -MockWith {
            return [PSCustomObject]@{
                UsbDevices = @([PSCustomObject]@{ VendorId = "1d50"; ProductId = "614e" })
            }
        }

        $result = Get-KlippyUsbDevice -PrinterName "TestPrinter"

        $result | Should -Not -BeNullOrEmpty
        $result.PSTypeName | Should -Be "KlippyCLI.UsbDeviceInfo"
        $result.UsbDevices[0].VendorId | Should -Be "1d50"
    }

    It "Should handle JSON-RPC endpoint returning a device array" {
        Mock -CommandName Invoke-KlippyJsonRpcMethod -ModuleName KlippyCLI -ParameterFilter { $Method -eq "machine.peripherals.usb" } -MockWith {
            return @([PSCustomObject]@{ VendorId = "abcd"; ProductId = "1234" })
        }

        $result = Get-KlippyUsbDevice -PrinterName "TestPrinter"

        $result | Should -Not -BeNullOrEmpty
        $result.UsbDevices[0].VendorId | Should -Be "abcd"
    }

    It "Should fall back to machine/system_info when JSON-RPC endpoint is not found" {
        Mock -CommandName Invoke-KlippyJsonRpcMethod -ModuleName KlippyCLI -ParameterFilter { $Method -eq "machine.peripherals.usb" } -MockWith {
            throw [System.Exception]::new("Method not found")
        }
        Mock -CommandName Invoke-KlippyJsonRpc -ModuleName KlippyCLI -ParameterFilter { $Method -eq "machine/usb" } -MockWith {
            throw [System.Exception]::new("Not Found")
        }
        Mock -CommandName Invoke-KlippyJsonRpc -ModuleName KlippyCLI -ParameterFilter { $Method -eq "machine/system_info" } -MockWith {
            return [PSCustomObject]@{
                SystemInfo = [PSCustomObject]@{
                    UsbDevices = @([PSCustomObject]@{ VendorId = "abcd"; ProductId = "1234" })
                }
            }
        }

        $result = Get-KlippyUsbDevice -PrinterName "TestPrinter"

        $result | Should -Not -BeNullOrEmpty
        $result.UsbDevices[0].VendorId | Should -Be "abcd"
    }

    It "Should accept printer input from the pipeline" {
        Mock -CommandName Invoke-KlippyJsonRpcMethod -ModuleName KlippyCLI -MockWith {
            return @()
        }

        $result = $script:testPrinter | Get-KlippyUsbDevice

        $result | Should -Not -BeNullOrEmpty
        $result.PrinterName | Should -Be "TestPrinter"
    }

    It "Should return raw USB devices when -Raw is set" {
        Mock -CommandName Invoke-KlippyJsonRpcMethod -ModuleName KlippyCLI -ParameterFilter { $Method -eq "machine.peripherals.usb" } -MockWith {
            return @([PSCustomObject]@{ vendor_id = "abcd"; product_id = "1234" })
        }

        $result = Get-KlippyUsbDevice -PrinterName "TestPrinter" -Raw

        $result | Should -Not -BeNullOrEmpty
        $result[0].vendor_id | Should -Be "abcd"
    }
}