1 package net.pterodactylus.sone.web.ajax
3 import freenet.clients.http.ToadletContext
4 import freenet.support.SimpleReadOnlyArrayBucket
5 import freenet.support.api.HTTPRequest
6 import net.pterodactylus.sone.core.Core
7 import net.pterodactylus.sone.core.ElementLoader
8 import net.pterodactylus.sone.core.LinkedElement
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.data.Sone.SoneStatus
13 import net.pterodactylus.sone.data.Sone.SoneStatus.idle
14 import net.pterodactylus.sone.test.deepMock
15 import net.pterodactylus.sone.test.get
16 import net.pterodactylus.sone.test.mock
17 import net.pterodactylus.sone.test.whenever
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.util.notify.Notification
22 import org.junit.Before
23 import org.mockito.ArgumentMatchers.anyInt
24 import org.mockito.ArgumentMatchers.anyString
25 import org.mockito.ArgumentMatchers.isNull
26 import java.util.NoSuchElementException
27 import javax.naming.SizeLimitExceededException
30 * Base class for tests for any [JsonPage] implementations.
32 open class JsonPageTest(pageSupplier: (WebInterface) -> JsonPage = { _ -> mock<JsonPage>() }) {
34 protected val webInterface = mock<WebInterface>()
35 protected val core = mock<Core>()
36 protected val elementLoader = mock<ElementLoader>()
37 protected open val page: JsonPage by lazy { pageSupplier(webInterface) }
38 protected val json by lazy { page.createJsonObject(freenetRequest)!! }
40 protected val toadletContext = mock<ToadletContext>()
41 protected val freenetRequest = mock<FreenetRequest>()
42 protected val httpRequest = mock<HTTPRequest>()
43 protected val currentSone = deepMock<Sone>()
45 private val requestParameters = mutableMapOf<String, String>()
46 private val requestParts = mutableMapOf<String, String>()
47 private val localSones = mutableMapOf<String, Sone>()
48 private val remoteSones = mutableMapOf<String, Sone>()
49 private val newPosts = mutableMapOf<String, Post>()
50 private val newReplies = mutableMapOf<String, PostReply>()
51 private val linkedElements = mutableMapOf<String, LinkedElement>()
52 private val notifications = mutableListOf<Notification>()
55 fun setupWebInterface() {
56 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(currentSone)
57 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(currentSone)
58 whenever(webInterface.core).thenReturn(core)
59 whenever(webInterface.getNotifications(currentSone)).thenAnswer { notifications }
60 whenever(webInterface.getNewPosts(currentSone)).thenAnswer { newPosts.values }
61 whenever(webInterface.getNewReplies(currentSone)).thenAnswer { newReplies.values }
66 whenever(core.getSone(anyString())).thenAnswer { (localSones + remoteSones)[it.getArgument(0)].asOptional() }
67 whenever(core.getPost(anyString())).thenAnswer { newPosts[it[0]].asOptional() }
71 fun setupElementLoader() {
72 whenever(elementLoader.loadElement(anyString())).thenAnswer {
73 linkedElements[it.getArgument(0)] ?: LinkedElement(it.getArgument(0), loading = true)
78 fun setupCurrentSone() {
79 currentSone.mock("soneId", "Sone_Id", true, 1000, idle)
83 fun setupFreenetRequest() {
84 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
85 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
89 fun setupHttpRequest() {
90 whenever(httpRequest.getParam(anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: "" }
91 whenever(httpRequest.getParam(anyString(), anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: it.getArgument(1) }
92 whenever(httpRequest.getParam(anyString(), isNull())).thenAnswer { requestParameters[it.getArgument(0)] }
93 whenever(httpRequest.getPart(anyString())).thenAnswer { requestParts[it.getArgument(0)]?.let { SimpleReadOnlyArrayBucket(it.toByteArray()) } }
94 whenever(httpRequest.getPartAsBytesFailsafe(anyString(), anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.toByteArray()?.copyOf(it.getArgument(1)) ?: ByteArray(0) }
95 whenever(httpRequest.getPartAsBytesThrowing(anyString(), anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.let { it.toByteArray().let { if (it.size > invocation.getArgument<Int>(1)) throw SizeLimitExceededException() else it } } ?: throw NoSuchElementException() }
96 whenever(httpRequest.getPartAsStringFailsafe(anyString(), anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.substring(0, it.getArgument(1)) ?: "" }
97 whenever(httpRequest.getPartAsStringThrowing(anyString(), anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.let { if (it.length > invocation.getArgument<Int>(1)) throw SizeLimitExceededException() else it } ?: throw NoSuchElementException() }
98 whenever(httpRequest.getIntPart(anyString(), anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.toIntOrNull() ?: invocation.getArgument(1) }
99 whenever(httpRequest.isPartSet(anyString())).thenAnswer { it.getArgument(0) in requestParts }
102 protected fun Sone.mock(id: String, name: String, local: Boolean = false, time: Long, status: SoneStatus = idle) = apply {
103 whenever(this.id).thenReturn(id)
104 whenever(this.name).thenReturn(name)
105 whenever(isLocal).thenReturn(local)
106 whenever(this.time).thenReturn(time)
107 whenever(this.status).thenReturn(status)
110 protected fun unsetCurrentSone() {
111 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(null)
112 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(null)
115 protected fun addRequestParameter(key: String, value: String) {
116 requestParameters += key to value
119 protected fun addRequestPart(key: String, value: String) {
120 requestParts += key to value
123 protected fun addNotification(vararg notifications: Notification) {
124 this.notifications += notifications
127 protected fun addSone(sone: Sone) {
128 remoteSones += sone.id to sone
131 protected fun addNewPost(id: String, soneId: String, time: Long, recipientId: String? = null) =
133 whenever(this.id).thenReturn(id)
134 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
135 whenever(this.sone).thenReturn(sone)
136 whenever(this.time).thenReturn(time)
137 whenever(this.recipientId).thenReturn(recipientId.asOptional())
138 }.also { newPosts[id] = it }
140 protected fun addNewReply(id: String, soneId: String, postId: String, postSoneId: String) {
141 newReplies[id] = mock<PostReply>().apply {
142 whenever(this.id).thenReturn(id)
143 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
144 whenever(this.sone).thenReturn(sone)
145 val postSone = mock<Sone>().apply { whenever(this.id).thenReturn(postSoneId) }
146 val post = mock<Post>().apply {
147 whenever(this.sone).thenReturn(postSone)
149 whenever(this.post).thenReturn(post.asOptional())
150 whenever(this.postId).thenReturn(postId)
154 protected fun addLinkedElement(link: String, loading: Boolean, failed: Boolean) {
155 linkedElements[link] = LinkedElement(link, failed, loading)