Convert options 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.isPartSet(anyString())).then { it[0] in postRequestParameters }
105                 whenever(httpRequest.getPartAsStringFailsafe(anyString(), anyInt())).then { postRequestParameters[it[0]]?.decode()?.take(it[1]) ?: "" }
106         }
107
108         private fun ByteArray.decode(charset: Charset = UTF_8) = String(this, charset)
109
110         @Before
111         fun setupFreenetRequest() {
112                 whenever(freenetRequest.method).thenReturn(GET)
113                 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
114                 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
115         }
116
117         @Before
118         fun setupTranslations() {
119                 whenever(l10n.getString(anyString())).then { translations[it[0]] ?: it[0] }
120         }
121
122         fun setMethod(method: Method) {
123                 whenever(httpRequest.method).thenReturn(method.name)
124                 whenever(freenetRequest.method).thenReturn(method)
125         }
126
127         fun request(uri: String) {
128                 whenever(httpRequest.path).thenReturn(uri)
129                 whenever(freenetRequest.uri).thenReturn(URI(uri))
130         }
131
132         fun addHttpRequestHeader(name: String, value: String) {
133                 requestHeaders[name.toLowerCase()] = value
134         }
135
136         fun addHttpRequestParameter(name: String, value: String) {
137                 getRequestParameters[name] = getRequestParameters.getOrElse(name) { mutableListOf<String>() }.apply { add(value) }
138         }
139
140         fun addHttpRequestPart(name: String, value: String) {
141                 postRequestParameters[name] = value.toByteArray(UTF_8)
142         }
143
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)
148         }
149
150         fun addSone(id: String, sone: Sone) {
151                 allSones[id] = sone
152         }
153
154         fun addLocalSone(id: String, localSone: Sone) {
155                 localSones[id] = localSone
156         }
157
158         fun addPost(id: String, post: Post) {
159                 allPosts[id] = post
160         }
161
162         fun addPostReply(id: String, postReply: PostReply) {
163                 allPostReplies[id] = postReply
164                 postReply.postId?.also { perPostReplies[it] = postReply }
165         }
166
167         fun addAlbum(id: String, album: Album) {
168                 allAlbums[id] = album
169         }
170
171         fun addImage(id: String, image: Image) {
172                 allImages[id] = image
173         }
174
175         fun addTranslation(key: String, value: String) {
176                 translations[key] = value
177         }
178
179         fun verifyNoRedirect(assertions: () -> Unit) {
180                 var caughtException: Exception? = null
181                 try {
182                         page.handleRequest(freenetRequest, templateContext)
183                 } catch (e: Exception) {
184                         caughtException = e
185                 }
186                 caughtException?.run { throw this } ?: assertions()
187         }
188
189         fun verifyRedirect(target: String, assertions: () -> Unit = {}) {
190                 try {
191                         page.handleRequest(freenetRequest, templateContext)
192                         fail()
193                 } catch (re: RedirectException) {
194                         if (re.target != target) {
195                                 throw re
196                         }
197                         assertions()
198                 } catch (e: Exception) {
199                         throw e
200                 }
201         }
202
203 }