package com.peachpasswords.sync import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Test /** * The relay frames share a channel with ordinary sync frames, so the one thing * that must never break is telling them apart: a sync frame misread as a relay * frame would be forwarded to another device, and a relay frame misread as sync * would be handed to the vault. */ class RelayFramesTest { @Test fun `a relay request round-trips`() { val key = "ab".repeat(32) val decoded = decodeRelayMessage(RelayMessage.Request(key).encodeToBytes()) assertEquals(RelayMessage.Request(key), decoded) } @Test fun `frames use the type discriminator the browser sync frames use`() { val json = String(RelayMessage.Request("00".repeat(32)).encodeToBytes(), Charsets.UTF_8) assertTrue(json, json.contains("\"type\":\"RELAY_REQUEST\"")) assertTrue(json, json.contains("\"targetDeviceId\":")) } @Test fun `sync traffic is not mistaken for a relay frame`() { val hello = SyncMessage.Hello("v", "d", 1, 2).encodeToBytes() assertNull(decodeRelayMessage(hello)) } @Test fun `junk and empty frames are not relay frames`() { assertNull(decodeRelayMessage(ByteArray(0))) assertNull(decodeRelayMessage(byteArrayOf(0x01, 0x02, 0x03))) assertNull(decodeRelayMessage("not json".toByteArray())) } @Test fun `a payload survives forwarding unchanged`() { val opaque = java.util.Base64.getEncoder().encodeToString(byteArrayOf(0, 1, 2, -1, -2)) val decoded = decodeRelayMessage(RelayMessage.Payload(opaque).encodeToBytes()) assertEquals(opaque, (decoded as RelayMessage.Payload).payload) } @Test fun `the parameterless responses decode by type alone`() { listOf( RelayMessage.Accept, RelayMessage.Unavailable, RelayMessage.Disabled, RelayMessage.Close, ).forEach { assertEquals(it, decodeRelayMessage(it.encodeToBytes())) } } }