Files
openclaw/apps/ios/Tests/OpenClawAppDelegateTests.swift
PollyBot13 a320f775f0 fix(ios): defer QR pairing after scanner dismissal (#99572)
* fix(ios): defer QR pairing after scanner dismissal

* fix(ios): process QR pairing after scanner dismissal

* fix(ios): harden QR scanner handoff

* fix(ios): give QR scanner dismissal more time

* fix(ios): keep onboarding open for QR trust prompt

* fix(ios): keep QR trust prompt owned by onboarding

* fix(ios): recover operator pairing after QR bootstrap

* fix(ios): cancel stale QR scanner handoffs

Co-authored-by: PollyBot13 <pollybot13@gmail.com>

* fix(ios): defer QR setup until onboarding closes

* fix(ios): keep QR setup links with visible settings

* fix(ios): consume setup links during onboarding

* fix(ios): handle setup links during onboarding launch

* fix(ios): route setup links through active onboarding

* fix(ios): harden QR gateway handoff

* fix(ios): cancel superseded gateway attempts

* fix(ios): serialize scanner result delivery

* fix(ios): prevent stale gateway reconnects

* fix(ios): serialize gateway target handoff

* fix(ios): disable stale gateway relaunch route

* fix(ios): await staged bootstrap reset

* test(ios): bound gateway reset handoff

* fix(ios): preserve explicit gateway handoff

* fix(ios): harden gateway lifecycle ownership

* chore(ios): sync native i18n inventory

* test(ios): align gateway ownership assertions

* refactor(ios): remove superseded gateway helpers

* fix(ios): keep gateway auth route scoped

* fix(ios): restore gateway target review state

* fix(protocol): refresh Swift plugin approval model

* test(ios): isolate state directory overrides

* fix(ios): preserve watch alerts across gateway switches

* fix(ios): bind deferred work to gateway ownership

* docs(changelog): credit iOS gateway handoff fix

* chore(i18n): sync native app inventory

* test(ios): remove unused Watch approval hooks

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 12:31:53 -07:00

90 lines
3.3 KiB
Swift

import Foundation
import OpenClawKit
import Testing
import UIKit
@testable import OpenClaw
@Suite(.serialized) struct OpenClawAppDelegateTests {
@Test @MainActor func `resolves registry model before view task assigns delegate model`() {
let registryModel = NodeAppModel()
OpenClawAppModelRegistry.appModel = registryModel
defer { OpenClawAppModelRegistry.appModel = nil }
let delegate = OpenClawAppDelegate()
#expect(delegate._test_resolvedAppModel() === registryModel)
}
@Test @MainActor func `prefers explicit delegate model over registry fallback`() {
let registryModel = NodeAppModel()
let explicitModel = NodeAppModel()
OpenClawAppModelRegistry.appModel = registryModel
defer { OpenClawAppModelRegistry.appModel = nil }
let delegate = OpenClawAppDelegate()
delegate.appModel = explicitModel
#expect(delegate._test_resolvedAppModel() === explicitModel)
}
@Test @MainActor func `derives background refresh task identifier from app bundle identifier`() {
let delegate = OpenClawAppDelegate()
let bundleIdentifier = Bundle.main.bundleIdentifier ?? "ai.openclawfoundation.app.tests"
#expect(delegate._test_wakeRefreshTaskIdentifier() == "\(bundleIdentifier).bgrefresh")
}
@Test @MainActor func `stages a gateway URL when the model is ready`() async throws {
OpenClawAppModelRegistry.appModel = nil
defer { OpenClawAppModelRegistry.appModel = nil }
let model = NodeAppModel()
let delegate = OpenClawAppDelegate()
delegate.appModel = model
let url = try #require(URL(
string: "openclaw://gateway?host=gateway.example.com&port=443&tls=1&token=tok"))
#expect(delegate.application(UIApplication.shared, open: url))
let link = await Self.waitForGatewaySetup(in: model)
#expect(link?.host == "gateway.example.com")
#expect(link?.port == 443)
#expect(link?.tls == true)
#expect(link?.token == "tok")
}
@Test @MainActor func `replays a gateway URL received before the model is ready`() async throws {
OpenClawAppModelRegistry.appModel = nil
defer { OpenClawAppModelRegistry.appModel = nil }
let delegate = OpenClawAppDelegate()
let url = try #require(URL(
string: "openclaw://gateway?host=gateway.example.com&port=443&tls=1&token=tok"))
#expect(delegate.application(UIApplication.shared, open: url))
let model = NodeAppModel()
delegate.appModel = model
let link = await Self.waitForGatewaySetup(in: model)
#expect(link?.host == "gateway.example.com")
#expect(link?.token == "tok")
}
@Test @MainActor func `rejects an invalid URL`() throws {
let delegate = OpenClawAppDelegate()
let url = try #require(URL(string: "https://example.com/gateway"))
#expect(!delegate.application(UIApplication.shared, open: url))
}
@MainActor
private static func waitForGatewaySetup(in model: NodeAppModel) async -> GatewayConnectDeepLink? {
for _ in 0..<20 {
if model.gatewaySetupRequestID > 0 {
return model.consumePendingGatewaySetupLink()
}
await Task.yield()
}
return nil
}
}