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.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 net.pterodactylus.util.web.Method.GET
12 import org.hamcrest.Matcher
13 import org.hamcrest.MatcherAssert.assertThat
14 import org.hamcrest.Matchers.anyOf
15 import org.hamcrest.Matchers.contains
16 import org.hamcrest.Matchers.containsInAnyOrder
17 import org.hamcrest.Matchers.equalTo
18 import org.hamcrest.Matchers.nullValue
20 import org.mockito.Mockito.verify
23 * Unit test for [SoneTemplatePage].
25 class SoneTemplatePageTest : WebPageTest() {
27 private val preferences by lazy { core.preferences!! }
28 private val page = object : SoneTemplatePage("path.html", template, webInterface, true) {}
31 fun `current sone is retrieved from web interface`() {
32 assertThat(page.getCurrentSone(toadletContext), equalTo(currentSone))
36 fun `retrieving current sone without creation is forwarded to web interface`() {
38 whenever(webInterface.getCurrentSone(toadletContext, false)).thenReturn(it)
39 assertThat(page.getCurrentSone(toadletContext, false), equalTo(it))
44 fun `setting the current sone is forwarded to web interface`() {
46 page.setCurrentSone(toadletContext, it)
47 verify(webInterface).setCurrentSone(toadletContext, it)
52 fun `page title is empty string if no page title key was given`() {
53 SoneTemplatePage("path.html", template, null, webInterface).let { page ->
54 assertThat(page.getPageTitle(freenetRequest), equalTo(""))
59 fun `page title is retrieved from l10n if page title key is given`() {
60 SoneTemplatePage("path.html", template, "page.title", webInterface).let { page ->
61 whenever(l10n.getString("page.title")).thenReturn("Page Title")
62 assertThat(page.getPageTitle(freenetRequest), equalTo("Page Title"))
67 fun `additional link nodes contain open search link`() {
68 addHttpRequestHeader("Host", "www.example.com")
69 assertThat(page.getAdditionalLinkNodes(freenetRequest), contains(mapOf(
71 "type" to "application/opensearchdescription+xml",
73 "href" to "http://www.example.com/Sone/OpenSearch.xml"
78 fun `style sheets contains sone CSS file`() {
79 assertThat(page.styleSheets, contains("css/sone.css"))
83 fun `shortcut icon is the sone icon`() {
84 assertThat(page.shortcutIcon, equalTo("images/icon.png"))
88 fun `page requires login if require login was specified in the constructor`() {
89 SoneTemplatePage("path.html", template, webInterface, true).let { page ->
90 assertThat(page.requiresLogin(), equalTo(true))
95 fun `page does not require login if require login was not specified in the constructor`() {
96 SoneTemplatePage("path.html", template, webInterface, false).let { page ->
97 assertThat(page.requiresLogin(), equalTo(false))
101 private fun verifyVariableIsSet(name: String, value: Any) = verifyVariableMatches(name, equalTo<Any>(value))
103 private fun <T> verifyVariableMatches(name: String, matcher: Matcher<T>) {
104 page.processTemplate(freenetRequest, templateContext)
105 @Suppress("UNCHECKED_CAST")
106 assertThat(templateContext[name] as T, matcher)
110 fun `preferences are set in template context`() {
111 verifyVariableIsSet("preferences", preferences)
115 fun `current sone is set in template context`() {
116 verifyVariableIsSet("currentSone", currentSone)
120 fun `local sones are set in template context`() {
121 val localSones = listOf(mock<Sone>(), mock<Sone>())
122 whenever(core.localSones).thenReturn(localSones)
123 verifyVariableMatches("localSones", containsInAnyOrder(*localSones.toTypedArray()))
127 fun `freenet request is set in template context`() {
128 verifyVariableIsSet("request", freenetRequest)
132 fun `current version is set in template context`() {
133 verifyVariableIsSet("currentVersion", SonePlugin.getPluginVersion())
137 fun `has latest version is set correctly in template context if true`() {
138 whenever(core.updateChecker.hasLatestVersion()).thenReturn(true)
139 verifyVariableIsSet("hasLatestVersion", true)
143 fun `has latest version is set correctly in template context if false`() {
144 whenever(core.updateChecker.hasLatestVersion()).thenReturn(false)
145 verifyVariableIsSet("hasLatestVersion", false)
149 fun `latest edition is set in template context`() {
150 whenever(core.updateChecker.latestEdition).thenReturn(1234L)
151 verifyVariableIsSet("latestEdition", 1234L)
155 fun `latest version is set in template context`() {
156 whenever(core.updateChecker.latestVersion).thenReturn(Version(1, 2, 3))
157 verifyVariableIsSet("latestVersion", Version(1, 2, 3))
161 fun `latest version time is set in template context`() {
162 whenever(core.updateChecker.latestVersionDate).thenReturn(12345L)
163 verifyVariableIsSet("latestVersionTime", 12345L)
166 private fun createNotification(time: Long) = mock<Notification>().apply {
167 whenever(createdTime).thenReturn(time)
171 fun `notifications are set in template context`() {
172 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
173 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
174 verifyVariableMatches("notifications", contains(notifications[1], notifications[2], notifications[0]))
178 fun `notification hash is set in template context`() {
179 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
180 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
181 verifyVariableIsSet("notificationHash", listOf(notifications[1], notifications[2], notifications[0]).hashCode())
185 fun `handleRequest method is called`() {
187 val page = object : SoneTemplatePage("path.html", template, webInterface, true) {
188 override fun handleRequest(request: FreenetRequest, templateContext: TemplateContext) {
192 page.processTemplate(freenetRequest, templateContext)
193 assertThat(called, equalTo(true))
197 fun `redirect does not happen if login is not required`() {
198 val page = SoneTemplatePage("page.html", template, webInterface, false)
199 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
203 fun `redirect does not happen if sone is logged in`() {
204 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
208 fun `redirect does happen if sone is not logged in`() {
210 request("index.html", GET)
211 assertThat(page.getRedirectTarget(freenetRequest), equalTo("login.html?target=index.html"))
215 fun `redirect does happen with parameters encoded correctly if sone is not logged in`() {
217 request("index.html", GET)
218 addHttpRequestParameter("foo", "b=r")
219 addHttpRequestParameter("baz", "q&o")
220 assertThat(page.getRedirectTarget(freenetRequest), anyOf(
221 equalTo("login.html?target=index.html%3Ffoo%3Db%253Dr%26baz%3Dq%2526o"),
222 equalTo("login.html?target=index.html%3Fbaz%3Dq%2526o%26foo%3Db%253Dr")
227 fun `full access requirement is correctly forwarded from the preferences if false`() {
228 assertThat(page.isFullAccessOnly, equalTo(false))
232 fun `full access requirement is correctly forwarded from the preferences if true`() {
233 core.preferences.isRequireFullAccess = true
234 assertThat(page.isFullAccessOnly, equalTo(true))
238 fun `page is disabled if full access is required but request does not have full access`() {
239 core.preferences.isRequireFullAccess = true
240 assertThat(page.isEnabled(toadletContext), equalTo(false))
244 fun `page is disabled if login is required but there is no current sone`() {
246 assertThat(page.isEnabled(toadletContext), equalTo(false))
250 fun `page is enabled if login is required and there is a current sone`() {
251 assertThat(page.isEnabled(toadletContext), equalTo(true))
255 fun `page is enabled if full access is required and request has full access and login is required and there is a current sone`() {
256 core.preferences.isRequireFullAccess = true
257 whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
258 assertThat(page.isEnabled(toadletContext), equalTo(true))
262 fun `page is enabled if no full access is required and login is not required`() {
263 SoneTemplatePage("path.html", template, webInterface, false).let { page ->
264 assertThat(page.isEnabled(toadletContext), equalTo(true))