1 package net.pterodactylus.sone.web.pages
3 import com.google.common.eventbus.EventBus
4 import freenet.clients.http.ToadletContext
5 import freenet.support.api.HTTPRequest
6 import net.pterodactylus.sone.core.Preferences
7 import net.pterodactylus.sone.data.Album
8 import net.pterodactylus.sone.data.Image
9 import net.pterodactylus.sone.data.Post
10 import net.pterodactylus.sone.data.PostReply
11 import net.pterodactylus.sone.data.Sone
12 import net.pterodactylus.sone.test.deepMock
13 import net.pterodactylus.sone.test.get
14 import net.pterodactylus.sone.test.mock
15 import net.pterodactylus.sone.test.whenever
16 import net.pterodactylus.sone.utils.asList
17 import net.pterodactylus.sone.utils.asOptional
18 import net.pterodactylus.sone.web.WebInterface
19 import net.pterodactylus.sone.web.page.FreenetRequest
20 import net.pterodactylus.sone.web.page.FreenetTemplatePage.RedirectException
21 import net.pterodactylus.util.template.Template
22 import net.pterodactylus.util.template.TemplateContext
23 import net.pterodactylus.util.web.Method
24 import net.pterodactylus.util.web.Method.GET
25 import org.junit.Assert.fail
26 import org.junit.Before
27 import org.mockito.ArgumentMatchers.anyBoolean
28 import org.mockito.ArgumentMatchers.anyInt
29 import org.mockito.ArgumentMatchers.anyLong
30 import org.mockito.ArgumentMatchers.anyString
31 import org.mockito.ArgumentMatchers.eq
33 import java.nio.charset.Charset
34 import kotlin.text.Charsets.UTF_8
37 * Base class for web page tests.
39 abstract class WebPageTest2(pageSupplier: (Template, WebInterface) -> SoneTemplatePage) {
41 protected val currentSone = mock<Sone>()
42 protected val template = mock<Template>()
43 protected val webInterface = deepMock<WebInterface>()
44 protected val core = webInterface.core!!
45 private val eventBus = mock<EventBus>()
46 protected val preferences = Preferences(eventBus)
47 protected val l10n = webInterface.l10n!!
49 protected val page by lazy { pageSupplier(template, webInterface) }
50 private val httpRequest = mock<HTTPRequest>()
51 protected val freenetRequest = mock<FreenetRequest>()
52 protected val templateContext = TemplateContext()
54 protected val toadletContext = deepMock<ToadletContext>()
55 private val requestHeaders = mutableMapOf<String, String>()
56 private val getRequestParameters = mutableMapOf<String, MutableList<String>>()
57 private val postRequestParameters = mutableMapOf<String, ByteArray>()
58 private val allSones = mutableMapOf<String, Sone>()
59 private val localSones = mutableMapOf<String, Sone>()
60 private val allPosts = mutableMapOf<String, Post>()
61 private val allPostReplies = mutableMapOf<String, PostReply>()
62 private val perPostReplies = mutableMapOf<String, PostReply>()
63 private val allAlbums = mutableMapOf<String, Album>()
64 private val allImages = mutableMapOf<String, Image>()
65 private val translations = mutableMapOf<String, String>()
69 whenever(core.preferences).thenReturn(preferences)
70 whenever(core.sones).then { allSones.values }
71 whenever(core.getSone(anyString())).then { allSones[it[0]].asOptional() }
72 whenever(core.localSones).then { localSones.values }
73 whenever(core.getLocalSone(anyString())).then { localSones[it[0]] }
74 whenever(core.getPost(anyString())).then { allPosts[it[0]].asOptional() }
75 whenever(core.getPostReply(anyString())).then { allPostReplies[it[0]].asOptional() }
76 whenever(core.getReplies(anyString())).then { perPostReplies[it[0]].asList() }
77 whenever(core.getAlbum(anyString())).then { allAlbums[it[0]] }
78 whenever(core.getImage(anyString())).then { allImages[it[0]]}
79 whenever(core.getImage(anyString(), anyBoolean())).then { allImages[it[0]]}
83 fun setupWebInterface() {
84 whenever(webInterface.getCurrentSoneCreatingSession(eq(toadletContext))).thenReturn(currentSone)
85 whenever(webInterface.getCurrentSone(eq(toadletContext), anyBoolean())).thenReturn(currentSone)
86 whenever(webInterface.getCurrentSoneWithoutCreatingSession(eq(toadletContext))).thenReturn(currentSone)
87 whenever(webInterface.getNotifications(currentSone)).thenReturn(emptyList())
91 fun setupHttpRequest() {
92 whenever(httpRequest.method).thenReturn("GET")
93 whenever(httpRequest.getHeader(anyString())).then { requestHeaders[it.get<String>(0).toLowerCase()] }
94 whenever(httpRequest.hasParameters()).then { getRequestParameters.isNotEmpty() }
95 whenever(httpRequest.parameterNames).then { getRequestParameters.keys }
96 whenever(httpRequest.isParameterSet(anyString())).then { it[0] in getRequestParameters }
97 whenever(httpRequest.getParam(anyString())).then { getRequestParameters[it[0]]?.firstOrNull() ?: "" }
98 whenever(httpRequest.getParam(anyString(), anyString())).then { getRequestParameters[it[0]]?.firstOrNull() ?: it[1] }
99 whenever(httpRequest.getIntParam(anyString())).then { getRequestParameters[it[0]]?.first()?.toIntOrNull() ?: 0 }
100 whenever(httpRequest.getIntParam(anyString(), anyInt())).then { getRequestParameters[it[0]]?.first()?.toIntOrNull() ?: it[1] }
101 whenever(httpRequest.getLongParam(anyString(), anyLong())).then { getRequestParameters[it[0]]?.first()?.toLongOrNull() ?: it[1] }
102 whenever(httpRequest.getMultipleParam(anyString())).then { getRequestParameters[it[0]]?.toTypedArray() ?: emptyArray<String>() }
103 whenever(httpRequest.getMultipleIntParam(anyString())).then { getRequestParameters[it[0]]?.map { it.toIntOrNull() ?: 0 } ?: emptyArray<Int>() }
104 whenever(httpRequest.getPartAsStringFailsafe(anyString(), anyInt())).then { postRequestParameters[it[0]]?.decode()?.take(it[1]) ?: "" }
107 private fun ByteArray.decode(charset: Charset = UTF_8) = String(this, charset)
110 fun setupFreenetRequest() {
111 whenever(freenetRequest.method).thenReturn(GET)
112 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
113 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
117 fun setupTranslations() {
118 whenever(l10n.getString(anyString())).then { translations[it[0]] ?: it[0] }
121 fun setMethod(method: Method) {
122 whenever(httpRequest.method).thenReturn(method.name)
123 whenever(freenetRequest.method).thenReturn(method)
126 fun request(uri: String) {
127 whenever(httpRequest.path).thenReturn(uri)
128 whenever(freenetRequest.uri).thenReturn(URI(uri))
131 fun addHttpRequestHeader(name: String, value: String) {
132 requestHeaders[name.toLowerCase()] = value
135 fun addHttpRequestParameter(name: String, value: String) {
136 getRequestParameters[name] = getRequestParameters.getOrElse(name) { mutableListOf<String>() }.apply { add(value) }
139 fun addHttpRequestPart(name: String, value: String) {
140 postRequestParameters[name] = value.toByteArray(UTF_8)
143 fun unsetCurrentSone() {
144 whenever(webInterface.getCurrentSoneCreatingSession(eq(toadletContext))).thenReturn(null)
145 whenever(webInterface.getCurrentSone(eq(toadletContext), anyBoolean())).thenReturn(null)
146 whenever(webInterface.getCurrentSoneWithoutCreatingSession(eq(toadletContext))).thenReturn(null)
149 fun addSone(id: String, sone: Sone) {
153 fun addLocalSone(id: String, localSone: Sone) {
154 localSones[id] = localSone
157 fun addPost(id: String, post: Post) {
161 fun addPostReply(id: String, postReply: PostReply) {
162 allPostReplies[id] = postReply
163 postReply.postId?.also { perPostReplies[it] = postReply }
166 fun addAlbum(id: String, album: Album) {
167 allAlbums[id] = album
170 fun addImage(id: String, image: Image) {
171 allImages[id] = image
174 fun addTranslation(key: String, value: String) {
175 translations[key] = value
178 fun verifyNoRedirect(assertions: () -> Unit) {
179 var caughtException: Exception? = null
181 page.handleRequest(freenetRequest, templateContext)
182 } catch (e: Exception) {
185 caughtException?.run { throw this } ?: assertions()
188 fun verifyRedirect(target: String, assertions: () -> Unit = {}) {
190 page.handleRequest(freenetRequest, templateContext)
192 } catch (re: RedirectException) {
193 if (re.target != target) {
197 } catch (e: Exception) {