diff --git a/commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParserTest.kt b/commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParserTest.kt index 9a5ce0bb0..f0f8ff5a9 100644 --- a/commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParserTest.kt +++ b/commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/richtext/RichTextParserTest.kt @@ -4420,6 +4420,23 @@ class RichTextParserTest { assertEquals("m", nowhere?.tool) } + @Test + fun testNowhereLinkWithLargeBase64UrlFragment() { + // Real nowhere links can be kilobytes long (a full store catalogue or forum thread + // base64url-encoded). Verify both UrlDetector capture and our classifier survive a + // ~5KB fragment containing every base64url-legal character (A-Z, a-z, 0-9, -, _). + val alphabet = ('A'..'Z').joinToString("") + ('a'..'z').joinToString("") + ('0'..'9').joinToString("") + "-_" + val payload = (0 until 80).joinToString("") { alphabet } + val url = "https://nowhr.xyz/s#$payload" + val text = "look at this big store $url and reply" + val state = RichTextParser().parseText(text, EmptyTagList, null) + val nowhere = state.paragraphs.flatMap { it.words }.firstOrNull { it is NowhereLinkSegment } as? NowhereLinkSegment + assertEquals(url, nowhere?.segmentText) + assertEquals(payload.length, nowhere?.segmentText?.substringAfter('#')?.length) + assertEquals("nowhr.xyz", nowhere?.host) + assertEquals("s", nowhere?.tool) + } + @Test fun testPlainNowhereHostWithoutFragmentStaysAsLink() { // No fragment => not a nowhere site, fall through to LinkSegment.