Convert search page test to use new web page test base
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / pages / WebPageTest2.kt
1 package net.pterodactylus.sone.web.pages
2
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
32 import java.net.URI
33 import java.nio.charset.Charset
34 import kotlin.text.Charsets.UTF_8
35
36 /**
37  * Base class for web page tests.
38  */
39 abstract class WebPageTest2(pageSupplier: (Template, WebInterface) -> SoneTemplatePage) {
40
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!!
48
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()
53
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>()
66
67         @Before
68         fun setupCore() {
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]]}
80         }
81
82         @Before
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())
88         }
89
90         @Before
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]) ?: "" }
105         }
106
107         private fun ByteArray.decode(charset: Charset = UTF_8) = String(this, charset)
108
109         @Before
110         fun setupFreenetRequest() {
111                 whenever(freenetRequest.method).thenReturn(GET)
112                 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
113                 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
114         }
115
116         @Before
117         fun setupTranslations() {
118                 whenever(l10n.getString(anyString())).then { translations[it[0]] ?: it[0] }
119         }
120
121         fun setMethod(method: Method) {
122                 whenever(httpRequest.method).thenReturn(method.name)
123                 whenever(freenetRequest.method).thenReturn(method)
124         }
125
126         fun request(uri: String) {
127                 whenever(httpRequest.path).thenReturn(uri)
128                 whenever(freenetRequest.uri).thenReturn(URI(uri))
129         }
130
131         fun addHttpRequestHeader(name: String, value: String) {
132                 requestHeaders[name.toLowerCase()] = value
133         }
134
135         fun addHttpRequestParameter(name: String, value: String) {
136                 getRequestParameters[name] = getRequestParameters.getOrElse(name) { mutableListOf<String>() }.apply { add(value) }
137         }
138
139         fun addHttpRequestPart(name: String, value: String) {
140                 postRequestParameters[name] = value.toByteArray(UTF_8)
141         }
142
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)
147         }
148
149         fun addSone(id: String, sone: Sone) {
150                 allSones[id] = sone
151         }
152
153         fun addLocalSone(id: String, localSone: Sone) {
154                 localSones[id] = localSone
155         }
156
157         fun addPost(id: String, post: Post) {
158                 allPosts[id] = post
159         }
160
161         fun addPostReply(id: String, postReply: PostReply) {
162                 allPostReplies[id] = postReply
163                 postReply.postId?.also { perPostReplies[it] = postReply }
164         }
165
166         fun addAlbum(id: String, album: Album) {
167                 allAlbums[id] = album
168         }
169
170         fun addImage(id: String, image: Image) {
171                 allImages[id] = image
172         }
173
174         fun addTranslation(key: String, value: String) {
175                 translations[key] = value
176         }
177
178         fun verifyNoRedirect(assertions: () -> Unit) {
179                 var caughtException: Exception? = null
180                 try {
181                         page.handleRequest(freenetRequest, templateContext)
182                 } catch (e: Exception) {
183                         caughtException = e
184                 }
185                 caughtException?.run { throw this } ?: assertions()
186         }
187
188         fun verifyRedirect(target: String, assertions: () -> Unit = {}) {
189                 try {
190                         page.handleRequest(freenetRequest, templateContext)
191                         fail()
192                 } catch (re: RedirectException) {
193                         if (re.target != target) {
194                                 throw re
195                         }
196                         assertions()
197                 } catch (e: Exception) {
198                         throw e
199                 }
200         }
201
202 }