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.freenet.wot.OwnIdentity
13 import net.pterodactylus.sone.test.deepMock
14 import net.pterodactylus.sone.test.get
15 import net.pterodactylus.sone.test.mock
16 import net.pterodactylus.sone.test.whenever
17 import net.pterodactylus.sone.utils.asList
18 import net.pterodactylus.sone.utils.asOptional
19 import net.pterodactylus.sone.web.WebInterface
20 import net.pterodactylus.sone.web.page.FreenetRequest
21 import net.pterodactylus.sone.web.page.FreenetTemplatePage.RedirectException
22 import net.pterodactylus.util.template.Template
23 import net.pterodactylus.util.template.TemplateContext
24 import net.pterodactylus.util.web.Method
25 import net.pterodactylus.util.web.Method.GET
26 import org.junit.Assert.fail
27 import org.junit.Before
28 import org.mockito.ArgumentMatchers.anyBoolean
29 import org.mockito.ArgumentMatchers.anyInt
30 import org.mockito.ArgumentMatchers.anyLong
31 import org.mockito.ArgumentMatchers.anyString
32 import org.mockito.ArgumentMatchers.eq
34 import java.nio.charset.Charset
35 import kotlin.text.Charsets.UTF_8
38 * Base class for web page tests.
40 abstract class WebPageTest2(pageSupplier: (Template, WebInterface) -> SoneTemplatePage) {
42 protected val currentSone = mock<Sone>()
43 protected val template = mock<Template>()
44 protected val webInterface = deepMock<WebInterface>()
45 protected val core = webInterface.core!!
46 private val eventBus = mock<EventBus>()
47 protected val preferences = Preferences(eventBus)
48 protected val l10n = webInterface.l10n!!
50 protected val page by lazy { pageSupplier(template, webInterface) }
51 private val httpRequest = mock<HTTPRequest>()
52 protected val freenetRequest = mock<FreenetRequest>()
53 protected val templateContext = TemplateContext()
55 protected val toadletContext = deepMock<ToadletContext>()
56 private val requestHeaders = mutableMapOf<String, String>()
57 private val getRequestParameters = mutableMapOf<String, MutableList<String>>()
58 private val postRequestParameters = mutableMapOf<String, ByteArray>()
59 private val ownIdentities = mutableSetOf<OwnIdentity>()
60 private val allSones = mutableMapOf<String, Sone>()
61 private val localSones = mutableMapOf<String, Sone>()
62 private val allPosts = mutableMapOf<String, Post>()
63 private val allPostReplies = mutableMapOf<String, PostReply>()
64 private val perPostReplies = mutableMapOf<String, PostReply>()
65 private val allAlbums = mutableMapOf<String, Album>()
66 private val allImages = mutableMapOf<String, Image>()
67 private val translations = mutableMapOf<String, String>()
71 whenever(core.preferences).thenReturn(preferences)
72 whenever(core.identityManager.allOwnIdentities).then { ownIdentities }
73 whenever(core.sones).then { allSones.values }
74 whenever(core.getSone(anyString())).then { allSones[it[0]].asOptional() }
75 whenever(core.localSones).then { localSones.values }
76 whenever(core.getLocalSone(anyString())).then { localSones[it[0]] }
77 whenever(core.getPost(anyString())).then { allPosts[it[0]].asOptional() }
78 whenever(core.getPostReply(anyString())).then { allPostReplies[it[0]].asOptional() }
79 whenever(core.getReplies(anyString())).then { perPostReplies[it[0]].asList() }
80 whenever(core.getAlbum(anyString())).then { allAlbums[it[0]] }
81 whenever(core.getImage(anyString())).then { allImages[it[0]]}
82 whenever(core.getImage(anyString(), anyBoolean())).then { allImages[it[0]]}
86 fun setupWebInterface() {
87 whenever(webInterface.getCurrentSoneCreatingSession(eq(toadletContext))).thenReturn(currentSone)
88 whenever(webInterface.getCurrentSone(eq(toadletContext), anyBoolean())).thenReturn(currentSone)
89 whenever(webInterface.getCurrentSoneWithoutCreatingSession(eq(toadletContext))).thenReturn(currentSone)
90 whenever(webInterface.getNotifications(currentSone)).thenReturn(emptyList())
94 fun setupHttpRequest() {
95 whenever(httpRequest.method).thenReturn("GET")
96 whenever(httpRequest.getHeader(anyString())).then { requestHeaders[it.get<String>(0).toLowerCase()] }
97 whenever(httpRequest.hasParameters()).then { getRequestParameters.isNotEmpty() }
98 whenever(httpRequest.parameterNames).then { getRequestParameters.keys }
99 whenever(httpRequest.isParameterSet(anyString())).then { it[0] in getRequestParameters }
100 whenever(httpRequest.getParam(anyString())).then { getRequestParameters[it[0]]?.firstOrNull() ?: "" }
101 whenever(httpRequest.getParam(anyString(), anyString())).then { getRequestParameters[it[0]]?.firstOrNull() ?: it[1] }
102 whenever(httpRequest.getIntParam(anyString())).then { getRequestParameters[it[0]]?.first()?.toIntOrNull() ?: 0 }
103 whenever(httpRequest.getIntParam(anyString(), anyInt())).then { getRequestParameters[it[0]]?.first()?.toIntOrNull() ?: it[1] }
104 whenever(httpRequest.getLongParam(anyString(), anyLong())).then { getRequestParameters[it[0]]?.first()?.toLongOrNull() ?: it[1] }
105 whenever(httpRequest.getMultipleParam(anyString())).then { getRequestParameters[it[0]]?.toTypedArray() ?: emptyArray<String>() }
106 whenever(httpRequest.getMultipleIntParam(anyString())).then { getRequestParameters[it[0]]?.map { it.toIntOrNull() ?: 0 } ?: emptyArray<Int>() }
107 whenever(httpRequest.isPartSet(anyString())).then { it[0] in postRequestParameters }
108 whenever(httpRequest.getPartAsStringFailsafe(anyString(), anyInt())).then { postRequestParameters[it[0]]?.decode()?.take(it[1]) ?: "" }
111 private fun ByteArray.decode(charset: Charset = UTF_8) = String(this, charset)
114 fun setupFreenetRequest() {
115 whenever(freenetRequest.method).thenReturn(GET)
116 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
117 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
121 fun setupTranslations() {
122 whenever(l10n.getString(anyString())).then { translations[it[0]] ?: it[0] }
125 fun setMethod(method: Method) {
126 whenever(httpRequest.method).thenReturn(method.name)
127 whenever(freenetRequest.method).thenReturn(method)
130 fun request(uri: String) {
131 whenever(httpRequest.path).thenReturn(uri)
132 whenever(freenetRequest.uri).thenReturn(URI(uri))
135 fun addHttpRequestHeader(name: String, value: String) {
136 requestHeaders[name.toLowerCase()] = value
139 fun addHttpRequestParameter(name: String, value: String) {
140 getRequestParameters[name] = getRequestParameters.getOrElse(name) { mutableListOf<String>() }.apply { add(value) }
143 fun addHttpRequestPart(name: String, value: String) {
144 postRequestParameters[name] = value.toByteArray(UTF_8)
147 fun unsetCurrentSone() {
148 whenever(webInterface.getCurrentSoneCreatingSession(eq(toadletContext))).thenReturn(null)
149 whenever(webInterface.getCurrentSone(eq(toadletContext), anyBoolean())).thenReturn(null)
150 whenever(webInterface.getCurrentSoneWithoutCreatingSession(eq(toadletContext))).thenReturn(null)
153 fun addOwnIdentity(ownIdentity: OwnIdentity) {
154 ownIdentities += ownIdentity
157 fun addSone(id: String, sone: Sone) {
161 fun addLocalSone(id: String, localSone: Sone) {
162 localSones[id] = localSone
165 fun addPost(id: String, post: Post) {
169 fun addPostReply(id: String, postReply: PostReply) {
170 allPostReplies[id] = postReply
171 postReply.postId?.also { perPostReplies[it] = postReply }
174 fun addAlbum(id: String, album: Album) {
175 allAlbums[id] = album
178 fun addImage(id: String, image: Image) {
179 allImages[id] = image
182 fun addTranslation(key: String, value: String) {
183 translations[key] = value
186 fun verifyNoRedirect(assertions: () -> Unit) {
187 var caughtException: Exception? = null
189 page.handleRequest(freenetRequest, templateContext)
190 } catch (e: Exception) {
193 caughtException?.run { throw this } ?: assertions()
196 fun verifyRedirect(target: String, assertions: () -> Unit = {}) {
198 page.handleRequest(freenetRequest, templateContext)
200 } catch (re: RedirectException) {
201 if (re.target != target) {
205 } catch (e: Exception) {