forked from kay/RouterOS
- WAN-Schritt: fehlenden "Zurück"-Button ergänzt (beide Modi) - "Abbrechen"/"Jetzt sichern" prominent gemacht (wie "Neu scannen") - LAN-/VLAN-Schritt: Adressfelder starten leer, nur Format-Beispiel im Feld sichtbar statt vorbelegter Werte. VlanStepView bekam dafür eine Validierungssperre auf "Weiter" (fehlte bisher, war ok solange Defaults immer gültig waren). Zwei Tests entsprechend angepasst. - SSH-Host-Key-Trust aus M24 hatte sich entgegen der Live-Bestätigung nie tatsächlich persistiert (defaults read zeigte leeren Schlüssel, Ursache ungeklärt) — betraf BackupServices dedizierte SSH-Verbindung beim ersten Experte-Tab-Schreibversuch pro Sitzung. Erneut über den bestehenden Trust-Dialog bestätigt, diesmal per defaults read verifiziert statt nur der UI-Bestätigung vertraut. Alles live bestätigt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
128 lines
4.9 KiB
Swift
128 lines
4.9 KiB
Swift
import XCTest
|
|
@testable import RouterOSAssistant
|
|
|
|
final class RouterOSCommandBuilderTests: XCTestCase {
|
|
func testWanDhcpClientCommand() {
|
|
let config = WanConfig(interfaceName: "ether1", mode: .dhcpClient)
|
|
let commands = config.buildCommands()
|
|
|
|
XCTAssertEqual(commands.count, 1)
|
|
XCTAssertEqual(commands[0].menuPath, "/ip dhcp-client")
|
|
XCTAssertEqual(commands[0].operation, .add)
|
|
XCTAssertEqual(commands[0].arguments["interface"], "ether1")
|
|
}
|
|
|
|
func testWanStaticIPCommandsIncludeRouteOnlyWhenGatewayGiven() {
|
|
var config = WanConfig(interfaceName: "ether1", mode: .staticIP)
|
|
config.staticAddress = "203.0.113.5/24"
|
|
|
|
XCTAssertEqual(config.buildCommands().count, 1)
|
|
|
|
config.staticGateway = "203.0.113.1"
|
|
let commands = config.buildCommands()
|
|
|
|
XCTAssertEqual(commands.count, 2)
|
|
XCTAssertEqual(commands[0].arguments["address"], "203.0.113.5/24")
|
|
XCTAssertEqual(commands[1].arguments["gateway"], "203.0.113.1")
|
|
}
|
|
|
|
func testWanPppoeCommand() {
|
|
var config = WanConfig(interfaceName: "ether1", mode: .pppoe)
|
|
config.pppoeUsername = "user@isp"
|
|
config.pppoePassword = "secret"
|
|
|
|
let commands = config.buildCommands()
|
|
|
|
XCTAssertEqual(commands.count, 1)
|
|
XCTAssertEqual(commands[0].menuPath, "/interface pppoe-client")
|
|
XCTAssertEqual(commands[0].arguments["user"], "user@isp")
|
|
XCTAssertEqual(commands[0].arguments["password"], "secret")
|
|
}
|
|
|
|
func testLanDhcpCommandsCoverAddressPoolServerAndNetwork() {
|
|
// Address fields default to "" now (Nutzerwunsch, 2026-09-16: fields start empty,
|
|
// showing only the format example) — set explicitly here so this test keeps verifying
|
|
// the command-building logic itself, not incidentally the model's old default values.
|
|
var config = LanDhcpConfig()
|
|
config.networkAddress = "192.168.88.0/24"
|
|
config.routerAddress = "192.168.88.1/24"
|
|
config.poolRangeStart = "192.168.88.10"
|
|
config.poolRangeEnd = "192.168.88.254"
|
|
config.dnsServers = "192.168.88.1"
|
|
let commands = config.buildCommands()
|
|
|
|
XCTAssertEqual(commands.count, 6)
|
|
XCTAssertEqual(commands[0].menuPath, "/ip address")
|
|
XCTAssertEqual(commands[1].menuPath, "/ip pool")
|
|
XCTAssertEqual(commands[2].menuPath, "/ip dhcp-server")
|
|
XCTAssertEqual(commands[3].menuPath, "/ip dhcp-server network")
|
|
XCTAssertEqual(commands[3].arguments["gateway"], "192.168.88.1")
|
|
XCTAssertEqual(commands[4].menuPath, "/interface list")
|
|
XCTAssertEqual(commands[4].arguments["name"], "LAN")
|
|
XCTAssertEqual(commands[5].menuPath, "/interface list member")
|
|
XCTAssertEqual(commands[5].arguments["list"], "LAN")
|
|
XCTAssertEqual(commands[5].arguments["interface"], "bridge")
|
|
}
|
|
|
|
func testLanDhcpCommandsDetachInterfaceFromBridgeWhenNotDefaultBridge() {
|
|
var config = LanDhcpConfig()
|
|
config.interfaceName = "ether4"
|
|
let commands = config.buildCommands()
|
|
|
|
XCTAssertEqual(commands.count, 7)
|
|
XCTAssertEqual(commands[0].menuPath, "/interface bridge port")
|
|
XCTAssertEqual(commands[0].operation, .remove(matchField: "interface", matchValue: "ether4"))
|
|
XCTAssertEqual(commands[1].menuPath, "/ip address")
|
|
}
|
|
|
|
func testCliLineRendersEmptyValueAsExplicitEmptyQuotes() {
|
|
let command = RouterOSCommand.set(
|
|
menuPath: "/ip route",
|
|
restPath: "ip/route",
|
|
matchField: ".id",
|
|
matchValue: "*1",
|
|
arguments: ["comment": ""],
|
|
summary: "test"
|
|
)
|
|
|
|
XCTAssertEqual(command.cliLine, "/ip route set [find .id=*1] comment=\"\"")
|
|
}
|
|
|
|
func testCliLineRendersSortedQuotedArgumentsForAdd() {
|
|
let command = RouterOSCommand.add(
|
|
menuPath: "/interface pppoe-client",
|
|
restPath: "interface/pppoe-client",
|
|
arguments: ["user": "user@isp", "password": "a secret"],
|
|
summary: "test"
|
|
)
|
|
|
|
XCTAssertEqual(command.cliLine, "/interface pppoe-client add password=\"a secret\" user=user@isp")
|
|
}
|
|
|
|
func testCliLineRendersFindLookupForSet() {
|
|
let command = RouterOSCommand.set(
|
|
menuPath: "/interface wireless",
|
|
restPath: "interface/wireless",
|
|
matchField: "name",
|
|
matchValue: "wlan1",
|
|
arguments: ["ssid": "Home"],
|
|
summary: "test"
|
|
)
|
|
|
|
XCTAssertEqual(command.cliLine, "/interface wireless set [find name=wlan1] ssid=Home")
|
|
}
|
|
|
|
func testCliLineRendersFindLookupForAction() {
|
|
let command = RouterOSCommand.action(
|
|
menuPath: "/ip dhcp-server lease",
|
|
restPath: "ip/dhcp-server/lease",
|
|
name: "make-static",
|
|
matchField: ".id",
|
|
matchValue: "*7",
|
|
summary: "test"
|
|
)
|
|
|
|
XCTAssertEqual(command.cliLine, "/ip dhcp-server lease make-static [find .id=*7]")
|
|
}
|
|
}
|