mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-10 00:11:19 +00:00
test(android): cover discovery and startup gates (#102758)
* test(android): cover discovery and startup gates Co-authored-by: NianJiuZst <180004567+users.noreply.github.com> * test(android): keep startup gate tests keystore-free
This commit is contained in:
parent
64e80888d4
commit
411bf2ad4b
5 changed files with 144 additions and 26 deletions
|
|
@ -139,7 +139,7 @@
|
|||
},
|
||||
{
|
||||
"kind": "ui-state-text",
|
||||
"line": 138,
|
||||
"line": 143,
|
||||
"path": "apps/android/app/src/main/java/ai/openclaw/app/MainViewModel.kt",
|
||||
"source": "Searching…",
|
||||
"surface": "android",
|
||||
|
|
@ -147,7 +147,7 @@
|
|||
},
|
||||
{
|
||||
"kind": "ui-state-text",
|
||||
"line": 238,
|
||||
"line": 243,
|
||||
"path": "apps/android/app/src/main/java/ai/openclaw/app/MainViewModel.kt",
|
||||
"source": "Mic off",
|
||||
"surface": "android",
|
||||
|
|
@ -155,7 +155,7 @@
|
|||
},
|
||||
{
|
||||
"kind": "ui-state-text",
|
||||
"line": 248,
|
||||
"line": 253,
|
||||
"path": "apps/android/app/src/main/java/ai/openclaw/app/MainViewModel.kt",
|
||||
"source": "Off",
|
||||
"surface": "android",
|
||||
|
|
@ -379,7 +379,7 @@
|
|||
},
|
||||
{
|
||||
"kind": "ui-state-text",
|
||||
"line": 86,
|
||||
"line": 106,
|
||||
"path": "apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayDiscovery.kt",
|
||||
"source": "Searching…",
|
||||
"surface": "android",
|
||||
|
|
|
|||
|
|
@ -46,6 +46,11 @@ data class ChatDraft(
|
|||
val placement: ChatDraftPlacement,
|
||||
)
|
||||
|
||||
internal fun shouldStartRuntimeOnForeground(
|
||||
foreground: Boolean,
|
||||
onboardingCompleted: Boolean,
|
||||
): Boolean = foreground && onboardingCompleted
|
||||
|
||||
/**
|
||||
* UI-facing bridge that exposes NodeRuntime and preference state as Compose-friendly StateFlows.
|
||||
*/
|
||||
|
|
@ -298,7 +303,12 @@ class MainViewModel(
|
|||
*/
|
||||
fun setForeground(value: Boolean) {
|
||||
foreground = value
|
||||
if (value && prefs.onboardingCompleted.value) {
|
||||
if (
|
||||
shouldStartRuntimeOnForeground(
|
||||
foreground = value,
|
||||
onboardingCompleted = prefs.onboardingCompleted.value,
|
||||
)
|
||||
) {
|
||||
queueRuntimeStartup()
|
||||
}
|
||||
runtimeRef.value?.setForeground(value)
|
||||
|
|
|
|||
|
|
@ -62,6 +62,26 @@ private fun createContextDnsResolver(context: Context): DnsResolver = DnsResolve
|
|||
@Suppress("DEPRECATION")
|
||||
private fun createLegacyDnsResolver(): DnsResolver = DnsResolver.getInstance()
|
||||
|
||||
internal fun gatewayDiscoveryStatusText(
|
||||
localCount: Int,
|
||||
wideAreaRcode: Int?,
|
||||
wideAreaCount: Int,
|
||||
): String {
|
||||
val wide =
|
||||
when (wideAreaRcode) {
|
||||
null -> "Wide: ?"
|
||||
Rcode.NOERROR -> "Wide: $wideAreaCount"
|
||||
Rcode.NXDOMAIN -> "Wide: NXDOMAIN"
|
||||
else -> "Wide: ${Rcode.string(wideAreaRcode)}"
|
||||
}
|
||||
|
||||
return when {
|
||||
localCount == 0 && wideAreaRcode == null -> "Searching for gateways…"
|
||||
localCount == 0 -> wide
|
||||
else -> "Local: $localCount • $wide"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Watches local DNS-SD and optional wide-area DNS-SD for reachable OpenClaw gateways.
|
||||
*/
|
||||
|
|
@ -306,27 +326,12 @@ class GatewayDiscovery(
|
|||
_gateways.value =
|
||||
// Merge local and wide-area results deterministically for stable UI selection.
|
||||
(localById.values + unicastById.values).sortedBy { it.name.lowercase() }
|
||||
_statusText.value = buildStatusText()
|
||||
}
|
||||
|
||||
private fun buildStatusText(): String {
|
||||
val localCount = localById.size
|
||||
val wideRcode = lastWideAreaRcode
|
||||
val wideCount = lastWideAreaCount
|
||||
|
||||
val wide =
|
||||
when (wideRcode) {
|
||||
null -> "Wide: ?"
|
||||
Rcode.NOERROR -> "Wide: $wideCount"
|
||||
Rcode.NXDOMAIN -> "Wide: NXDOMAIN"
|
||||
else -> "Wide: ${Rcode.string(wideRcode)}"
|
||||
}
|
||||
|
||||
return when {
|
||||
localCount == 0 && wideRcode == null -> "Searching for gateways…"
|
||||
localCount == 0 -> "$wide"
|
||||
else -> "Local: $localCount • $wide"
|
||||
}
|
||||
_statusText.value =
|
||||
gatewayDiscoveryStatusText(
|
||||
localCount = localById.size,
|
||||
wideAreaRcode = lastWideAreaRcode,
|
||||
wideAreaCount = lastWideAreaCount,
|
||||
)
|
||||
}
|
||||
|
||||
private fun stableId(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
package ai.openclaw.app
|
||||
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class MainViewModelTest {
|
||||
@Test
|
||||
fun foregroundStartupRequiresForegroundAndCompletedOnboarding() {
|
||||
assertFalse(
|
||||
shouldStartRuntimeOnForeground(
|
||||
foreground = false,
|
||||
onboardingCompleted = true,
|
||||
),
|
||||
)
|
||||
assertFalse(
|
||||
shouldStartRuntimeOnForeground(
|
||||
foreground = true,
|
||||
onboardingCompleted = false,
|
||||
),
|
||||
)
|
||||
assertFalse(
|
||||
shouldStartRuntimeOnForeground(
|
||||
foreground = false,
|
||||
onboardingCompleted = false,
|
||||
),
|
||||
)
|
||||
assertTrue(
|
||||
shouldStartRuntimeOnForeground(
|
||||
foreground = true,
|
||||
onboardingCompleted = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package ai.openclaw.app.gateway
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.xbill.DNS.Rcode
|
||||
|
||||
class GatewayDiscoveryTest {
|
||||
@Test
|
||||
fun statusTextFormatsLocalAndWideAreaDiscoveryStates() {
|
||||
val cases =
|
||||
listOf(
|
||||
StatusCase(
|
||||
localCount = 0,
|
||||
wideAreaRcode = null,
|
||||
wideAreaCount = 0,
|
||||
expected = "Searching for gateways…",
|
||||
),
|
||||
StatusCase(
|
||||
localCount = 0,
|
||||
wideAreaRcode = Rcode.NOERROR,
|
||||
wideAreaCount = 2,
|
||||
expected = "Wide: 2",
|
||||
),
|
||||
StatusCase(
|
||||
localCount = 1,
|
||||
wideAreaRcode = Rcode.NOERROR,
|
||||
wideAreaCount = 2,
|
||||
expected = "Local: 1 • Wide: 2",
|
||||
),
|
||||
StatusCase(
|
||||
localCount = 1,
|
||||
wideAreaRcode = null,
|
||||
wideAreaCount = 0,
|
||||
expected = "Local: 1 • Wide: ?",
|
||||
),
|
||||
StatusCase(
|
||||
localCount = 0,
|
||||
wideAreaRcode = Rcode.NXDOMAIN,
|
||||
wideAreaCount = 0,
|
||||
expected = "Wide: NXDOMAIN",
|
||||
),
|
||||
StatusCase(
|
||||
localCount = 2,
|
||||
wideAreaRcode = Rcode.SERVFAIL,
|
||||
wideAreaCount = 0,
|
||||
expected = "Local: 2 • Wide: SERVFAIL",
|
||||
),
|
||||
)
|
||||
|
||||
for (case in cases) {
|
||||
assertEquals(
|
||||
case.expected,
|
||||
gatewayDiscoveryStatusText(
|
||||
localCount = case.localCount,
|
||||
wideAreaRcode = case.wideAreaRcode,
|
||||
wideAreaCount = case.wideAreaCount,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class StatusCase(
|
||||
val localCount: Int,
|
||||
val wideAreaRcode: Int?,
|
||||
val wideAreaCount: Int,
|
||||
val expected: String,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue