import Testing @testable import OpenClaw @Suite(.serialized) @MainActor struct AppStateRemoteConfigTests { @Test func updatedRemoteGatewayConfigSetsTrimmedToken() { let remote = AppState._testUpdatedRemoteGatewayConfig( current: [:], transport: .ssh, remoteUrl: "", remoteHost: "gateway.example", remoteTarget: "alice@gateway.example", remoteIdentity: "/tmp/id_ed25519", remoteToken: " secret-token ", remoteTokenDirty: true) #expect(remote["token"] as? String == "secret-token") } @Test func updatedRemoteGatewayConfigClearsTokenWhenBlank() { let remote = AppState._testUpdatedRemoteGatewayConfig( current: ["token": "old-token"], transport: .direct, remoteUrl: "wss://gateway.example", remoteHost: nil, remoteTarget: "", remoteIdentity: "", remoteToken: " ", remoteTokenDirty: true) #expect((remote["token"] as? String) == nil) } @Test func syncedGatewayRootPreservesObjectTokenAcrossModeAndTransportChangesWhenUntouched() { let initialRoot: [String: Any] = [ "gateway": [ "mode": "remote", "remote": [ "transport": "direct", "url": "wss://old-gateway.example", "token": [ "$secretRef": "gateway-token", // pragma: allowlist secret ], ], ], ] let sshRoot = AppState._testSyncedGatewayRoot( currentRoot: initialRoot, connectionMode: .remote, remoteTransport: .ssh, remoteTarget: "alice@gateway.example", remoteIdentity: "", remoteUrl: "", remoteToken: "", remoteTokenDirty: false) let sshRemote = (sshRoot["gateway"] as? [String: Any])?["remote"] as? [String: Any] #expect((sshRemote?["token"] as? [String: String])?["$secretRef"] == "gateway-token") // pragma: allowlist secret let localRoot = AppState._testSyncedGatewayRoot( currentRoot: sshRoot, connectionMode: .local, remoteTransport: .ssh, remoteTarget: "", remoteIdentity: "", remoteUrl: "", remoteToken: "", remoteTokenDirty: false) let localGateway = localRoot["gateway"] as? [String: Any] let localRemote = localGateway?["remote"] as? [String: Any] #expect(localGateway?["mode"] as? String == "local") #expect((localRemote?["token"] as? [String: String])?["$secretRef"] == "gateway-token") // pragma: allowlist secret } @Test func updatedRemoteGatewayConfigReplacesObjectTokenWhenUserEntersPlaintext() { let remote = AppState._testUpdatedRemoteGatewayConfig( current: [ "token": [ "$secretRef": "gateway-token", // pragma: allowlist secret ], ], transport: .direct, remoteUrl: "wss://gateway.example", remoteHost: nil, remoteTarget: "", remoteIdentity: "", remoteToken: " fresh-token ", remoteTokenDirty: true) #expect(remote["token"] as? String == "fresh-token") } @Test func updatedRemoteGatewayConfigClearsObjectTokenOnlyAfterExplicitEdit() { let current: [String: Any] = [ "token": [ "$secretRef": "gateway-token", // pragma: allowlist secret ], ] let preserved = AppState._testUpdatedRemoteGatewayConfig( current: current, transport: .direct, remoteUrl: "wss://gateway.example", remoteHost: nil, remoteTarget: "", remoteIdentity: "", remoteToken: "", remoteTokenDirty: false) #expect((preserved["token"] as? [String: String])?["$secretRef"] == "gateway-token") // pragma: allowlist secret let cleared = AppState._testUpdatedRemoteGatewayConfig( current: current, transport: .direct, remoteUrl: "wss://gateway.example", remoteHost: nil, remoteTarget: "", remoteIdentity: "", remoteToken: " ", remoteTokenDirty: true) #expect((cleared["token"] as? String) == nil) } }