Replace web page test base with Kotlin version
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / pages / SoneTemplatePageTest.kt
1 package net.pterodactylus.sone.web.pages
2
3 import net.pterodactylus.sone.data.Sone
4 import net.pterodactylus.sone.main.SonePlugin
5 import net.pterodactylus.sone.test.mock
6 import net.pterodactylus.sone.test.whenever
7 import net.pterodactylus.sone.web.page.FreenetRequest
8 import net.pterodactylus.util.notify.Notification
9 import net.pterodactylus.util.template.TemplateContext
10 import net.pterodactylus.util.version.Version
11 import org.hamcrest.Matcher
12 import org.hamcrest.MatcherAssert.assertThat
13 import org.hamcrest.Matchers.anyOf
14 import org.hamcrest.Matchers.contains
15 import org.hamcrest.Matchers.containsInAnyOrder
16 import org.hamcrest.Matchers.equalTo
17 import org.hamcrest.Matchers.nullValue
18 import org.junit.Test
19 import org.mockito.Mockito.verify
20
21 /**
22  * Unit test for [SoneTemplatePage].
23  */
24 class SoneTemplatePageTest: WebPageTest({ template, webInterface -> object : SoneTemplatePage("path.html", template, webInterface, true) {}}) {
25
26         @Test
27         fun `current sone is retrieved from web interface`() {
28                 assertThat(page.getCurrentSone(toadletContext), equalTo(currentSone))
29         }
30
31         @Test
32         fun `retrieving current sone without creation is forwarded to web interface`() {
33                 mock<Sone>().let {
34                         whenever(webInterface.getCurrentSone(toadletContext, false)).thenReturn(it)
35                         assertThat(page.getCurrentSone(toadletContext, false), equalTo(it))
36                 }
37         }
38
39         @Test
40         fun `setting the current sone is forwarded to web interface`() {
41                 mock<Sone>().let {
42                         page.setCurrentSone(toadletContext, it)
43                         verify(webInterface).setCurrentSone(toadletContext, it)
44                 }
45         }
46
47         @Test
48         fun `page title is empty string if no page title key was given`() {
49                 SoneTemplatePage("path.html", template, null, webInterface).let { page ->
50                         assertThat(page.getPageTitle(freenetRequest), equalTo(""))
51                 }
52         }
53
54         @Test
55         fun `page title is retrieved from l10n if page title key is given`() {
56                 SoneTemplatePage("path.html", template, "page.title", webInterface).let { page ->
57                         whenever(l10n.getString("page.title")).thenReturn("Page Title")
58                         assertThat(page.getPageTitle(freenetRequest), equalTo("Page Title"))
59                 }
60         }
61
62         @Test
63         fun `additional link nodes contain open search link`() {
64                 addHttpRequestHeader("Host", "www.example.com")
65                 assertThat(page.getAdditionalLinkNodes(freenetRequest), contains(mapOf(
66                                 "rel" to "search",
67                                 "type" to "application/opensearchdescription+xml",
68                                 "title" to "Sone",
69                                 "href" to "http://www.example.com/Sone/OpenSearch.xml"
70                 )))
71         }
72
73         @Test
74         fun `style sheets contains sone CSS file`() {
75                 assertThat(page.styleSheets, contains("css/sone.css"))
76         }
77
78         @Test
79         fun `shortcut icon is the sone icon`() {
80                 assertThat(page.shortcutIcon, equalTo("images/icon.png"))
81         }
82
83         @Test
84         fun `page requires login if require login was specified in the constructor`() {
85                 SoneTemplatePage("path.html", template, webInterface, true).let { page ->
86                         assertThat(page.requiresLogin(), equalTo(true))
87                 }
88         }
89
90         @Test
91         fun `page does not require login if require login was not specified in the constructor`() {
92                 SoneTemplatePage("path.html", template, webInterface, false).let { page ->
93                         assertThat(page.requiresLogin(), equalTo(false))
94                 }
95         }
96
97         private fun verifyVariableIsSet(name: String, value: Any) = verifyVariableMatches(name, equalTo<Any>(value))
98
99         private fun <T> verifyVariableMatches(name: String, matcher: Matcher<T>) {
100                 page.processTemplate(freenetRequest, templateContext)
101                 @Suppress("UNCHECKED_CAST")
102                 assertThat(templateContext[name] as T, matcher)
103         }
104
105         @Test
106         fun `preferences are set in template context`() {
107             verifyVariableIsSet("preferences", preferences)
108         }
109
110         @Test
111         fun `current sone is set in template context`() {
112                 verifyVariableIsSet("currentSone", currentSone)
113         }
114
115         @Test
116         fun `local sones are set in template context`() {
117                 val localSones = listOf(mock<Sone>(), mock<Sone>())
118                 whenever(core.localSones).thenReturn(localSones)
119                 verifyVariableMatches("localSones", containsInAnyOrder(*localSones.toTypedArray()))
120         }
121
122         @Test
123         fun `freenet request is set in template context`() {
124                 verifyVariableIsSet("request", freenetRequest)
125         }
126
127         @Test
128         fun `current version is set in template context`() {
129                 verifyVariableIsSet("currentVersion", SonePlugin.getPluginVersion())
130         }
131
132         @Test
133         fun `has latest version is set correctly in template context if true`() {
134                 whenever(core.updateChecker.hasLatestVersion()).thenReturn(true)
135                 verifyVariableIsSet("hasLatestVersion", true)
136         }
137
138         @Test
139         fun `has latest version is set correctly in template context if false`() {
140                 whenever(core.updateChecker.hasLatestVersion()).thenReturn(false)
141                 verifyVariableIsSet("hasLatestVersion", false)
142         }
143
144         @Test
145         fun `latest edition is set in template context`() {
146                 whenever(core.updateChecker.latestEdition).thenReturn(1234L)
147                 verifyVariableIsSet("latestEdition", 1234L)
148         }
149
150         @Test
151         fun `latest version is set in template context`() {
152                 whenever(core.updateChecker.latestVersion).thenReturn(Version(1, 2, 3))
153                 verifyVariableIsSet("latestVersion", Version(1, 2, 3))
154         }
155
156         @Test
157         fun `latest version time is set in template context`() {
158                 whenever(core.updateChecker.latestVersionDate).thenReturn(12345L)
159                 verifyVariableIsSet("latestVersionTime", 12345L)
160         }
161
162         private fun createNotification(time: Long) = mock<Notification>().apply {
163                 whenever(createdTime).thenReturn(time)
164         }
165
166         @Test
167         fun `notifications are set in template context`() {
168                 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
169                 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
170                 verifyVariableMatches("notifications", contains(notifications[1], notifications[2], notifications[0]))
171         }
172
173         @Test
174         fun `notification hash is set in template context`() {
175                 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
176                 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
177                 verifyVariableIsSet("notificationHash", listOf(notifications[1], notifications[2], notifications[0]).hashCode())
178         }
179
180         @Test
181         fun `handleRequest method is called`() {
182                 var called = false
183                 val page = object : SoneTemplatePage("path.html", template, webInterface, true) {
184                         override fun handleRequest(request: FreenetRequest, templateContext: TemplateContext) {
185                                 called = true
186                         }
187                 }
188                 page.processTemplate(freenetRequest, templateContext)
189                 assertThat(called, equalTo(true))
190         }
191
192         @Test
193         fun `redirect does not happen if login is not required`() {
194                 val page = SoneTemplatePage("page.html", template, webInterface, false)
195                 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
196         }
197
198         @Test
199         fun `redirect does not happen if sone is logged in`() {
200                 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
201         }
202
203         @Test
204         fun `redirect does happen if sone is not logged in`() {
205                 unsetCurrentSone()
206                 request("index.html")
207                 assertThat(page.getRedirectTarget(freenetRequest), equalTo("login.html?target=index.html"))
208         }
209
210         @Test
211         fun `redirect does happen with parameters encoded correctly if sone is not logged in`() {
212                 unsetCurrentSone()
213                 request("index.html")
214                 addHttpRequestParameter("foo", "b=r")
215                 addHttpRequestParameter("baz", "q&o")
216                 assertThat(page.getRedirectTarget(freenetRequest), anyOf(
217                                 equalTo("login.html?target=index.html%3Ffoo%3Db%253Dr%26baz%3Dq%2526o"),
218                                 equalTo("login.html?target=index.html%3Fbaz%3Dq%2526o%26foo%3Db%253Dr")
219                 ))
220         }
221
222         @Test
223         fun `full access requirement is correctly forwarded from the preferences if false`() {
224                 assertThat(page.isFullAccessOnly, equalTo(false))
225         }
226
227         @Test
228         fun `full access requirement is correctly forwarded from the preferences if true`() {
229                 core.preferences.isRequireFullAccess = true
230                 assertThat(page.isFullAccessOnly, equalTo(true))
231         }
232
233         @Test
234         fun `page is disabled if full access is required but request does not have full access`() {
235                 core.preferences.isRequireFullAccess = true
236                 assertThat(page.isEnabled(toadletContext), equalTo(false))
237         }
238
239         @Test
240         fun `page is disabled if login is required but there is no current sone`() {
241                 unsetCurrentSone()
242                 assertThat(page.isEnabled(toadletContext), equalTo(false))
243         }
244
245         @Test
246         fun `page is enabled if login is required and there is a current sone`() {
247                 assertThat(page.isEnabled(toadletContext), equalTo(true))
248         }
249
250         @Test
251         fun `page is enabled if full access is required and request has full access and login is required and there is a current sone`() {
252                 core.preferences.isRequireFullAccess = true
253                 whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
254                 assertThat(page.isEnabled(toadletContext), equalTo(true))
255         }
256
257         @Test
258         fun `page is enabled if no full access is required and login is not required`() {
259                 SoneTemplatePage("path.html", template, webInterface, false).let { page ->
260                         assertThat(page.isEnabled(toadletContext), equalTo(true))
261                 }
262         }
263
264 }