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