Files
openclaw/apps/macos/Tests/OpenClawIPCTests/ExecApprovalPromptLayoutTests.swift
Jesse Merhi 42f0822bfa fix(exec): hide unavailable durable approval actions (#86359)
* fix(macos): align ask always approval actions

* fix(macos): harden approval prompt decisions

* fix(ui): satisfy approval action lint

* fix(infra): settle jsonl sockets on close

* fix(ui): explain unavailable durable approvals

* test(macos): document legacy approval fallback
2026-05-27 14:58:11 +10:00

149 lines
5.4 KiB
Swift

import AppKit
import Testing
@testable import OpenClaw
@Suite(.serialized)
@MainActor
struct ExecApprovalPromptLayoutTests {
@Test func `allowed decisions omit durable approval even when ask allows it`() {
let decisions = ExecApprovalsPromptPresenter.allowedPromptDecisions(
ExecApprovalPromptRequest(
command: "/bin/sh -lc pwd",
cwd: "/Users/example/projects/openclaw",
host: "node",
security: "full",
ask: "on-miss",
agentId: "main",
resolvedPath: "/bin/sh",
sessionKey: "session-1",
allowedDecisions: [.allowOnce, .deny]))
#expect(decisions == [.allowOnce, .deny])
}
@Test func `ask always prompts omit durable approval when decisions are omitted`() {
let decisions = ExecApprovalsPromptPresenter.allowedPromptDecisions(
ExecApprovalPromptRequest(
command: "/bin/sh -lc pwd",
cwd: "/Users/example/projects/openclaw",
host: "node",
security: "full",
ask: "always",
agentId: "main",
resolvedPath: "/bin/sh",
sessionKey: "session-1"))
#expect(decisions == [.allowOnce, .deny])
}
@Test func `ask on miss prompts keep durable approval when decisions are omitted`() {
let decisions = ExecApprovalsPromptPresenter.allowedPromptDecisions(
ExecApprovalPromptRequest(
command: "/bin/sh -lc pwd",
cwd: "/Users/example/projects/openclaw",
host: "node",
security: "full",
ask: "on-miss",
agentId: "main",
resolvedPath: "/bin/sh",
sessionKey: "session-1"))
#expect(decisions == [.allowOnce, .allowAlways, .deny])
}
@Test func `legacy prompts keep durable approval when policy fields are omitted`() {
let decisions = ExecApprovalsPromptPresenter.allowedPromptDecisions(
ExecApprovalPromptRequest(
command: "/bin/sh -lc pwd",
cwd: "/Users/example/projects/openclaw",
host: "node",
security: "full",
agentId: "main",
resolvedPath: "/bin/sh",
sessionKey: "session-1"))
#expect(decisions == [.allowOnce, .allowAlways, .deny])
}
@Test func `unknown ask prompts keep legacy durable approval when decisions are omitted`() {
let decisions = ExecApprovalsPromptPresenter.allowedPromptDecisions(
ExecApprovalPromptRequest(
command: "/bin/sh -lc pwd",
cwd: "/Users/example/projects/openclaw",
host: "node",
security: "full",
ask: "unexpected",
agentId: "main",
resolvedPath: "/bin/sh",
sessionKey: "session-1"))
#expect(decisions == [.allowOnce, .allowAlways, .deny])
}
@Test func `approval request decodes valid allowed decisions only`() throws {
let data = """
{
"command": "/bin/sh -lc pwd",
"ask": "on-miss",
"allowedDecisions": ["allow-once", "bad", "deny", 3]
}
""".data(using: .utf8)!
let request = try JSONDecoder().decode(ExecApprovalPromptRequest.self, from: data)
#expect(request.allowedDecisions == [.allowOnce, .deny])
}
@Test func `approval request falls back when allowed decisions has wrong shape`() throws {
let data = """
{
"command": "/bin/sh -lc pwd",
"ask": "always",
"allowedDecisions": "allow-once"
}
""".data(using: .utf8)!
let request = try JSONDecoder().decode(ExecApprovalPromptRequest.self, from: data)
#expect(ExecApprovalsPromptPresenter.allowedPromptDecisions(request) == [.allowOnce, .deny])
}
@Test func `modal close does not synthesize deny when deny is unavailable`() {
let closeResponse = NSApplication.ModalResponse(rawValue: 0)
let withoutDeny = ExecApprovalsPromptPresenter.decision(
forModalResponse: closeResponse,
decisions: [.allowOnce])
let withDeny = ExecApprovalsPromptPresenter.decision(
forModalResponse: closeResponse,
decisions: [.allowOnce, .deny])
#expect(withoutDeny == nil)
#expect(withDeny == .deny)
}
@Test func `accessory view reserves nonzero alert layout space`() {
let accessory = ExecApprovalsPromptPresenter.buildAccessoryView(
ExecApprovalPromptRequest(
command: "/bin/sh -lc \"hostname; uptime; echo '---'\"",
cwd: "/Users/example/projects/openclaw",
host: "node",
security: "allowlist",
ask: "on-miss",
agentId: "main",
resolvedPath: "/bin/sh",
sessionKey: "session-1"))
#expect(accessory.frame.width >= 380)
#expect(accessory.frame.height >= 160)
let alert = NSAlert()
alert.messageText = "Allow this command?"
alert.informativeText = "Review the command details before allowing."
alert.accessoryView = accessory
#expect(alert.accessoryView?.frame.width == accessory.frame.width)
#expect(alert.accessoryView?.frame.height == accessory.frame.height)
}
}