Skip to content

Commit e13fe60

Browse files
committed
Cover WS connect and peer-echo paths for device capabilities
Two coverage gaps spotted in review of the existing capabilities tests: - WsFlowTest: open a WS handshake with the capabilities header and verify the device's stored set reflects it. The wiring lives in WsRoute, not HttpExtensions.verifyCaller, so the existing HTTP-only tests didn't reach it. - DeviceFlowTest: two-device test where device 2 joins via share code with capabilities, device 1 reads them via the devices list endpoint. Pins the user-visible peer-echo contract that the client-side feature depends on.
1 parent cfe0070 commit e13fe60

2 files changed

Lines changed: 49 additions & 0 deletions

File tree

src/test/kotlin/eu/darken/octi/server/device/DeviceFlowTest.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,27 @@ class DeviceFlowTest : TestRunner() {
346346
getDevices(creds).devices.single().capabilities shouldBe emptySet()
347347
}
348348

349+
@Test
350+
fun `peer sees other device's capabilities via device list`() = runTest2 {
351+
// End-to-end echo: device 2 joins with capabilities, device 1 reads them off the
352+
// /v1/devices response. This is the user-visible contract the client-side feature
353+
// depends on (peers learning each other's supported encryption modes).
354+
val creds1 = createDevice()
355+
val shareCode = createShareCode(creds1)
356+
val creds2 = createDevice(
357+
shareCode = shareCode,
358+
capabilities = """["encryption:_reported","encryption:AES256_GCM_SIV"]""",
359+
)
360+
361+
val devices = getDevices(creds1).devices
362+
devices.size shouldBe 2
363+
val peer = devices.single { it.id == creds2.deviceId }
364+
peer.capabilities shouldBe setOf(
365+
"encryption:_reported",
366+
"encryption:AES256_GCM_SIV",
367+
)
368+
}
369+
349370
@Test
350371
fun `auth failure with missing X-Device-ID is tracked`() = runTest2 {
351372
http.get(endPoint).apply {

src/test/kotlin/eu/darken/octi/server/ws/WsFlowTest.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,34 @@ class WsFlowTest : TestRunner() {
108108
wsClient.close()
109109
}
110110

111+
@Test
112+
fun `connect with Octi-Device-Capabilities stores the capabilities`() = runWsTest {
113+
// WS connect goes through the same touchAuthenticatedDevice path as HTTP, but the
114+
// wiring is in WsRoute (not HttpExtensions.verifyCaller). Pin it here so the WS
115+
// wire claim in the PR description is actually test-covered.
116+
val creds = createDevice()
117+
val wsClient = createWsClient()
118+
119+
wsClient.webSocket(
120+
urlString = wsUrl(),
121+
request = {
122+
addCredentials(creds)
123+
headers.append(
124+
"Octi-Device-Capabilities",
125+
"""["encryption:_reported","encryption:AES256_GCM_SIV"]""",
126+
)
127+
},
128+
) {
129+
close(CloseReason(CloseReason.Codes.NORMAL, "Test done"))
130+
}
131+
132+
getDevices(creds).devices.single().capabilities shouldBe setOf(
133+
"encryption:_reported",
134+
"encryption:AES256_GCM_SIV",
135+
)
136+
wsClient.close()
137+
}
138+
111139
@Test
112140
fun `rate-limited authenticated connect still records client identity`() = runWsTest(
113141
appConfig = baseConfig.copy(

0 commit comments

Comments
 (0)