1 package net.pterodactylus.sone.web.pages
3 import net.pterodactylus.sone.data.*
4 import net.pterodactylus.sone.main.*
5 import net.pterodactylus.sone.test.*
6 import net.pterodactylus.sone.web.page.*
7 import net.pterodactylus.util.notify.*
8 import net.pterodactylus.util.template.*
9 import net.pterodactylus.util.version.Version
11 import org.hamcrest.MatcherAssert.*
12 import org.hamcrest.Matchers.*
16 * Unit test for [SoneTemplatePage].
18 class SoneTemplatePageTest : WebPageTest({ webInterface, loaders, templateRenderer -> object : SoneTemplatePage(webInterface, loaders, templateRenderer, requiresLogin = true) {} }) {
25 fun `page title is empty string if no page title key was given`() {
26 SoneTemplatePage(webInterface, loaders, templateRenderer, requiresLogin = false).let { page ->
27 assertThat(page.getPageTitle(soneRequest), equalTo(""))
32 fun `page title is retrieved from l10n if page title key is given`() {
33 SoneTemplatePage(webInterface, loaders, templateRenderer, pageTitleKey = "page.title", requiresLogin = false).let { page ->
34 addTranslation("page.title", "Page Title")
35 assertThat(page.getPageTitle(soneRequest), equalTo("Page Title"))
40 fun `additional link nodes contain open search link`() {
41 addHttpRequestHeader("Host", "www.example.com")
42 assertThat(page.getAdditionalLinkNodes(freenetRequest), contains(mapOf(
44 "type" to "application/opensearchdescription+xml",
46 "href" to "http://www.example.com/Sone/OpenSearch.xml"
51 fun `style sheets contains sone CSS file`() {
52 assertThat(page.styleSheets, contains("css/sone.css"))
56 fun `shortcut icon is the sone icon`() {
57 assertThat(page.shortcutIcon, equalTo("images/icon.png"))
60 private fun verifyVariableIsSet(name: String, value: Any) = verifyVariableMatches(name, equalTo<Any>(value))
62 private fun <T> verifyVariableMatches(name: String, matcher: Matcher<T>) {
63 page.processTemplate(freenetRequest, templateContext)
64 @Suppress("UNCHECKED_CAST")
65 assertThat(templateContext[name] as T, matcher)
69 fun `preferences are set in template context`() {
70 verifyVariableIsSet("preferences", preferences)
74 fun `current sone is set in template context`() {
75 verifyVariableIsSet("currentSone", currentSone)
79 fun `local sones are set in template context`() {
80 val localSones = listOf(mock<Sone>(), mock())
81 whenever(core.localSones).thenReturn(localSones)
82 verifyVariableMatches("localSones", containsInAnyOrder(*localSones.toTypedArray()))
86 fun `freenet request is set in template context`() {
87 verifyVariableIsSet("request", freenetRequest)
91 fun `current version is set in template context`() {
92 verifyVariableIsSet("currentVersion", SonePlugin.getPluginVersion())
96 fun `has latest version is set correctly in template context if true`() {
97 whenever(core.updateChecker.hasLatestVersion()).thenReturn(true)
98 verifyVariableIsSet("hasLatestVersion", true)
102 fun `has latest version is set correctly in template context if false`() {
103 whenever(core.updateChecker.hasLatestVersion()).thenReturn(false)
104 verifyVariableIsSet("hasLatestVersion", false)
108 fun `latest edition is set in template context`() {
109 whenever(core.updateChecker.latestEdition).thenReturn(1234L)
110 verifyVariableIsSet("latestEdition", 1234L)
114 fun `latest version is set in template context`() {
115 whenever(core.updateChecker.latestVersion).thenReturn(Version(1, 2, 3))
116 verifyVariableIsSet("latestVersion", Version(1, 2, 3))
120 fun `latest version time is set in template context`() {
121 whenever(core.updateChecker.latestVersionDate).thenReturn(12345L)
122 verifyVariableIsSet("latestVersionTime", 12345L)
125 private fun createNotification(time: Long) = mock<Notification>().apply {
126 whenever(createdTime).thenReturn(time)
130 fun `notifications are set in template context`() {
131 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
132 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
133 verifyVariableMatches("notifications", contains(notifications[1], notifications[2], notifications[0]))
137 fun `notification hash is set in template context`() {
138 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
139 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
140 verifyVariableIsSet("notificationHash", listOf(notifications[1], notifications[2], notifications[0]).hashCode())
144 fun `handleRequest method is called`() {
146 val page = object : SoneTemplatePage(webInterface, loaders, templateRenderer, requiresLogin = true) {
147 override fun handleRequest(freenetRequest: FreenetRequest, templateContext: TemplateContext) {
151 page.processTemplate(freenetRequest, templateContext)
152 assertThat(called, equalTo(true))
156 fun `redirect does not happen if login is not required`() {
157 val page = SoneTemplatePage(webInterface, loaders, templateRenderer, requiresLogin = false)
158 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
162 fun `redirect does not happen if sone is logged in`() {
163 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
167 fun `redirect does happen if sone is not logged in`() {
169 assertThat(page.getRedirectTarget(freenetRequest), equalTo("login.html?target=index.html"))
173 fun `redirect does happen with parameters encoded correctly if sone is not logged in`() {
175 addHttpRequestParameter("foo", "b=r")
176 addHttpRequestParameter("baz", "q&o")
177 assertThat(page.getRedirectTarget(freenetRequest), anyOf(
178 equalTo("login.html?target=index.html%3Ffoo%3Db%253Dr%26baz%3Dq%2526o"),
179 equalTo("login.html?target=index.html%3Fbaz%3Dq%2526o%26foo%3Db%253Dr")
184 fun `page is disabled if full access is required but request does not have full access`() {
185 core.preferences.newRequireFullAccess = true
186 assertThat(page.isEnabled(toadletContext), equalTo(false))
190 fun `page is disabled if login is required but there is no current sone`() {
192 assertThat(page.isEnabled(toadletContext), equalTo(false))
196 fun `page is enabled if login is required and there is a current sone`() {
197 assertThat(page.isEnabled(toadletContext), equalTo(true))
201 fun `page is enabled if full access is required and request has full access and login is required and there is a current sone`() {
202 core.preferences.newRequireFullAccess = true
203 whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
204 assertThat(page.isEnabled(toadletContext), equalTo(true))
208 fun `page is enabled if no full access is required and login is not required`() {
209 SoneTemplatePage(webInterface, loaders, templateRenderer, requiresLogin = false).let { page ->
210 assertThat(page.isEnabled(toadletContext), equalTo(true))
215 fun `handle request with sone request is called`() {
217 val page = object : SoneTemplatePage(webInterface, loaders, templateRenderer) {
218 override fun handleRequest(soneRequest: SoneRequest, templateContext: TemplateContext) {
222 page.processTemplate(freenetRequest, templateContext)
223 assertThat(called, equalTo(true))