Files
openclaw/apps/ios/Tests/GatewayStatusBuilderTests.swift
Peter Steinberger 3261667b73 fix(ios): keep reconnect errors visible (#105875)
* fix(ios): keep reconnect errors visible

* fix(ios): clear stale errors on gateway switch

* chore(ios): keep release notes in PR

* fix(ios): reset status when switching gateways

* fix(ios): retain errors through same-target reconnect

* fix(ios): unpause explicit pairing retries

* fix(ios): isolate retained reconnect errors

* chore(i18n): resync rebased native inventory

* fix(ios): separate reconnect display state
2026-07-13 02:11:26 -07:00

76 lines
3.2 KiB
Swift

import OpenClawKit
import Testing
@testable import OpenClaw
struct GatewayStatusBuilderTests {
@Test func `paused problem keeps error status`() {
let state = GatewayStatusBuilder.build(
gatewayServerName: nil,
lastGatewayProblem: GatewayConnectionProblem(
kind: .pairingRequired,
owner: .gateway,
title: "Pairing required",
message: "Approve this device before reconnecting.",
requestId: "req-123",
retryable: false,
pauseReconnect: true),
gatewayStatusText: "Reconnecting…")
#expect(state == .error)
}
@Test func `transient problem keeps error status while reconnecting`() {
let state = GatewayStatusBuilder.build(
gatewayServerName: nil,
lastGatewayProblem: GatewayConnectionProblem(
kind: .timeout,
owner: .network,
title: "Connection timed out",
message: "The gateway did not respond before the connection timed out.",
retryable: true,
pauseReconnect: false),
gatewayStatusText: "Reconnecting…")
#expect(state == .error)
}
@Test func `chat gateway pill labels match display state`() {
#expect(ChatProTab.gatewayPillTitle(state: .disconnected, isGatewayUsable: false) == "Offline")
#expect(ChatProTab.gatewayPillTitle(state: .connecting, isGatewayUsable: false) == "Connecting")
#expect(ChatProTab.gatewayPillTitle(state: .error, isGatewayUsable: false) == "Attention")
#expect(ChatProTab.gatewayPillTitle(state: .connected, isGatewayUsable: true) == "Connected")
#expect(ChatProTab.gatewayPillTitle(state: .connected, isGatewayUsable: false) == "Unavailable")
}
@Test func `chat agent badge rejects placeholder question mark`() {
#expect(ChatProTab.normalizedBadgeEmoji(" 🦞 ") == "🦞")
#expect(ChatProTab.normalizedBadgeEmoji("?") == nil)
#expect(ChatProTab.normalizedBadgeEmoji(" ") == nil)
#expect(ChatProTab.normalizedBadgeEmoji(nil) == nil)
#expect(ChatProTab.initialsBadge(for: "Agent Smith") == "AS")
}
@Test func `pinned attachment displays its captured gateway owner`() {
#expect(ChatProTab.presentationGatewayState(
current: .connected,
isAttachmentOwnerPinned: true,
capturedOwnerID: "gateway-a",
currentOwnerID: "gateway-b") == .disconnected)
#expect(ChatProTab.presentationGatewayState(
current: .connected,
isAttachmentOwnerPinned: true,
capturedOwnerID: "gateway-a",
currentOwnerID: "gateway-a") == .connected)
#expect(ChatProTab.presentationGatewayState(
current: .connected,
isAttachmentOwnerPinned: false,
capturedOwnerID: "gateway-a",
currentOwnerID: "gateway-b") == .connected)
}
@Test func `chat starter prompts stay stable and actionable`() {
#expect(ChatProTab.emptyAssistantPrompts.map(\.id) == ["summarize-status", "show-controls", "start-voice"])
#expect(ChatProTab.emptyAssistantPrompts.allSatisfy { !$0.title.isEmpty && !$0.prompt.isEmpty })
}
}