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 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
19 import org.mockito.Mockito.verify
22 * Unit test for [SoneTemplatePage].
24 class SoneTemplatePageTest : WebPageTest() {
26 private val preferences by lazy { core.preferences!! }
27 private val page = object : SoneTemplatePage("path.html", template, webInterface, true) {}
30 fun `current sone is retrieved from web interface`() {
31 assertThat(page.getCurrentSone(toadletContext), equalTo(currentSone))
35 fun `retrieving current sone without creation is forwarded to web interface`() {
37 whenever(webInterface.getCurrentSone(toadletContext, false)).thenReturn(it)
38 assertThat(page.getCurrentSone(toadletContext, false), equalTo(it))
43 fun `setting the current sone is forwarded to web interface`() {
45 page.setCurrentSone(toadletContext, it)
46 verify(webInterface).setCurrentSone(toadletContext, it)
51 fun `page title is empty string if no page title key was given`() {
52 SoneTemplatePage("path.html", template, null, webInterface).let { page ->
53 assertThat(page.getPageTitle(freenetRequest), equalTo(""))
58 fun `page title is retrieved from l10n if page title key is given`() {
59 SoneTemplatePage("path.html", template, "page.title", webInterface).let { page ->
60 whenever(l10n.getString("page.title")).thenReturn("Page Title")
61 assertThat(page.getPageTitle(freenetRequest), equalTo("Page Title"))
66 fun `additional link nodes contain open search link`() {
67 addHttpRequestHeader("Host", "www.example.com")
68 assertThat(page.getAdditionalLinkNodes(freenetRequest), contains(mapOf(
70 "type" to "application/opensearchdescription+xml",
72 "href" to "http://www.example.com/Sone/OpenSearch.xml"
77 fun `style sheets contains sone CSS file`() {
78 assertThat(page.styleSheets, contains("css/sone.css"))
82 fun `shortcut icon is the sone icon`() {
83 assertThat(page.shortcutIcon, equalTo("images/icon.png"))
87 fun `page requires login if require login was specified in the constructor`() {
88 SoneTemplatePage("path.html", template, webInterface, true).let { page ->
89 assertThat(page.requiresLogin(), equalTo(true))
94 fun `page does not require login if require login was not specified in the constructor`() {
95 SoneTemplatePage("path.html", template, webInterface, false).let { page ->
96 assertThat(page.requiresLogin(), equalTo(false))
100 private fun verifyVariableIsSet(name: String, value: Any) = verifyVariableMatches(name, equalTo<Any>(value))
102 private fun <T> verifyVariableMatches(name: String, matcher: Matcher<T>) {
103 page.processTemplate(freenetRequest, templateContext)
104 @Suppress("UNCHECKED_CAST")
105 assertThat(templateContext[name] as T, matcher)
109 fun `preferences are set in template context`() {
110 verifyVariableIsSet("preferences", preferences)
114 fun `current sone is set in template context`() {
115 verifyVariableIsSet("currentSone", currentSone)
119 fun `local sones are set in template context`() {
120 val localSones = listOf(mock<Sone>(), mock<Sone>())
121 whenever(core.localSones).thenReturn(localSones)
122 verifyVariableMatches("localSones", containsInAnyOrder(*localSones.toTypedArray()))
126 fun `freenet request is set in template context`() {
127 verifyVariableIsSet("request", freenetRequest)
131 fun `current version is set in template context`() {
132 verifyVariableIsSet("currentVersion", SonePlugin.getPluginVersion())
136 fun `has latest version is set correctly in template context if true`() {
137 whenever(core.updateChecker.hasLatestVersion()).thenReturn(true)
138 verifyVariableIsSet("hasLatestVersion", true)
142 fun `has latest version is set correctly in template context if false`() {
143 whenever(core.updateChecker.hasLatestVersion()).thenReturn(false)
144 verifyVariableIsSet("hasLatestVersion", false)
148 fun `latest edition is set in template context`() {
149 whenever(core.updateChecker.latestEdition).thenReturn(1234L)
150 verifyVariableIsSet("latestEdition", 1234L)
154 fun `latest version is set in template context`() {
155 whenever(core.updateChecker.latestVersion).thenReturn(Version(1, 2, 3))
156 verifyVariableIsSet("latestVersion", Version(1, 2, 3))
160 fun `latest version time is set in template context`() {
161 whenever(core.updateChecker.latestVersionDate).thenReturn(12345L)
162 verifyVariableIsSet("latestVersionTime", 12345L)
165 private fun createNotification(time: Long) = mock<Notification>().apply {
166 whenever(createdTime).thenReturn(time)
170 fun `notifications are set in template context`() {
171 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
172 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
173 verifyVariableMatches("notifications", contains(notifications[1], notifications[2], notifications[0]))
177 fun `notification hash is set in template context`() {
178 val notifications = listOf(createNotification(3000), createNotification(1000), createNotification(2000))
179 whenever(webInterface.getNotifications(currentSone)).thenReturn(notifications)
180 verifyVariableIsSet("notificationHash", listOf(notifications[1], notifications[2], notifications[0]).hashCode())
184 fun `handleRequest method is called`() {
186 val page = object : SoneTemplatePage("path.html", template, webInterface, true) {
187 override fun handleRequest(request: FreenetRequest, templateContext: TemplateContext) {
191 page.processTemplate(freenetRequest, templateContext)
192 assertThat(called, equalTo(true))
196 fun `redirect does not happen if login is not required`() {
197 val page = SoneTemplatePage("page.html", template, webInterface, false)
198 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
202 fun `redirect does not happen if sone is logged in`() {
203 assertThat(page.getRedirectTarget(freenetRequest), nullValue())
207 fun `redirect does happen if sone is not logged in`() {
209 request("index.html")
210 assertThat(page.getRedirectTarget(freenetRequest), equalTo("login.html?target=index.html"))
214 fun `redirect does happen with parameters encoded correctly if sone is not logged in`() {
216 request("index.html")
217 addHttpRequestParameter("foo", "b=r")
218 addHttpRequestParameter("baz", "q&o")
219 assertThat(page.getRedirectTarget(freenetRequest), anyOf(
220 equalTo("login.html?target=index.html%3Ffoo%3Db%253Dr%26baz%3Dq%2526o"),
221 equalTo("login.html?target=index.html%3Fbaz%3Dq%2526o%26foo%3Db%253Dr")
226 fun `full access requirement is correctly forwarded from the preferences if false`() {
227 assertThat(page.isFullAccessOnly, equalTo(false))
231 fun `full access requirement is correctly forwarded from the preferences if true`() {
232 core.preferences.isRequireFullAccess = true
233 assertThat(page.isFullAccessOnly, equalTo(true))
237 fun `page is disabled if full access is required but request does not have full access`() {
238 core.preferences.isRequireFullAccess = true
239 assertThat(page.isEnabled(toadletContext), equalTo(false))
243 fun `page is disabled if login is required but there is no current sone`() {
245 assertThat(page.isEnabled(toadletContext), equalTo(false))
249 fun `page is enabled if login is required and there is a current sone`() {
250 assertThat(page.isEnabled(toadletContext), equalTo(true))
254 fun `page is enabled if full access is required and request has full access and login is required and there is a current sone`() {
255 core.preferences.isRequireFullAccess = true
256 whenever(toadletContext.isAllowedFullAccess).thenReturn(true)
257 assertThat(page.isEnabled(toadletContext), equalTo(true))
261 fun `page is enabled if no full access is required and login is not required`() {
262 SoneTemplatePage("path.html", template, webInterface, false).let { page ->
263 assertThat(page.isEnabled(toadletContext), equalTo(true))