package com.peachpasswords.sync import org.junit.Assert.assertEquals import org.junit.Assert.assertSame import org.junit.Test /** * What a relay change does to the existing mesh, mirroring the browser's * `setSyncMode` / `setRelayUrl`. The store around this is only * EncryptedSharedPreferences and a Context this suite has no reason to stand * up; the decision it delegates to lives here. */ class RelaySettingsPropagationTest { private val selfHosted = "wss://relay.example.com" private val pairs = listOf( PairedDevice(deviceId = "browser", relayUrl = "wss://old-relay.example", pairedAt = 1L), PairedDevice(deviceId = "phone", relayUrl = null, pairedAt = 2L), ) @Test fun `switching to private with an address moves every existing pair to it`() { val updated = withRelaySetting(pairs, SyncMode.PRIVATE, selfHosted) assertEquals(listOf(selfHosted, selfHosted), updated.map { it.relayUrl }) assertEquals(listOf("browser", "phone"), updated.map { it.deviceId }) } @Test fun `switching to public moves every existing pair back to peach's relay`() { val updated = withRelaySetting(pairs, SyncMode.PUBLIC, selfHosted) assertEquals( listOf(Rendezvous.DEFAULT_RELAY_URL, Rendezvous.DEFAULT_RELAY_URL), updated.map { it.relayUrl }, ) } /** * The exception. Private-with-no-address has nothing to push, and pushing * the stored default would put the whole mesh on Peach's relay under a * private label. */ @Test fun `private with no address moves no pair`() { assertSame(pairs, withRelaySetting(pairs, SyncMode.PRIVATE, Rendezvous.DEFAULT_RELAY_URL)) } @Test fun `turning sync off leaves the mesh where it was`() { assertSame(pairs, withRelaySetting(pairs, SyncMode.OFF, selfHosted)) } /** * Adoption records the source's relay through the same path as the Settings * field, so what the Sync card then reads is [modeForRelayUrl] plus * [privateRelayUrlOf] over the adopted URL. */ @Test fun `adoption over the public relay leaves the receiver reading public`() { val adopted = Rendezvous.DEFAULT_RELAY_URL assertEquals(SyncMode.PUBLIC, modeForRelayUrl(adopted)) assertEquals("", privateRelayUrlOf(adopted)) assertEquals("wss://", privateRelayDraftOf(privateRelayUrlOf(adopted))) } @Test fun `adoption over a private relay leaves the receiver reading that url`() { assertEquals(SyncMode.PRIVATE, modeForRelayUrl(selfHosted)) assertEquals(selfHosted, privateRelayUrlOf(selfHosted)) assertEquals(selfHosted, privateRelayDraftOf(privateRelayUrlOf(selfHosted))) // And the receiver is not stranded in the unconfigured-private state // that would pause its sync. assertEquals( RelayDecision.Dial(selfHosted), relayInForce(modeForRelayUrl(selfHosted), selfHosted), ) } }