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.isPartSet(anyString())).then { it[0] in postRequestParameters }
105 whenever(httpRequest.getPartAsStringFailsafe(anyString(), anyInt())).then { postRequestParameters[it[0]]?.decode()?.take(it[1]) ?: "" }
108 private fun ByteArray.decode(charset: Charset = UTF_8) = String(this, charset)
111 fun setupFreenetRequest() {
112 whenever(freenetRequest.method).thenReturn(GET)
113 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
114 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
118 fun setupTranslations() {
119 whenever(l10n.getString(anyString())).then { translations[it[0]] ?: it[0] }
122 fun setMethod(method: Method) {
123 whenever(httpRequest.method).thenReturn(method.name)
124 whenever(freenetRequest.method).thenReturn(method)
127 fun request(uri: String) {
128 whenever(httpRequest.path).thenReturn(uri)
129 whenever(freenetRequest.uri).thenReturn(URI(uri))
132 fun addHttpRequestHeader(name: String, value: String) {
133 requestHeaders[name.toLowerCase()] = value
136 fun addHttpRequestParameter(name: String, value: String) {
137 getRequestParameters[name] = getRequestParameters.getOrElse(name) { mutableListOf<String>() }.apply { add(value) }
140 fun addHttpRequestPart(name: String, value: String) {
141 postRequestParameters[name] = value.toByteArray(UTF_8)
144 fun unsetCurrentSone() {
145 whenever(webInterface.getCurrentSoneCreatingSession(eq(toadletContext))).thenReturn(null)
146 whenever(webInterface.getCurrentSone(eq(toadletContext), anyBoolean())).thenReturn(null)
147 whenever(webInterface.getCurrentSoneWithoutCreatingSession(eq(toadletContext))).thenReturn(null)
150 fun addSone(id: String, sone: Sone) {
154 fun addLocalSone(id: String, localSone: Sone) {
155 localSones[id] = localSone
158 fun addPost(id: String, post: Post) {
162 fun addPostReply(id: String, postReply: PostReply) {
163 allPostReplies[id] = postReply
164 postReply.postId?.also { perPostReplies[it] = postReply }
167 fun addAlbum(id: String, album: Album) {
168 allAlbums[id] = album
171 fun addImage(id: String, image: Image) {
172 allImages[id] = image
175 fun addTranslation(key: String, value: String) {
176 translations[key] = value
179 fun verifyNoRedirect(assertions: () -> Unit) {
180 var caughtException: Exception? = null
182 page.handleRequest(freenetRequest, templateContext)
183 } catch (e: Exception) {
186 caughtException?.run { throw this } ?: assertions()
189 fun verifyRedirect(target: String, assertions: () -> Unit = {}) {
191 page.handleRequest(freenetRequest, templateContext)
193 } catch (re: RedirectException) {
194 if (re.target != target) {
198 } catch (e: Exception) {