summaryrefslogtreecommitdiff
path: root/app/src/test/java/org/terst/feedreader/readability/PreferredSourceBadgeTest.kt
blob: edbb9d053719dc72250d5edadd52ae8717ee57bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package org.terst.feedreader.readability

import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

/**
 * The "Add as a preferred source on Google" badge beside a byline.
 *
 * Reported live: "remove giant Google icon" on West Hawaii Today. The markup below is what the
 * vendored Readability.js actually leaves behind on that article -- the wrapper's class is gone
 * by then, which is why the link's address is what gets matched.
 */
class PreferredSourceBadgeTest {

    private val realBadge =
        """<p><a href="https://www.google.com/preferences/source?q=westhawaiitoday.com" """ +
            """target="_blank" rel="noopener"> """ +
            """<img src="https://www.westhawaiitoday.com/wp-content/themes/2024-cmg/media/img/""" +
            """google_preferred_source_badge_light_en.png" alt="Add as a preferred source on Google"> </a> </p>"""

    @Test
    fun `strips the badge that sits beside the byline`() {
        val html = "<div><p>By A Reporter</p>$realBadge</div><p>The first real sentence.</p>"

        val cleaned = PreferredSourceBadge.strip(html)!!

        assertFalse("the badge is still there: $cleaned", cleaned.contains("preferred_source_badge"))
        assertFalse(cleaned.contains("google.com/preferences/source"))
        assertTrue(cleaned.contains("By A Reporter"))
        assertTrue(cleaned.contains("The first real sentence."))
    }

    /** It leaves no blank gap where it used to be: the paragraph held nothing else. */
    @Test
    fun `takes the emptied paragraph with it`() {
        val cleaned = PreferredSourceBadge.strip("<p>Real.</p>$realBadge")!!

        assertEquals("<p>Real.</p>", cleaned.trim())
    }

    /**
     * The safety valve. An article may discuss the programme and link to it in a sentence, and
     * that sentence belongs to whoever wrote it.
     */
    @Test
    fun `leaves a link alone when it has words in it`() {
        val html = """<p>You can <a href="https://www.google.com/preferences/source?q=x">""" +
            """add us as a preferred source</a> if you like.</p>"""

        assertEquals(html, PreferredSourceBadge.strip(html))
    }

    @Test
    fun `leaves an ordinary image link alone`() {
        val html = """<p><a href="https://example.com/photo"><img src="https://example.com/p.jpg"></a></p>"""

        assertEquals(html, PreferredSourceBadge.strip(html))
    }

    @Test
    fun `leaves an article with no badge exactly as it was`() {
        val html = "<p>Nothing to do here.</p>"

        assertEquals(html, PreferredSourceBadge.strip(html))
    }

    /**
     * The whole article, as the app would really hold it.
     *
     * The fixture is the reported USPS story put through the vendored Readability.js exactly as
     * the app does -- the cases above prove the matcher against the badge on its own, this
     * proves it meets reality in one piece. Same arrangement as the recirculation widgets, on
     * the same newspaper.
     */
    @Test
    fun `the real extracted article loses the badge and keeps its text`() {
        val extracted = checkNotNull(
            javaClass.getResourceAsStream("/west-hawaii-today-usps-extracted.html")
        ).bufferedReader().use { it.readText() }
        assertEquals(
            "fixture should carry the reported bug",
            1,
            Regex("google_preferred_source_badge").findAll(extracted).count(),
        )

        val cleaned = PreferredSourceBadge.strip(extracted)!!

        assertEquals(0, Regex("google_preferred_source_badge").findAll(cleaned).count())
        assertFalse(cleaned.contains("preferences/source"))
        assertTrue(cleaned.contains("The U.S. Postal Service is moving to raise"))
        assertTrue(cleaned.contains("Cailley LaPara"))
        assertTrue(
            "barely any of the article should have gone with the badge",
            cleaned.length > extracted.length - 400,
        )
    }

    @Test
    fun `copes with nothing`() {
        assertEquals(null, PreferredSourceBadge.strip(null))
        assertEquals("", PreferredSourceBadge.strip(""))
    }
}