Files
openclaw/apps/macos/Tests/OpenClawIPCTests/DeepLinkAgentPolicyTests.swift
Peter Steinberger 57e5ab7a87 fix(apps): show native gateway and notification failures (#125909)
* fix(apps): surface native action failures

Make iOS gateway reconnect attempts return visible closed outcomes, route macOS gateway deep links through primary setup confirmation, and expose pending/sent/error notification test results across native and Dashboard settings.

* chore(apps): refresh native i18n inventory

* test(macos): isolate gateway cancel state

* fix(ui): accept permission-only notification status

* test(gateway): drain accepted agent run before fixture reset

* fix(ui): notify clients after service worker claim

* test(gateway): wait for accepted root work to drain

* test(ui): isolate widget theme observer window

* test(ui): await durable attachment draft before teardown

* test(agents): use race-safe MCP process cleanup

* test(ui): await cloud startup runtime before error probe

* test(ui): align startup and teardown probes with current owners
2026-08-18 20:15:52 -07:00

111 lines
4.0 KiB
Swift

import Foundation
import OpenClawKit
import Testing
@testable import OpenClaw
struct DeepLinkAgentPolicyTests {
@Test func `validate message for handle rejects too long when unkeyed`() {
let msg = String(repeating: "a", count: DeepLinkAgentPolicy.maxUnkeyedConfirmChars + 1)
let res = DeepLinkAgentPolicy.validateMessageForHandle(message: msg, allowUnattended: false)
switch res {
case let .failure(error):
#expect(
error == .messageTooLongForConfirmation(
max: DeepLinkAgentPolicy.maxUnkeyedConfirmChars,
actual: DeepLinkAgentPolicy.maxUnkeyedConfirmChars + 1))
case .success:
Issue.record("expected failure, got success")
}
}
@Test func `validate message for handle allows too long when keyed`() {
let msg = String(repeating: "a", count: DeepLinkAgentPolicy.maxUnkeyedConfirmChars + 1)
let res = DeepLinkAgentPolicy.validateMessageForHandle(message: msg, allowUnattended: true)
switch res {
case .success:
break
case let .failure(error):
Issue.record("expected success, got failure: \(error)")
}
}
@Test func `effective delivery ignores delivery fields when unkeyed`() {
let link = AgentDeepLink(
message: "Hello",
sessionKey: "s",
thinking: "low",
deliver: true,
to: "+15551234567",
channel: "whatsapp",
timeoutSeconds: 10,
key: nil)
let res = DeepLinkAgentPolicy.effectiveDelivery(link: link, allowUnattended: false)
#expect(res.deliver == false)
#expect(res.to == nil)
#expect(res.channel == .last)
}
@Test func `effective delivery honors deliver for deliverable channels when keyed`() {
let link = AgentDeepLink(
message: "Hello",
sessionKey: "s",
thinking: "low",
deliver: true,
to: " +15551234567 ",
channel: "whatsapp",
timeoutSeconds: 10,
key: "secret")
let res = DeepLinkAgentPolicy.effectiveDelivery(link: link, allowUnattended: true)
#expect(res.deliver == true)
#expect(res.to == "+15551234567")
#expect(res.channel == .whatsapp)
}
@Test func `effective delivery still blocks web chat delivery when keyed`() {
let link = AgentDeepLink(
message: "Hello",
sessionKey: "s",
thinking: "low",
deliver: true,
to: "+15551234567",
channel: "webchat",
timeoutSeconds: 10,
key: "secret")
let res = DeepLinkAgentPolicy.effectiveDelivery(link: link, allowUnattended: true)
#expect(res.deliver == false)
#expect(res.channel == .webchat)
}
}
@MainActor
struct DeepLinkGatewayRoutingTests {
@Test func `valid gateway route is forwarded once even while app is paused`() async throws {
let state = AppStateStore.shared
let wasPaused = state.isPaused
defer { state.isPaused = wasPaused }
state.isPaused = true
var routed: [GatewayConnectDeepLink] = []
let handler = DeepLinkHandler(gatewaySetup: { routed.append($0) })
let url = try #require(URL(
string: "openclaw://gateway?host=gateway.example&port=443&tls=1&token=route-token"))
await handler.handle(url: url)
#expect(routed.count == 1)
#expect(routed.first?.host == "gateway.example")
}
@Test func `invalid route metadata omits query credentials`() throws {
let token = "fixture-route-token"
let password = "fixture-route-password"
let url = try #require(URL(
string: "openclaw://gateway?host=attacker.example&tls=0&token=\(token)&password=\(password)"))
let metadata = DeepLinkHandler.invalidRouteMetadata(url)
#expect(!metadata.contains(token))
#expect(!metadata.contains(password))
#expect(!metadata.contains("?"))
}
}