test: expand menu and node coverage

This commit is contained in:
Peter Steinberger
2025-12-24 17:42:24 +01:00
parent deec315f6a
commit 49e466dd40
9 changed files with 272 additions and 11 deletions

View File

@@ -503,3 +503,40 @@ enum BridgePairingApprover {
}
}
}
#if DEBUG
extension BridgeServer {
func exerciseForTesting() async {
let conn = NWConnection(to: .hostPort(host: "127.0.0.1", port: 22), using: .tcp)
let handler = BridgeConnectionHandler(connection: conn, logger: self.logger)
self.connections["node-1"] = handler
self.nodeInfoById["node-1"] = BridgeNodeInfo(
nodeId: "node-1",
displayName: "Node One",
platform: "macOS",
version: "1.0.0",
deviceFamily: "Mac",
modelIdentifier: "MacBookPro18,1",
remoteAddress: "127.0.0.1",
caps: ["chat", "voice"])
_ = self.connectedNodeIds()
_ = self.connectedNodes()
self.handleListenerState(.ready)
self.handleListenerState(.failed(NWError.posix(.ECONNREFUSED)))
self.handleListenerState(.waiting(NWError.posix(.ETIMEDOUT)))
self.handleListenerState(.cancelled)
self.handleListenerState(.setup)
let subscribe = BridgeEventFrame(event: "chat.subscribe", payloadJSON: "{\"sessionKey\":\"main\"}")
await self.handleEvent(nodeId: "node-1", evt: subscribe)
let unsubscribe = BridgeEventFrame(event: "chat.unsubscribe", payloadJSON: "{\"sessionKey\":\"main\"}")
await self.handleEvent(nodeId: "node-1", evt: unsubscribe)
let invalid = BridgeRPCRequest(id: "req-1", method: "invalid.method", paramsJSON: nil)
_ = await self.handleRequest(nodeId: "node-1", req: invalid)
}
}
#endif

View File

@@ -19,6 +19,9 @@ final class MenuSessionsInjector: NSObject, NSMenuDelegate {
private var cachedErrorText: String?
private var cacheUpdatedAt: Date?
private let refreshIntervalSeconds: TimeInterval = 12
#if DEBUG
private var testControlChannelConnected: Bool?
#endif
func install(into statusItem: NSStatusItem) {
self.statusItem = statusItem
@@ -157,6 +160,9 @@ final class MenuSessionsInjector: NSObject, NSMenuDelegate {
}
private var isControlChannelConnected: Bool {
#if DEBUG
if let override = self.testControlChannelConnected { return override }
#endif
if case .connected = ControlChannel.shared.state { return true }
return false
}
@@ -467,6 +473,24 @@ final class MenuSessionsInjector: NSObject, NSMenuDelegate {
}
}
#if DEBUG
extension MenuSessionsInjector {
func setTestingControlChannelConnected(_ connected: Bool?) {
self.testControlChannelConnected = connected
}
func setTestingSnapshot(_ snapshot: SessionStoreSnapshot?, errorText: String? = nil) {
self.cachedSnapshot = snapshot
self.cachedErrorText = errorText
self.cacheUpdatedAt = Date()
}
func injectForTesting(into menu: NSMenu) {
self.inject(into: menu)
}
}
#endif
private final class HighlightedMenuItemHostView: NSView {
private let baseView: AnyView
private let hosting: NSHostingView<AnyView>

View File

@@ -653,3 +653,40 @@ final class NodePairingApprovalPrompter {
self.updateReconcileLoop()
}
}
#if DEBUG
@MainActor
extension NodePairingApprovalPrompter {
static func exerciseForTesting() async {
let prompter = NodePairingApprovalPrompter()
let pending = PendingRequest(
requestId: "req-1",
nodeId: "node-1",
displayName: "Node One",
platform: "macos",
version: "1.0.0",
remoteIp: "127.0.0.1",
isRepair: false,
silent: true,
ts: 1_700_000_000_000)
let paired = PairedNode(
nodeId: "node-1",
approvedAtMs: 1_700_000_000_000,
displayName: "Node One",
platform: "macOS",
version: "1.0.0",
remoteIp: "127.0.0.1")
let list = PairingList(pending: [pending], paired: [paired])
_ = Self.describe(pending)
_ = Self.prettyIP(pending.remoteIp)
_ = Self.prettyPlatform(pending.platform)
_ = prompter.inferResolution(for: pending, list: list)
prompter.queue = [pending]
_ = prompter.shouldPoll
_ = await prompter.trySilentApproveIfPossible(pending)
prompter.queue.removeAll()
}
}
#endif