package com.peachpasswords.sync import kotlinx.coroutines.runBlocking import org.junit.Assert.assertFalse import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test class ChirpSyncTransportTest { private val peerPubkey = "ab".repeat(32) @Before fun setUp() { resetSubnetProbeCooldown() } @Test fun `subnetProbeOnCooldown returns false before any probe has happened`() { assertFalse(subnetProbeOnCooldown(peerPubkey)) } @Test fun `subnetProbeOnCooldown returns true within the cooldown window after a probe`() = runBlocking { val now = 1_000_000L probeSubnetForPeer( subnet = "10.0.0", port = SyncReconnectListener.SYNC_PORT, ourLongTermPrivateKey = ByteArray(32), ourLongTermPublicKey = ByteArray(32), expectedRemotePubkeyHex = peerPubkey, batch = 254, timeoutMs = 1, now = now, ) assertTrue(subnetProbeOnCooldown(peerPubkey, now + 1)) assertTrue(subnetProbeOnCooldown(peerPubkey, now + SUBNET_PROBE_COOLDOWN_MS - 1)) } @Test fun `subnetProbeOnCooldown releases after the window expires`() = runBlocking { val now = 1_000_000L probeSubnetForPeer( subnet = "10.0.0", port = SyncReconnectListener.SYNC_PORT, ourLongTermPrivateKey = ByteArray(32), ourLongTermPublicKey = ByteArray(32), expectedRemotePubkeyHex = peerPubkey, batch = 254, timeoutMs = 1, now = now, ) assertFalse(subnetProbeOnCooldown(peerPubkey, now + SUBNET_PROBE_COOLDOWN_MS)) } @Test fun `probeSubnetForPeer returns null and skips the scan when on cooldown`() = runBlocking { val now = 1_000_000L probeSubnetForPeer( subnet = "10.0.0", port = SyncReconnectListener.SYNC_PORT, ourLongTermPrivateKey = ByteArray(32), ourLongTermPublicKey = ByteArray(32), expectedRemotePubkeyHex = peerPubkey, batch = 254, timeoutMs = 1, now = now, ) val result = probeSubnetForPeer( subnet = "10.0.0", port = SyncReconnectListener.SYNC_PORT, ourLongTermPrivateKey = ByteArray(32), ourLongTermPublicKey = ByteArray(32), expectedRemotePubkeyHex = peerPubkey, batch = 254, timeoutMs = 1, now = now + 1_000, ) assertNull(result) } @Test fun `probeSubnetForPeer tracks cooldown independently per peer pubkey`() = runBlocking { val now = 1_000_000L val other = "cd".repeat(32) probeSubnetForPeer( subnet = "10.0.0", port = SyncReconnectListener.SYNC_PORT, ourLongTermPrivateKey = ByteArray(32), ourLongTermPublicKey = ByteArray(32), expectedRemotePubkeyHex = peerPubkey, batch = 254, timeoutMs = 1, now = now, ) assertTrue(subnetProbeOnCooldown(peerPubkey, now + 1)) assertFalse(subnetProbeOnCooldown(other, now + 1)) } }