From 087e5878a6d39325f985fbf13698ae5f5300bf1a Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 10 Mar 2026 16:14:38 -0400 Subject: [PATCH] Fixes some compilation issues --- .../amethyst/NewMessageTaggerKeyParseTest.kt | 2 +- .../followimport/FollowListImporterTest.kt | 268 ------------------ 2 files changed, 1 insertion(+), 269 deletions(-) delete mode 100644 amethyst/src/test/java/com/vitorpamplona/amethyst/service/followimport/FollowListImporterTest.kt diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt index 66ce6e751..6a209241c 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/NewMessageTaggerKeyParseTest.kt @@ -52,7 +52,7 @@ class NewMessageTaggerKeyParseTest { com.vitorpamplona.amethyst.model .Note(hex) - override suspend fun getOrCreateAddressableNote(address: Address) = + override fun getOrCreateAddressableNote(address: Address) = com.vitorpamplona.amethyst.model .AddressableNote(address) } diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/service/followimport/FollowListImporterTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/service/followimport/FollowListImporterTest.kt deleted file mode 100644 index 2fb8daa68..000000000 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/service/followimport/FollowListImporterTest.kt +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2025 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.amethyst.service.followimport - -import com.vitorpamplona.quartz.nip05DnsIdentifiers.namecoin.NamecoinNameResolver -import com.vitorpamplona.quartz.nip05DnsIdentifiers.namecoin.NamecoinResolveOutcome -import kotlinx.coroutines.runBlocking -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertNotNull -import org.junit.Assert.assertNull -import org.junit.Assert.assertTrue -import org.junit.Test - -class FollowListImporterTest { - private val importer = FollowListImporter() - - // Importer with a Namecoin resolver that always returns ServersUnreachable - // (simulates no real ElectrumX servers in test env) - private val importerWithNamecoin = - FollowListImporter( - resolveNamecoin = { identifier -> - NamecoinResolveOutcome.ServersUnreachable("Test: no servers available") - }, - ) - - // ── Hex pubkey resolution ────────────────────────────────────────── - - @Test - fun `resolves 64-char hex pubkey`() = - runBlocking { - val hex = "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9" - val r = importer.resolveIdentifier(hex) - assertNotNull(r) - assertEquals(hex, r!!.pubkeyHex) - assertNull(r.namecoinSource) - } - - @Test - fun `lowercases hex pubkey`() = - runBlocking { - val hex = "B0635D6A9851D3AED0CD6C495B282167ACF761729078D975FC341B22650B07B9" - assertEquals(hex.lowercase(), importer.resolveIdentifier(hex)!!.pubkeyHex) - } - - @Test - fun `rejects short hex`() = - runBlocking { - assertNull(importer.resolveIdentifier("abcdef")) - } - - // ── npub resolution ──────────────────────────────────────────────── - - @Test - fun `resolves valid npub`() = - runBlocking { - val npub = "npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6" - val r = importer.resolveIdentifier(npub) - assertNotNull(r) - assertEquals(64, r!!.pubkeyHex.length) - assertTrue(r.pubkeyHex.matches(Regex("^[0-9a-f]{64}$"))) - assertNull(r.namecoinSource) - } - - @Test - fun `rejects invalid npub`() = - runBlocking { - assertNull(importer.resolveIdentifier("npub1invalid")) - } - - // ── NIP-05 resolution ────────────────────────────────────────────── - - @Test - fun `delegates NIP-05 to callback`() = - runBlocking { - val expected = "aaaa000000000000000000000000000000000000000000000000000000000001" - val r = importer.resolveIdentifier("[email protected]", resolveNip05 = { expected }) - assertNotNull(r) - assertEquals(expected, r!!.pubkeyHex) - assertNull(r.namecoinSource) - } - - @Test - fun `returns null for NIP-05 without resolver`() = - runBlocking { - assertNull(importer.resolveIdentifier("[email protected]")) - } - - // ── nsec rejection ───────────────────────────────────────────────── - - @Test - fun `rejects nsec private keys`() = - runBlocking { - assertNull( - importer.resolveIdentifier( - "nsec1vl029mgpspedva04g90vltkh6fvh240zqtv9k0t9af8935ke9laqsnlfe5", - resolveNip05 = { "should-not-be-called" }, - ), - ) - } - - // ── Namecoin identifier detection ────────────────────────────────── - - @Test - fun `identifies dot-bit as Namecoin`() { - assertTrue(NamecoinNameResolver.isNamecoinIdentifier("example.bit")) - assertTrue(NamecoinNameResolver.isNamecoinIdentifier("alice@example.bit")) - assertTrue(NamecoinNameResolver.isNamecoinIdentifier("_@example.bit")) - } - - @Test - fun `identifies d-slash as Namecoin`() { - assertTrue(NamecoinNameResolver.isNamecoinIdentifier("d/example")) - } - - @Test - fun `identifies id-slash as Namecoin`() { - assertTrue(NamecoinNameResolver.isNamecoinIdentifier("id/alice")) - } - - @Test - fun `rejects non-Namecoin identifiers`() { - assertFalse(NamecoinNameResolver.isNamecoinIdentifier("[email protected]")) - assertFalse(NamecoinNameResolver.isNamecoinIdentifier("npub1abc")) - assertFalse(NamecoinNameResolver.isNamecoinIdentifier("")) - } - - // ── Kind 3 parsing ───────────────────────────────────────────────── - - @Test - fun `parses kind 3 p-tags with relay hints and petnames`() = - runBlocking { - val target = "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9" - val followA = "aaaa000000000000000000000000000000000000000000000000000000000001" - val followB = "bbbb000000000000000000000000000000000000000000000000000000000002" - - val result = - importer.fetchFollowList( - identifier = target, - relayUrls = listOf("wss://test"), - fetchEvent = { kind, author, _, onEvent -> - assertEquals(3, kind) - assertEquals(target, author) - onEvent( - Kind3EventData( - pTags = - listOf( - listOf(followA, "wss://relay.example.com", "alice"), - listOf(followB, "", "bob"), - ), - createdAt = 1700000000L, - ), - ) - AutoCloseable {} - }, - ) - - assertTrue(result is FollowListResult.Success) - val s = result as FollowListResult.Success - assertEquals(2, s.follows.size) - assertEquals(followA, s.follows[0].pubkeyHex) - assertEquals("wss://relay.example.com", s.follows[0].relayHint) - assertEquals("alice", s.follows[0].petname) - assertEquals(followB, s.follows[1].pubkeyHex) - assertNull(s.follows[1].relayHint) - assertEquals("bob", s.follows[1].petname) - assertNull(s.resolvedViaNamecoin) - } - - @Test - fun `deduplicates follows`() = - runBlocking { - val pk = "aaaa000000000000000000000000000000000000000000000000000000000001" - val result = - importer.fetchFollowList( - identifier = pk, - relayUrls = listOf("wss://t"), - fetchEvent = { _, _, _, onEvent -> - onEvent(Kind3EventData(pTags = listOf(listOf(pk), listOf(pk)), createdAt = 1L)) - AutoCloseable {} - }, - ) - assertEquals(1, (result as FollowListResult.Success).follows.size) - } - - @Test - fun `skips invalid pubkeys in p-tags`() = - runBlocking { - val result = - importer.fetchFollowList( - identifier = "aaaa000000000000000000000000000000000000000000000000000000000001", - relayUrls = listOf("wss://t"), - fetchEvent = { _, _, _, onEvent -> - onEvent( - Kind3EventData( - pTags = listOf(listOf("tooshort"), listOf(""), listOf("zzzz" + "0".repeat(60))), - createdAt = 1L, - ), - ) - AutoCloseable {} - }, - ) - assertEquals(0, (result as FollowListResult.Success).follows.size) - } - - @Test - fun `returns NoFollowList on timeout`() = - runBlocking { - val result = - importer.fetchFollowList( - identifier = "aaaa000000000000000000000000000000000000000000000000000000000001", - relayUrls = listOf("wss://t"), - fetchEvent = { _, _, _, _ -> AutoCloseable {} }, - timeoutMs = 200, - ) - assertTrue(result is FollowListResult.NoFollowList) - } - - @Test - fun `returns Error on fetch exception`() = - runBlocking { - val result = - importer.fetchFollowList( - identifier = "aaaa000000000000000000000000000000000000000000000000000000000001", - relayUrls = listOf("wss://t"), - fetchEvent = { _, _, _, _ -> throw RuntimeException("Connection refused") }, - ) - assertTrue(result is FollowListResult.Error) - assertTrue((result as FollowListResult.Error).message.contains("Connection refused")) - } - - // ── Namecoin-specific error messages ─────────────────────────────── - - @Test - fun `gives Namecoin-specific error for dot-bit failure`() = - runBlocking { - // Namecoin resolution will fail because NamecoinNameService is not - // configured with real servers in a test environment. The importer - // should give a Namecoin-specific error message. - val result = - importerWithNamecoin.fetchFollowList( - identifier = "nonexistent.bit", - relayUrls = listOf("wss://test"), - fetchEvent = { _, _, _, _ -> AutoCloseable {} }, - timeoutMs = 500, - ) - assertTrue(result is FollowListResult.InvalidIdentifier) - assertTrue((result as FollowListResult.InvalidIdentifier).reason.contains("Namecoin")) - } -}