mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 12:26:38 -06:00
57e5ab7a87
* 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
71 lines
3.3 KiB
Swift
71 lines
3.3 KiB
Swift
import Foundation
|
|
import Testing
|
|
import UserNotifications
|
|
@testable import OpenClaw
|
|
|
|
@MainActor
|
|
struct DashboardNotificationsBridgeTests {
|
|
@Test func `parses notification requests`() {
|
|
#expect(DashboardWindowController.notificationsRequest(from: ["type": "status"]) == .status)
|
|
#expect(DashboardWindowController.notificationsRequest(
|
|
from: ["type": "request-permission"]) == .requestPermission)
|
|
#expect(DashboardWindowController.notificationsRequest(
|
|
from: ["type": "send-test"]) == .sendTest)
|
|
}
|
|
|
|
@Test func `rejects invalid notification requests`() {
|
|
#expect(DashboardWindowController.notificationsRequest(from: ["type": "unknown"]) == nil)
|
|
#expect(DashboardWindowController.notificationsRequest(from: "status") == nil)
|
|
}
|
|
|
|
@Test func `maps notification permission labels`() throws {
|
|
#expect(DashboardWindowController.notificationsPermissionLabel(for: .authorized) == "granted")
|
|
#expect(DashboardWindowController.notificationsPermissionLabel(for: .provisional) == "granted")
|
|
// Ephemeral (unavailable by name on macOS, raw value 4) cannot occur here
|
|
// and maps to notDetermined with the rest of the default branch.
|
|
let ephemeral = try #require(UNAuthorizationStatus(rawValue: 4))
|
|
#expect(DashboardWindowController.notificationsPermissionLabel(
|
|
for: ephemeral) == "notDetermined")
|
|
#expect(DashboardWindowController.notificationsPermissionLabel(for: .denied) == "denied")
|
|
#expect(DashboardWindowController.notificationsPermissionLabel(
|
|
for: .notDetermined) == "notDetermined")
|
|
}
|
|
|
|
@Test func `permission and test send outcome remain independent bridge facts`() {
|
|
let failed = DashboardWindowController.notificationsSnapshot(
|
|
permission: "granted",
|
|
testOutcome: .error("Open System Settings and try again."))
|
|
let refreshed = DashboardWindowController.notificationsSnapshot(
|
|
permission: "granted",
|
|
testOutcome: .error("Open System Settings and try again."))
|
|
|
|
#expect(failed.permission == "granted")
|
|
#expect(failed.test == .error("Open System Settings and try again."))
|
|
#expect(refreshed == failed)
|
|
}
|
|
|
|
@Test func `bridge exposes pending and queued test send states`() {
|
|
#expect(DashboardWindowController.notificationsSnapshot(
|
|
permission: "granted",
|
|
testOutcome: .pending).test == .pending)
|
|
#expect(DashboardWindowController.notificationsSnapshot(
|
|
permission: "granted",
|
|
testOutcome: .sent).test == .sent)
|
|
}
|
|
|
|
@Test func `bridge encodes closed wire states and error-only messages`() throws {
|
|
let pending = try self.testSnapshotJSON(.pending)
|
|
let error = try self.testSnapshotJSON(.error("Open System Settings and try again."))
|
|
|
|
#expect(pending["state"] as? String == "pending")
|
|
#expect(pending["message"] == nil)
|
|
#expect(error["state"] as? String == "error")
|
|
#expect(error["message"] as? String == "Open System Settings and try again.")
|
|
}
|
|
|
|
private func testSnapshotJSON(_ snapshot: TestNotificationOutcome) throws -> [String: Any] {
|
|
let data = try JSONEncoder().encode(snapshot)
|
|
return try #require(JSONSerialization.jsonObject(with: data) as? [String: Any])
|
|
}
|
|
}
|