1 package net.pterodactylus.sone.web.pages
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.pages.SoneTemplatePage
8 import net.pterodactylus.sone.web.page.FreenetRequest
9 import net.pterodactylus.util.notify.Notification
10 import net.pterodactylus.util.template.TemplateContext
11 import net.pterodactylus.util.version.Version
12 import net.pterodactylus.util.web.Method.GET
13 import org.hamcrest.Matcher
14 import org.hamcrest.MatcherAssert.assertThat
15 import org.hamcrest.Matchers.anyOf
16 import org.hamcrest.Matchers.contains
17 import org.hamcrest.Matchers.containsInAnyOrder
18 import org.hamcrest.Matchers.equalTo
19 import org.hamcrest.Matchers.nullValue
21 import org.mockito.Mockito.verify
24 * Unit test for [SoneTemplatePage].
26 class SoneTemplatePageTest : WebPageTest() {
28 private val preferences by lazy { core.preferences!! }
29 private val page = object : SoneTemplatePage("path.html", template, webInterface, true) {}
32 fun `current sone is retrieved from web interface`() {
33 assertThat(page.getCurrentSone(toadletContext), equalTo(currentSone))
37 fun `retrieving current sone without creation is forwarded to web interface`() {
39 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(it)
40 assertThat(page.getCurrentSoneWithoutCreatingSession(toadletContext), equalTo(it))
45 fun `setting the current sone is forwarded to web interface`() {
47 page.setCurrentSone(toadletContext, it)
48 verify(webInterface).setCurrentSone(toadletContext, it)
53 fun `page title is empty string if no page title key was given`() {
54 SoneTemplatePage("path.html", template, null, webInterface).let { page ->
55 assertThat(page.getPageTitle(freenetRequest), equalTo(""))
60 fun `page title is retrieved from l10n if page title key is given`() {
61 SoneTemplatePage("path.html", template, "page.title", webInterface).let { page ->
62 whenever(l10n.getString("page.title")).thenReturn("Page Title")
63 assertThat(page.getPageTitle(freenetRequest), equalTo("Page Title"))
68 fun `additional link nodes contain open search link`() {
69 addHttpRequestHeader("Host", "www.example.com")
70 assertThat(page.getAdditionalLinkNodes(freenetRequest), contains(mapOf(
72 "type" to "application/opensearchdescription+xml",
74 "href" to "http://www.example.com/Sone/OpenSearch.xml"
79 fun `style sheets contains sone CSS file`() {
80 assertThat(page.styleSheets, contains("css/sone.css"))
84 fun `shortcut icon is the sone icon`() {
85 assertThat(page.shortcutIcon, equalTo("images/icon.png"))
89 fun `page requires login if require login was specified in the constructor`() {
90 SoneTemplatePage("path.html", template, webInterface, true).let { page ->
91 assertThat(page.requiresLogin(), equalTo(true))
96 fun `page does not require login if require login was not specified in the constructor`() {
97 SoneTemplatePage("path.html", template, webInterface, false).let { page ->
98 assertThat(page.requiresLogin(), equalTo(false))
102 private fun verifyVariableIsSet(name: String, value: Any) = verifyVariableMatches(name, equalTo<Any>(value))
104 private fun <T> verifyVariableMatches(name: String, matcher: Matcher<T>) {
105 page.processTemplate(freenetRequest, templateContext)
106 @Suppress("UNCHECKED_CAST")
107 assertThat(templateContext[name] as T, matcher)
111 fun `preferences are set in template context`() {
112 verifyVariableIsSet("preferences", preferences)
116 fun `current sone is set in template context`() {
117 verifyVariableIsSet("currentSone", currentSone)
121 fun `local sones are set in template context`() {
122 val localSones = listOf(mock<Sone>(), mock<Sone>())
123 whenever(core.localSones).thenReturn(localSones)
124 verifyVariableMatches("localSones", containsInAnyOrder(*localSones.toTypedArray()))
128 fun `freenet request is set in template context`() {
129 verifyVariableIsSet("request", freenetRequest)
133 fun `current version is set in template context`() {
134 verifyVariableIsSet("currentVersion", SonePlugin.getPluginVersion())
138 fun `has latest version is set correctly in template context if true`() {
139 whenever(core.updateChecker.hasLatestVersion()).thenReturn(true)
140 verifyVariableIsSet("hasLatestVersion", true)
144 fun `has latest version is set correctly in template context if false`() {
145 whenever(core.updateChecker.hasLatestVersion()).thenReturn(false)
146 verifyVariableIsSet("hasLatestVersion", false)
150 fun `latest edition is set in template context`() {
151 whenever(core.updateChecker.latestEdition).thenReturn(1234L)
152 verifyVariableIsSet("latestEdition", 1234L)
156 fun `latest version is set in template context`() {
157 whenever(core.updateChecker.latestVersion).thenReturn(Version(1, 2, 3))
158 verifyVariableIsSet("latestVersion", Version(1, 2, 3))
162 fun `latest version time is set in template context`() {
163 whenever(core.updateChecker.latestVersionDate).thenReturn(12345L)
164 verifyVariableIsSet("latestVersionTime", 12345L)
167 private fun createNotification(time: Long) = mock<Notification>().apply {
168 whenever(createdTime).thenReturn(time)
172 fun `notifications are set in template context`() {
173 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
174 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
175 verifyVariableMatches("notifications", contains(notifications[1], notifications[2], notifications[0]))
179 fun `notification hash is set in template context`() {
180 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
181 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
182 verifyVariableIsSet("notificationHash", listOf(notifications[1], notifications[2], notifications[0]).hashCode())
186 fun `handleRequest method is called`() {
188 val page = object : SoneTemplatePage("path.html", template, webInterface, true) {
189 override fun handleRequest(request: FreenetRequest, templateContext: TemplateContext) {
193 page.processTemplate(freenetRequest, templateContext)
194 assertThat(called, equalTo(true))
198 fun `redirect does not happen if login is not required`() {
199 val page = SoneTemplatePage("page.html", template, webInterface, false)
200 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
204 fun `redirect does not happen if sone is logged in`() {
205 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
209 fun `redirect does happen if sone is not logged in`() {
211 request("index.html", GET)
212 assertThat(page.getRedirectTarget(freenetRequest), equalTo("login.html?target=index.html"))
216 fun `redirect does happen with parameters encoded correctly if sone is not logged in`() {
218 request("index.html", GET)
219 addHttpRequestParameter("foo", "b=r")
220 addHttpRequestParameter("baz", "q&o")
221 assertThat(page.getRedirectTarget(freenetRequest), anyOf(
222 equalTo("login.html?target=index.html%3Ffoo%3Db%253Dr%26baz%3Dq%2526o"),
223 equalTo("login.html?target=index.html%3Fbaz%3Dq%2526o%26foo%3Db%253Dr")
228 fun `full access requirement is correctly forwarded from the preferences if false`() {
229 assertThat(page.isFullAccessOnly, equalTo(false))
233 fun `full access requirement is correctly forwarded from the preferences if true`() {
234 core.preferences.isRequireFullAccess = true
235 assertThat(page.isFullAccessOnly, equalTo(true))
239 fun `page is disabled if full access is required but request does not have full access`() {
240 core.preferences.isRequireFullAccess = true
241 assertThat(page.isEnabled(toadletContext), equalTo(false))
245 fun `page is disabled if login is required but there is no current sone`() {
247 assertThat(page.isEnabled(toadletContext), equalTo(false))
251 fun `page is enabled if login is required and there is a current sone`() {
252 assertThat(page.isEnabled(toadletContext), equalTo(true))
256 fun `page is enabled if full access is required and request has full access and login is required and there is a current sone`() {
257 core.preferences.isRequireFullAccess = true
258 whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
259 assertThat(page.isEnabled(toadletContext), equalTo(true))
263 fun `page is enabled if no full access is required and login is not required`() {
264 SoneTemplatePage("path.html", template, webInterface, false).let { page ->
265 assertThat(page.isEnabled(toadletContext), equalTo(true))