diff --git a/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt b/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt index acfb68e9e..c5a86add1 100644 --- a/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt +++ b/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt @@ -248,25 +248,30 @@ constructor( } private fun findThumbnail(mediaModule: MediaEntryModule): String? { + + val imageUrl = mediaModule.mediaContents + .asSequence() + .filter { it.medium == "image" } + .mapNotNull { content -> + (content.reference as? UrlReference)?.url?.toString() + } + .firstOrNull{it.isNotBlank()} + + if(imageUrl != null){ + return imageUrl + } + + val candidates = buildList { add(mediaModule.metadata) - addAll(mediaModule.mediaGroups.map { mediaGroup -> mediaGroup.metadata }) - addAll(mediaModule.mediaContents.map { content -> content.metadata }) + addAll(mediaModule.mediaGroups.map { it.metadata }) + addAll(mediaModule.mediaContents.map { it.metadata }) } .flatMap { it.thumbnail.toList() } - val thumbnail = candidates.firstOrNull() + return candidates.firstOrNull()?.url?.toString() - if (thumbnail != null) { - return thumbnail.url.toString() - } else { - val imageMedia = mediaModule.mediaContents.firstOrNull { it.medium == "image" } - if (imageMedia != null) { - return (imageMedia.reference as? UrlReference)?.url.toString() - } - } - return null } fun findThumbnail(text: String?): String? { diff --git a/app/src/test/java/me/ash/reader/infrastructure/rss/RssHelperTest.kt b/app/src/test/java/me/ash/reader/infrastructure/rss/RssHelperTest.kt index 6cfccb310..08bb6ad7c 100644 --- a/app/src/test/java/me/ash/reader/infrastructure/rss/RssHelperTest.kt +++ b/app/src/test/java/me/ash/reader/infrastructure/rss/RssHelperTest.kt @@ -10,6 +10,9 @@ import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.mock +import com.rometools.rome.feed.synd.SyndEntry +import com.rometools.rome.io.SyndFeedInput +import java.io.StringReader internal const val enclosureUrlString1: String = "https://example.com/enclosure.jpg" internal const val enclosureUrlString2: String = "https://github.blog/wp-content/uploads/2024/03/github_copilot_header.png" @@ -87,4 +90,79 @@ class RssHelperTest { """ Assert.assertEquals(imageUrlString, rssHelper.findThumbnail(case)) } + + + + private fun parseMediaEntry(mediaXml: String): SyndEntry { + val xml = """ + + + Test feed + https://example.com/ + Image selection tests + + Test article + https://example.com/article + $mediaXml + + + + """.trimIndent() + + return StringReader(xml).use { reader -> + SyndFeedInput().build(reader).entries.single() + } + } + + @Test + fun testPrefersMediaContentOverThumbnail() { + val entry = parseMediaEntry( + """ + + + """.trimIndent() + ) + + Assert.assertEquals( + "https://example.com/large.jpg", + rssHelper.findThumbnail(entry) + ) + } + + @Test + fun testFallsBackToMediaThumbnail() { + val entry = parseMediaEntry( + """""" + ) + + Assert.assertEquals( + "https://example.com/small.jpg", + rssHelper.findThumbnail(entry) + ) + } + + @Test + fun testUsesThumbnailInsteadOfVideoContent() { + val entry = parseMediaEntry( + """ + + + """.trimIndent() + ) + + Assert.assertEquals( + "https://example.com/small.jpg", + rssHelper.findThumbnail(entry) + ) + } + + @Test + fun testReturnsNullWithoutMediaImages() { + val entry = parseMediaEntry("") + + Assert.assertNull(rssHelper.findThumbnail(entry)) + } }