test(macos): cover control/camera disabled paths
parent
7d4c8ef6b2
commit
42645a7e0a
|
|
@ -0,0 +1,21 @@
|
||||||
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
@testable import Clawdis
|
||||||
|
|
||||||
|
@Suite
|
||||||
|
struct AgentIdentityTests {
|
||||||
|
@Test
|
||||||
|
func isEmptyTreatsWhitespaceAsEmpty() {
|
||||||
|
#expect(AgentIdentity(name: " ", theme: "\n", emoji: "\t").isEmpty == true)
|
||||||
|
#expect(AgentIdentity(name: "Pi", theme: "", emoji: "").isEmpty == false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
func emojiSuggestMatchesKnownThemes() {
|
||||||
|
#expect(AgentIdentityEmoji.suggest(theme: "") == "🦞")
|
||||||
|
#expect(AgentIdentityEmoji.suggest(theme: "shark") == "🦈")
|
||||||
|
#expect(AgentIdentityEmoji.suggest(theme: " Octopus helper ") == "🐙")
|
||||||
|
#expect(AgentIdentityEmoji.suggest(theme: "unknown") == "🦞")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -5,6 +5,28 @@ import Testing
|
||||||
|
|
||||||
@Suite(.serialized)
|
@Suite(.serialized)
|
||||||
struct ControlRequestHandlerTests {
|
struct ControlRequestHandlerTests {
|
||||||
|
private static func withDefaultOverride<T>(
|
||||||
|
_ key: String,
|
||||||
|
value: Any?,
|
||||||
|
operation: () async throws -> T) async rethrows -> T
|
||||||
|
{
|
||||||
|
let defaults = UserDefaults.standard
|
||||||
|
let previous = defaults.object(forKey: key)
|
||||||
|
if let value {
|
||||||
|
defaults.set(value, forKey: key)
|
||||||
|
} else {
|
||||||
|
defaults.removeObject(forKey: key)
|
||||||
|
}
|
||||||
|
defer {
|
||||||
|
if let previous {
|
||||||
|
defaults.set(previous, forKey: key)
|
||||||
|
} else {
|
||||||
|
defaults.removeObject(forKey: key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return try await operation()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
func statusReturnsReadyWhenNotPaused() async throws {
|
func statusReturnsReadyWhenNotPaused() async throws {
|
||||||
let defaults = UserDefaults.standard
|
let defaults = UserDefaults.standard
|
||||||
|
|
@ -58,5 +80,94 @@ struct ControlRequestHandlerTests {
|
||||||
#expect(res.ok == false)
|
#expect(res.ok == false)
|
||||||
#expect(res.message == "clawdis paused")
|
#expect(res.message == "clawdis paused")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
func agentRejectsEmptyMessage() async throws {
|
||||||
|
let res = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
||||||
|
try await ControlRequestHandler.process(request: .agent(
|
||||||
|
message: " ",
|
||||||
|
thinking: nil,
|
||||||
|
session: nil,
|
||||||
|
deliver: false,
|
||||||
|
to: nil))
|
||||||
|
}
|
||||||
|
#expect(res.ok == false)
|
||||||
|
#expect(res.message == "message empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
func runShellEchoReturnsPayload() async throws {
|
||||||
|
let res = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
||||||
|
try await ControlRequestHandler.process(request: .runShell(
|
||||||
|
command: ["echo", "hello"],
|
||||||
|
cwd: nil,
|
||||||
|
env: nil,
|
||||||
|
timeoutSec: nil,
|
||||||
|
needsScreenRecording: false))
|
||||||
|
}
|
||||||
|
#expect(res.ok == true)
|
||||||
|
#expect(String(data: res.payload ?? Data(), encoding: .utf8) == "hello\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
func cameraRequestsReturnDisabledWhenCameraDisabled() async throws {
|
||||||
|
let snap = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
||||||
|
try await Self.withDefaultOverride(cameraEnabledKey, value: false) {
|
||||||
|
try await ControlRequestHandler.process(request: .cameraSnap(
|
||||||
|
facing: nil,
|
||||||
|
maxWidth: nil,
|
||||||
|
quality: nil,
|
||||||
|
outPath: nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#expect(snap.ok == false)
|
||||||
|
#expect(snap.message == "Camera disabled by user")
|
||||||
|
|
||||||
|
let clip = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
||||||
|
try await Self.withDefaultOverride(cameraEnabledKey, value: false) {
|
||||||
|
try await ControlRequestHandler.process(request: .cameraClip(
|
||||||
|
facing: nil,
|
||||||
|
durationMs: nil,
|
||||||
|
includeAudio: true,
|
||||||
|
outPath: nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#expect(clip.ok == false)
|
||||||
|
#expect(clip.message == "Camera disabled by user")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
func canvasRequestsReturnDisabledWhenCanvasDisabled() async throws {
|
||||||
|
let show = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
||||||
|
try await Self.withDefaultOverride(canvasEnabledKey, value: false) {
|
||||||
|
try await ControlRequestHandler.process(request: .canvasShow(session: "s", path: nil, placement: nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#expect(show.ok == false)
|
||||||
|
#expect(show.message == "Canvas disabled by user")
|
||||||
|
|
||||||
|
let goto = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
||||||
|
try await Self.withDefaultOverride(canvasEnabledKey, value: false) {
|
||||||
|
try await ControlRequestHandler.process(request: .canvasGoto(session: "s", path: "/tmp", placement: nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#expect(goto.ok == false)
|
||||||
|
#expect(goto.message == "Canvas disabled by user")
|
||||||
|
|
||||||
|
let eval = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
||||||
|
try await Self.withDefaultOverride(canvasEnabledKey, value: false) {
|
||||||
|
try await ControlRequestHandler.process(request: .canvasEval(session: "s", javaScript: "1+1"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#expect(eval.ok == false)
|
||||||
|
#expect(eval.message == "Canvas disabled by user")
|
||||||
|
|
||||||
|
let snap = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
||||||
|
try await Self.withDefaultOverride(canvasEnabledKey, value: false) {
|
||||||
|
try await ControlRequestHandler.process(request: .canvasSnapshot(session: "s", outPath: nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#expect(snap.ok == false)
|
||||||
|
#expect(snap.message == "Canvas disabled by user")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
@testable import Clawdis
|
||||||
|
|
||||||
|
@Suite
|
||||||
|
struct ScreenshotSizeTests {
|
||||||
|
@Test
|
||||||
|
func readPNGSizeReturnsDimensions() throws {
|
||||||
|
let pngBase64 =
|
||||||
|
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+WZxkAAAAASUVORK5CYII="
|
||||||
|
let data = try #require(Data(base64Encoded: pngBase64))
|
||||||
|
let size = ScreenshotSize.readPNGSize(data: data)
|
||||||
|
#expect(size?.width == 1)
|
||||||
|
#expect(size?.height == 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
func readPNGSizeRejectsNonPNGData() {
|
||||||
|
#expect(ScreenshotSize.readPNGSize(data: Data("nope".utf8)) == nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue