From cdefcc441f8b2aab94adff05eb1f333fd0a983b2 Mon Sep 17 00:00:00 2001 From: Levi Bard Date: Mon, 28 Feb 2022 16:54:25 +0100 Subject: [PATCH] Fix relinkifying tags in posts from remote servers (#2359) * Fix relinkifying tags in posts from remote servers * Completely ignore urls, and (case-insensitively) match tag names instead --- .../keylesspalace/tusky/util/LinkHelper.kt | 9 ++-- .../tusky/util/LinkHelperTest.kt | 49 ++++--------------- 2 files changed, 15 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/util/LinkHelper.kt b/app/src/main/java/com/keylesspalace/tusky/util/LinkHelper.kt index 43d7c0f01..02ecf7735 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/LinkHelper.kt +++ b/app/src/main/java/com/keylesspalace/tusky/util/LinkHelper.kt @@ -98,15 +98,16 @@ fun setClickableText( } @VisibleForTesting -fun getTagName(text: CharSequence, tags: List?, span: URLSpan): String? { +fun getTagName(text: CharSequence, tags: List?): String? { + val scrapedName = text.subSequence(1, text.length).toString() return when (tags) { - null -> text.subSequence(1, text.length).toString() - else -> tags.firstOrNull { it.url == span.url }?.name + null -> scrapedName + else -> tags.firstOrNull { it.name.equals(scrapedName, true) }?.name } } private fun getCustomSpanForTag(text: CharSequence, tags: List?, span: URLSpan, listener: LinkListener): ClickableSpan? { - return getTagName(text, tags, span)?.let { + return getTagName(text, tags)?.let { object : NoUnderlineURLSpan(span.url) { override fun onClick(view: View) = listener.onViewTag(it) } diff --git a/app/src/test/java/com/keylesspalace/tusky/util/LinkHelperTest.kt b/app/src/test/java/com/keylesspalace/tusky/util/LinkHelperTest.kt index 8a9a1b38d..4a2cdc53f 100644 --- a/app/src/test/java/com/keylesspalace/tusky/util/LinkHelperTest.kt +++ b/app/src/test/java/com/keylesspalace/tusky/util/LinkHelperTest.kt @@ -70,56 +70,27 @@ class LinkHelperTest { } @Test - fun whenSettingClickableTest_tagUrlsArePreserved() { - val builder = SpannableStringBuilder() + fun whenCheckingTags_tagNameIsComparedCaseInsensitively() { for (tag in tags) { - builder.append("#${tag.name}", URLSpan(tag.url), 0) - builder.append(" ") - } - - var urlSpans = builder.getSpans(0, builder.length, URLSpan::class.java) - for (span in urlSpans) { - setClickableText(span, builder, emptyList(), tags, listener) - } - - urlSpans = builder.getSpans(0, builder.length, URLSpan::class.java) - for (span in urlSpans) { - Assert.assertNotNull(tags.firstOrNull { it.url == span.url }) + for (mutatedTagName in listOf(tag.name, tag.name.uppercase(), tag.name.lowercase())) { + val tagName = getTagName("#$mutatedTagName", tags) + Assert.assertNotNull(tagName) + Assert.assertNotNull(tags.firstOrNull { it.name == tagName }) + } } } @Test - fun whenSettingClickableTest_nonTagUrlsAreNotConverted() { - val builder = SpannableStringBuilder() - val nonTagUrl = "http://example.com/" + fun hashedUrlSpans_withNoMatchingTag_areNotModified() { for (tag in tags) { - builder.append("#${tag.name}", URLSpan(nonTagUrl), 0) - builder.append(" ") - builder.append("#${tag.name} ") - } - - var urlSpans = builder.getSpans(0, builder.length, URLSpan::class.java) - for (span in urlSpans) { - setClickableText(span, builder, emptyList(), tags, listener) - } - - urlSpans = builder.getSpans(0, builder.length, URLSpan::class.java) - for (span in urlSpans) { - Assert.assertEquals(nonTagUrl, span.url) + Assert.assertNull(getTagName("#not${tag.name}", tags)) } } @Test fun whenTagsAreNull_tagNameIsGeneratedFromText() { - SpannableStringBuilder().apply { - for (tag in tags) { - append("#${tag.name}", URLSpan(tag.url), 0) - append(" ") - } - - getSpans(0, length, URLSpan::class.java).forEach { - Assert.assertNotNull(getTagName(subSequence(getSpanStart(it), getSpanEnd(it)), null, it)) - } + for (tag in tags) { + Assert.assertEquals(tag.name, getTagName("#${tag.name}", null)) } }