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(""))
}
}
|