♻️ Change dependencies of render filter
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / template / RenderFilterTest.kt
1 package net.pterodactylus.sone.template
2
3 import net.pterodactylus.sone.data.*
4 import net.pterodactylus.sone.database.*
5 import net.pterodactylus.sone.test.*
6 import net.pterodactylus.sone.text.*
7 import net.pterodactylus.sone.text.Part
8 import net.pterodactylus.util.template.*
9 import org.hamcrest.MatcherAssert.*
10 import org.hamcrest.Matchers.*
11 import org.jsoup.*
12 import org.jsoup.nodes.*
13 import org.junit.*
14 import org.mockito.*
15 import java.net.*
16
17 /**
18  * Unit test for [RenderFilter].
19  */
20 class RenderFilterTest {
21
22         companion object {
23                 private const val FREEMAIL_ID = "t4dlzfdww3xvsnsc6j6gtliox6zaoak7ymkobbmcmdw527ubuqra"
24                 private const val SONE_FREEMAIL = "sone@$FREEMAIL_ID.freemail"
25                 private const val SONE_IDENTITY = "nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI"
26                 private const val POST_ID = "37a06250-6775-4b94-86ff-257ba690953c"
27         }
28
29         private val soneProvider = mock<SoneProvider>()
30         private val soneTextParser = mock<SoneTextParser>()
31         private val htmlFilter = HtmlFilter()
32         private val sone = setupSone(SONE_IDENTITY, "Sone", "First")
33         private val parameters = mutableMapOf<String, Any?>()
34
35         private val filter = RenderFilter(soneProvider, soneTextParser, htmlFilter)
36         private val templateContext = TemplateContext()
37
38         @Test
39         fun `plain text part is rendered correctly`() {
40                 assertThat(renderParts(PlainTextPart("plain text")), equalTo("plain text"))
41         }
42
43         private fun renderParts(vararg part: Part) = filter.format(templateContext, listOf(*part), parameters) as String
44
45         @Test
46         fun `freenet link is rendered correctly`() {
47                 val linkNode = renderParts(FreenetLinkPart("KSK@gpl.txt", "gpl.txt", false)).toLinkNode()
48                 verifyLink(linkNode, "/KSK@gpl.txt", "freenet", "KSK@gpl.txt", "gpl.txt")
49         }
50
51         private fun verifyLink(linkNode: Element, url: String, cssClass: String, tooltip: String, text: String) {
52                 assertThat(linkNode.nodeName(), equalTo("a"))
53                 assertThat<List<Attribute>>(linkNode.attributes().asList(), containsInAnyOrder(
54                                 Attribute("href", url),
55                                 Attribute("class", cssClass),
56                                 Attribute("title", tooltip)
57                 ))
58                 assertThat(linkNode.text(), equalTo(text))
59         }
60
61         @Test
62         fun `trusted freenet link is rendered with correct css class`() {
63                 val linkNode = renderParts(FreenetLinkPart("KSK@gpl.txt", "gpl.txt", true)).toLinkNode()
64                 verifyLink(linkNode, "/KSK@gpl.txt", "freenet-trusted", "KSK@gpl.txt", "gpl.txt")
65         }
66
67         private fun String.toLinkNode() = Jsoup.parseBodyFragment(this).body().child(0)
68
69         @Test
70         fun `internet link is rendered correctly`() {
71                 val linkNode = renderParts(LinkPart("http://test.com/test.html", "test.com/test.html")).toLinkNode()
72                 verifyLink(linkNode, "/external-link/?_CHECKED_HTTP_=${URLEncoder.encode("http://test.com/test.html", "UTF-8")}", "internet",
73                                 "http://test.com/test.html", "test.com/test.html")
74         }
75
76         @Test
77         fun `sone parts are rendered correctly`() {
78                 val linkNode = renderParts(SonePart(sone)).toLinkNode()
79                 verifyLink(linkNode, "viewSone.html?sone=" + SONE_IDENTITY, "in-sone", "First", "First")
80         }
81
82         private fun setupSone(identity: String, name: String?, firstName: String): Sone {
83                 val sone = mock<Sone>()
84                 whenever(sone.id).thenReturn(identity)
85                 whenever(sone.profile).thenReturn(Profile(sone))
86                 whenever(sone.name).thenReturn(name)
87                 sone.profile.firstName = firstName
88                 whenever(soneProvider.getSone(identity)).thenReturn(sone)
89                 return sone
90         }
91
92         @Test
93         fun `sone part with unknown sone is rendered as link to web of trust`() {
94                 val sone = setupSone(SONE_IDENTITY, null, "First")
95                 val linkNode = renderParts(SonePart(sone)).toLinkNode()
96                 verifyLink(linkNode, "/WebOfTrust/ShowIdentity?id=$SONE_IDENTITY", "in-sone", SONE_IDENTITY, SONE_IDENTITY)
97         }
98
99         @Test
100         fun `post part is cut off correctly when there are spaces`() {
101                 val post = setupPost(sone, "1234 678901 345 789012 45678 01.")
102                 whenever(soneTextParser.parse(eq("1234 678901 345 789012 45678 01."), ArgumentMatchers.any()))
103                                 .thenReturn(listOf(PlainTextPart("1234 678901 345 789012 45678 01.")))
104                 val linkNode = renderParts(PostPart(post)).toLinkNode()
105                 verifyLink(linkNode, "viewPost.html?post=$POST_ID", "in-sone", "First", "1234 678901 345…")
106         }
107
108         private fun setupPost(sone: Sone, value: String) =
109                         mock<Post>().apply {
110                                 whenever(id).thenReturn(POST_ID)
111                                 whenever(this.sone).thenReturn(this@RenderFilterTest.sone)
112                                 whenever(text).thenReturn(value)
113                         }
114
115         @Test
116         fun `post part is cut off correctly when there are no spaces`() {
117                 val post = setupPost(sone, "1234567890123456789012345678901.")
118                 whenever(soneTextParser.parse(eq("1234567890123456789012345678901."), ArgumentMatchers.any()))
119                                 .thenReturn(listOf(PlainTextPart("1234567890123456789012345678901.")))
120                 val linkNode = renderParts(PostPart(post)).toLinkNode()
121                 verifyLink(linkNode, "viewPost.html?post=$POST_ID", "in-sone", "First", "12345678901234567890…")
122         }
123
124         @Test
125         fun `post part shorter than 21 chars is not cut off`() {
126                 val post = setupPost(sone, "12345678901234567890")
127                 whenever(soneTextParser.parse(eq("12345678901234567890"), ArgumentMatchers.any()))
128                                 .thenReturn(listOf(PlainTextPart("12345678901234567890")))
129                 val linkNode = renderParts(PostPart(post)).toLinkNode()
130                 verifyLink(linkNode, "viewPost.html?post=$POST_ID", "in-sone", "First", "12345678901234567890")
131         }
132
133         @Test
134         fun `multiple parts are rendered correctly`() {
135                 val parts = arrayOf(PlainTextPart("te"), PlainTextPart("xt"))
136                 assertThat(renderParts(*parts), equalTo("text"))
137         }
138
139         @Test
140         fun `freemail address is displayed correctly`() {
141                 val linkNode = renderParts(FreemailPart("sone", FREEMAIL_ID, SONE_IDENTITY)).toLinkNode()
142                 verifyLink(linkNode, "/Freemail/NewMessage?to=$SONE_IDENTITY", "in-sone", "First\n$SONE_FREEMAIL", "sone@First.freemail")
143         }
144
145 }