/* * ============================================================================ * Projekt.....: rs2322tcp * Datei.......: internal/gui/assignment_test.go * Copyright (C) 2026 Dieter Lang * * SPDX-License-Identifier: GPL-3.0-or-later * * Beschreibung: * Tests für die GUI-unabhängige Aufbereitung der Zuordnung zwischen lokalen * virtuellen seriellen Schnittstellen und den vom rs2322tcp-Server * angebotenen Geräten. * ============================================================================ */ package gui import ( "testing" "git.lang-dieter.de/rs2322tcp/internal/config" "git.lang-dieter.de/rs2322tcp/internal/transport" ) /////////////////////////////////////////////////////////////////////////////// // Test helpers /////////////////////////////////////////////////////////////////////////////// // testClientConfig creates a client configuration containing the supplied // local-to-remote assignments. func testClientConfig( assignments ...config.VirtualPortConfig, ) *config.ClientConfig { return &config.ClientConfig{ VirtualPorts: assignments, } } // testRemoteDevices creates a list of remote devices from their IDs. func testRemoteDevices(ids ...string) []transport.RemoteDeviceInfo { devices := make([]transport.RemoteDeviceInfo, 0, len(ids)) for _, id := range ids { devices = append(devices, transport.RemoteDeviceInfo{ ID: id, Name: id, }) } return devices } /////////////////////////////////////////////////////////////////////////////// // BuildAssignments tests /////////////////////////////////////////////////////////////////////////////// func TestBuildAssignments(t *testing.T) { cfg := testClientConfig( config.VirtualPortConfig{ Port: "/dev/ttyUSB100", RemoteDevice: "radio", }, config.VirtualPortConfig{ Port: "/dev/ttyUSB101", RemoteDevice: "rotor", }, ) devices := testRemoteDevices( "radio", "rotor", "gps", ) assignments := BuildAssignments(cfg, devices) if len(assignments) != 2 { t.Fatalf( "BuildAssignments() returned %d assignments, want 2", len(assignments), ) } if assignments[0].LocalPort != "/dev/ttyUSB100" { t.Errorf( "assignments[0].LocalPort = %q, want %q", assignments[0].LocalPort, "/dev/ttyUSB100", ) } if assignments[0].RemoteDevice != "radio" { t.Errorf( "assignments[0].RemoteDevice = %q, want %q", assignments[0].RemoteDevice, "radio", ) } if !assignments[0].Available { t.Error("assignments[0].Available = false, want true") } if assignments[1].LocalPort != "/dev/ttyUSB101" { t.Errorf( "assignments[1].LocalPort = %q, want %q", assignments[1].LocalPort, "/dev/ttyUSB101", ) } if assignments[1].RemoteDevice != "rotor" { t.Errorf( "assignments[1].RemoteDevice = %q, want %q", assignments[1].RemoteDevice, "rotor", ) } if !assignments[1].Available { t.Error("assignments[1].Available = false, want true") } } func TestBuildAssignmentsUnavailableDevice(t *testing.T) { cfg := testClientConfig( config.VirtualPortConfig{ Port: "/dev/ttyUSB100", RemoteDevice: "radio", }, config.VirtualPortConfig{ Port: "/dev/ttyUSB101", RemoteDevice: "rotor", }, ) devices := testRemoteDevices("rotor") assignments := BuildAssignments(cfg, devices) if len(assignments) != 2 { t.Fatalf( "BuildAssignments() returned %d assignments, want 2", len(assignments), ) } if assignments[0].RemoteDevice != "radio" { t.Errorf( "assignments[0].RemoteDevice = %q, want %q", assignments[0].RemoteDevice, "radio", ) } if assignments[0].Available { t.Error("radio assignment marked available, want unavailable") } if assignments[1].RemoteDevice != "rotor" { t.Errorf( "assignments[1].RemoteDevice = %q, want %q", assignments[1].RemoteDevice, "rotor", ) } if !assignments[1].Available { t.Error("rotor assignment marked unavailable, want available") } } func TestBuildAssignmentsNilConfig(t *testing.T) { devices := testRemoteDevices("radio") assignments := BuildAssignments(nil, devices) if assignments != nil { t.Fatalf( "BuildAssignments(nil, ...) = %#v, want nil", assignments, ) } } func TestBuildAssignmentsEmptyConfig(t *testing.T) { cfg := testClientConfig() devices := testRemoteDevices( "radio", "rotor", ) assignments := BuildAssignments(cfg, devices) if len(assignments) != 0 { t.Fatalf( "BuildAssignments() returned %d assignments, want 0", len(assignments), ) } } /////////////////////////////////////////////////////////////////////////////// // UnassignedDevices tests /////////////////////////////////////////////////////////////////////////////// func TestUnassignedDevices(t *testing.T) { cfg := testClientConfig( config.VirtualPortConfig{ Port: "/dev/ttyUSB100", RemoteDevice: "radio", }, config.VirtualPortConfig{ Port: "/dev/ttyUSB101", RemoteDevice: "rotor", }, ) devices := testRemoteDevices( "radio", "rotor", "gps", "tnc", ) unassigned := UnassignedDevices(cfg, devices) if len(unassigned) != 2 { t.Fatalf( "UnassignedDevices() returned %d devices, want 2", len(unassigned), ) } if unassigned[0].ID != "gps" { t.Errorf( "unassigned[0].ID = %q, want %q", unassigned[0].ID, "gps", ) } if unassigned[1].ID != "tnc" { t.Errorf( "unassigned[1].ID = %q, want %q", unassigned[1].ID, "tnc", ) } } func TestUnassignedDevicesAllAssigned(t *testing.T) { cfg := testClientConfig( config.VirtualPortConfig{ Port: "/dev/ttyUSB100", RemoteDevice: "radio", }, config.VirtualPortConfig{ Port: "/dev/ttyUSB101", RemoteDevice: "rotor", }, ) devices := testRemoteDevices( "radio", "rotor", ) unassigned := UnassignedDevices(cfg, devices) if len(unassigned) != 0 { t.Fatalf( "UnassignedDevices() returned %d devices, want 0", len(unassigned), ) } } func TestUnassignedDevicesEmptyConfig(t *testing.T) { cfg := testClientConfig() devices := testRemoteDevices( "radio", "rotor", ) unassigned := UnassignedDevices(cfg, devices) if len(unassigned) != 2 { t.Fatalf( "UnassignedDevices() returned %d devices, want 2", len(unassigned), ) } } func TestUnassignedDevicesNilConfig(t *testing.T) { devices := testRemoteDevices( "radio", "rotor", ) unassigned := UnassignedDevices(nil, devices) if len(unassigned) != 2 { t.Fatalf( "UnassignedDevices(nil, ...) returned %d devices, want 2", len(unassigned), ) } } func TestUnassignedDevicesEmptyServerList(t *testing.T) { cfg := testClientConfig( config.VirtualPortConfig{ Port: "/dev/ttyUSB100", RemoteDevice: "radio", }, ) unassigned := UnassignedDevices(cfg, nil) if len(unassigned) != 0 { t.Fatalf( "UnassignedDevices() returned %d devices, want 0", len(unassigned), ) } } /////////////////////////////////////////////////////////////////////////////// // Existing configuration does not change /////////////////////////////////////////////////////////////////////////////// func TestAssignmentFunctionsDoNotModifyConfig(t *testing.T) { cfg := testClientConfig( config.VirtualPortConfig{ Port: "/dev/ttyUSB100", RemoteDevice: "radio", }, ) devices := testRemoteDevices( "radio", "rotor", "gps", ) _ = BuildAssignments(cfg, devices) _ = UnassignedDevices(cfg, devices) if len(cfg.VirtualPorts) != 1 { t.Fatalf( "configuration contains %d virtual ports, want 1", len(cfg.VirtualPorts), ) } if cfg.VirtualPorts[0].Port != "/dev/ttyUSB100" { t.Errorf( "configuration port = %q, want %q", cfg.VirtualPorts[0].Port, "/dev/ttyUSB100", ) } if cfg.VirtualPorts[0].RemoteDevice != "radio" { t.Errorf( "configuration remote device = %q, want %q", cfg.VirtualPorts[0].RemoteDevice, "radio", ) } }