1 package net.pterodactylus.sone.web
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 // @get:JvmName("getPage1")
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 with creation is forwarded to web interface`() {
38 whenever(webInterface.getCurrentSone(toadletContext, true)).thenReturn(it)
39 assertThat(page.getCurrentSone(toadletContext, true), equalTo(it))
44 fun `retrieving current sone without creation is forwarded to web interface`() {
46 whenever(webInterface.getCurrentSone(toadletContext, false)).thenReturn(it)
47 assertThat(page.getCurrentSone(toadletContext, false), equalTo(it))
52 fun `setting the current sone is forwarded to web interface`() {
54 page.setCurrentSone(toadletContext, it)
55 verify(webInterface).setCurrentSone(toadletContext, it)
60 fun `page title is empty string if no page title key was given`() {
61 SoneTemplatePage("path.html", template, null, webInterface).let { page ->
62 assertThat(page.getPageTitle(freenetRequest), equalTo(""))
67 fun `page title is retrieved from l10n if page title key is given`() {
68 SoneTemplatePage("path.html", template, "page.title", webInterface).let { page ->
69 whenever(l10n.getString("page.title")).thenReturn("Page Title")
70 assertThat(page.getPageTitle(freenetRequest), equalTo("Page Title"))
75 fun `additional link nodes contain open search link`() {
76 addHttpRequestHeader("Host", "www.example.com")
77 assertThat(page.getAdditionalLinkNodes(freenetRequest), contains(mapOf(
79 "type" to "application/opensearchdescription+xml",
81 "href" to "http://www.example.com/Sone/OpenSearch.xml"
86 fun `style sheets contains sone CSS file`() {
87 assertThat(page.styleSheets, contains("css/sone.css"))
91 fun `shortcut icon is the sone icon`() {
92 assertThat(page.shortcutIcon, equalTo("images/icon.png"))
96 fun `page requires login if require login was specified in the constructor`() {
97 SoneTemplatePage("path.html", template, webInterface, true).let { page ->
98 assertThat(page.requiresLogin(), equalTo(true))
103 fun `page does not require login if require login was not specified in the constructor`() {
104 SoneTemplatePage("path.html", template, webInterface, false).let { page ->
105 assertThat(page.requiresLogin(), equalTo(false))
109 private fun verifyVariableIsSet(name: String, value: Any) = verifyVariableMatches(name, equalTo<Any>(value))
111 private fun <T> verifyVariableMatches(name: String, matcher: Matcher<T>) {
112 page.processTemplate(freenetRequest, templateContext)
113 @Suppress("UNCHECKED_CAST")
114 assertThat(templateContext[name] as T, matcher)
118 fun `core is set in template context`() {
119 verifyVariableIsSet("core", core)
123 fun `current sone is set in template context`() {
124 verifyVariableIsSet("currentSone", currentSone)
128 fun `local sones are set in template context`() {
129 val localSones = listOf(mock<Sone>(), mock<Sone>())
130 whenever(core.localSones).thenReturn(localSones)
131 verifyVariableMatches("localSones", containsInAnyOrder(*localSones.toTypedArray()))
135 fun `freenet request is set in template context`() {
136 verifyVariableIsSet("request", freenetRequest)
140 fun `current version is set in template context`() {
141 verifyVariableIsSet("currentVersion", SonePlugin.getPluginVersion())
145 fun `has latest version is set correctly in template context if true`() {
146 whenever(core.updateChecker.hasLatestVersion()).thenReturn(true)
147 verifyVariableIsSet("hasLatestVersion", true)
151 fun `has latest version is set correctly in template context if false`() {
152 whenever(core.updateChecker.hasLatestVersion()).thenReturn(false)
153 verifyVariableIsSet("hasLatestVersion", false)
157 fun `latest edition is set in template context`() {
158 whenever(core.updateChecker.latestEdition).thenReturn(1234L)
159 verifyVariableIsSet("latestEdition", 1234L)
163 fun `latest version is set in template context`() {
164 whenever(core.updateChecker.latestVersion).thenReturn(Version(1, 2, 3))
165 verifyVariableIsSet("latestVersion", Version(1, 2, 3))
169 fun `latest version time is set in template context`() {
170 whenever(core.updateChecker.latestVersionDate).thenReturn(12345L)
171 verifyVariableIsSet("latestVersionTime", 12345L)
174 private fun createNotification(time: Long) = mock<Notification>().apply {
175 whenever(createdTime).thenReturn(time)
179 fun `notifications are set in template context`() {
180 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
181 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
182 verifyVariableMatches("notifications", contains(notifications[1], notifications[2], notifications[0]))
186 fun `notification hash is set in template context`() {
187 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
188 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
189 verifyVariableIsSet("notificationHash", listOf(notifications[1], notifications[2], notifications[0]).hashCode())
193 fun `handleRequest method is called`() {
195 val page = object : SoneTemplatePage("path.html", template, webInterface, true) {
196 override fun handleRequest(request: FreenetRequest, templateContext: TemplateContext) {
200 page.processTemplate(freenetRequest, templateContext)
201 assertThat(called, equalTo(true))
205 fun `redirect does not happen if login is not required`() {
206 val page = SoneTemplatePage("page.html", template, webInterface, false)
207 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
211 fun `redirect does not happen if sone is logged in`() {
212 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
216 fun `redirect does happen if sone is not logged in`() {
218 request("index.html", GET)
219 assertThat(page.getRedirectTarget(freenetRequest), equalTo("login.html?target=index.html"))
223 fun `redirect does happen with parameters encoded correctly if sone is not logged in`() {
225 request("index.html", GET)
226 addHttpRequestParameter("foo", "b=r")
227 addHttpRequestParameter("baz", "q&o")
228 assertThat(page.getRedirectTarget(freenetRequest), anyOf(
229 equalTo("login.html?target=index.html%3Ffoo%3Db%253Dr%26baz%3Dq%2526o"),
230 equalTo("login.html?target=index.html%3Fbaz%3Dq%2526o%26foo%3Db%253Dr")
235 fun `full access requirement is correctly forwarded from the preferences if false`() {
236 assertThat(page.isFullAccessOnly, equalTo(false))
240 fun `full access requirement is correctly forwarded from the preferences if true`() {
241 core.preferences.isRequireFullAccess = true
242 assertThat(page.isFullAccessOnly, equalTo(true))
246 fun `page is disabled if full access is required but request does not have full access`() {
247 core.preferences.isRequireFullAccess = true
248 assertThat(page.isEnabled(toadletContext), equalTo(false))
252 fun `page is disabled if login is required but there is no current sone`() {
254 assertThat(page.isEnabled(toadletContext), equalTo(false))
258 fun `page is enabled if login is required and there is a current sone`() {
259 assertThat(page.isEnabled(toadletContext), equalTo(true))
263 fun `page is enabled if full access is required and request has full access and login is required and there is a current sone`() {
264 core.preferences.isRequireFullAccess = true
265 whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
266 assertThat(page.isEnabled(toadletContext), equalTo(true))
270 fun `page is enabled if no full access is required and login is not required`() {
271 SoneTemplatePage("path.html", template, webInterface, false).let { page ->
272 assertThat(page.isEnabled(toadletContext), equalTo(true))