Files
RouterOS/RouterOSAssistantTests/RouterOSCommandBuilderTests.swift
T
KayandClaude Sonnet 5 fc3b2ca039 M8: Netzwerk-Isolation live verifiziert (manuell + über den Wizard)
Isolation zuerst manuell per SSH nachgebaut (ether5), danach über den
App-Wizard (Experte-Modus, ether4), um die eigentliche Abnahme-
Bedingung ("kompletter Wizard-Durchlauf") zu erfüllen. Dabei drei
App-Bugs gefunden und gefixt:

- Bug 22: neues LAN-/VLAN-Interface wurde nie der defconf-Interface-
  Liste "LAN" hinzugefügt, wodurch DNS-Anfragen an den Router selbst
  blockiert blieben (Werks-Firewall droppt Input von allem außerhalb
  dieser Liste).
- Bug 23: ein voller Wizard-Durchlauf gegen einen bereits konfigurierten
  Router brach am ersten nicht-idempotenten Add-Befehl ab
  (/ip address, /ip pool, /ip dhcp-server, /ip dhcp-server network).
- Bug 24: ein als eigenes isoliertes Netz konfiguriertes Interface
  blieb Bridge-"Slave" (Werks-Bridging), wodurch RouterOS die
  generierten Isolationsregeln selbst als ungültig verwarf.

Alle drei in DhcpServerCommandBuilder/SetupViewModel gefixt, 52 Unit-
Tests grün, Isolation+DNS+Internet am echten Gerät bestätigt. M8 auf
live verifiziert gesetzt. Nebenbei zwei veraltete Doku-Stellen zum
Gitea-Remote korrigiert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
2026-09-15 10:28:09 +02:00

107 lines
4.0 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() {
let config = LanDhcpConfig()
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 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]")
}
}