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.mock
16 import net.pterodactylus.sone.test.whenever
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.util.notify.Notification
21 import org.junit.Before
22 import org.mockito.ArgumentMatchers.anyInt
23 import org.mockito.ArgumentMatchers.anyString
24 import java.util.NoSuchElementException
25 import javax.naming.SizeLimitExceededException
26 import kotlin.coroutines.experimental.EmptyCoroutineContext.plus
29 * Base class for tests for any [JsonPage] implementations.
31 open class JsonPageTest {
33 protected val webInterface = mock<WebInterface>()
34 protected val core = mock<Core>()
35 protected val elementLoader = mock<ElementLoader>()
36 protected open lateinit var page: JsonPage
37 protected val json by lazy { page.createJsonObject(freenetRequest)!! }
39 protected val toadletContext = mock<ToadletContext>()
40 protected val freenetRequest = mock<FreenetRequest>()
41 protected val httpRequest = mock<HTTPRequest>()
42 protected val currentSone = deepMock<Sone>()
44 private val requestParameters = mutableMapOf<String, String>()
45 private val requestParts = mutableMapOf<String, String>()
46 private val localSones = mutableMapOf<String, Sone>()
47 private val remoteSones = mutableMapOf<String, Sone>()
48 private val newPosts = mutableMapOf<String, Post>()
49 private val newReplies = mutableMapOf<String, PostReply>()
50 private val linkedElements = mutableMapOf<String, LinkedElement>()
51 private val notifications = mutableListOf<Notification>()
54 fun setupWebInterface() {
55 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(currentSone)
56 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(currentSone)
57 whenever(webInterface.core).thenReturn(core)
58 whenever(webInterface.getNotifications(currentSone)).thenAnswer { notifications }
59 whenever(webInterface.getNewPosts(currentSone)).thenAnswer { newPosts.values }
60 whenever(webInterface.getNewReplies(currentSone)).thenAnswer { newReplies.values }
65 whenever(core.getSone(anyString())).thenAnswer { (localSones + remoteSones)[it.getArgument(0)].asOptional() }
69 fun setupElementLoader() {
70 whenever(elementLoader.loadElement(anyString())).thenAnswer {
71 linkedElements[it.getArgument(0)] ?: LinkedElement(it.getArgument(0), loading = true)
76 fun setupCurrentSone() {
77 currentSone.mock("soneId", "Sone_Id", true, 1000, idle)
81 fun setupFreenetRequest() {
82 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
83 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
87 fun setupHttpRequest() {
88 whenever(httpRequest.getParam(anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: "" }
89 whenever(httpRequest.getParam(anyString(), anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: it.getArgument(1) }
90 whenever(httpRequest.getPart(anyString())).thenAnswer { requestParts[it.getArgument(0)]?.let { SimpleReadOnlyArrayBucket(it.toByteArray()) } }
91 whenever(httpRequest.getPartAsBytesFailsafe(anyString(), anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.toByteArray()?.copyOf(it.getArgument(1)) ?: ByteArray(0) }
92 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() }
93 whenever(httpRequest.getPartAsStringFailsafe(anyString(), anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.substring(0, it.getArgument(1)) ?: "" }
94 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() }
95 whenever(httpRequest.getIntPart(anyString(), anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.toIntOrNull() ?: invocation.getArgument(1) }
96 whenever(httpRequest.isPartSet(anyString())).thenAnswer { it.getArgument(0) in requestParts }
99 protected fun Sone.mock(id: String, name: String, local: Boolean = false, time: Long, status: SoneStatus = idle) = apply {
100 whenever(this.id).thenReturn(id)
101 whenever(this.name).thenReturn(name)
102 whenever(isLocal).thenReturn(local)
103 whenever(this.time).thenReturn(time)
104 whenever(this.status).thenReturn(status)
107 protected fun unsetCurrentSone() {
108 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(null)
109 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(null)
112 protected fun addRequestParameter(key: String, value: String) {
113 requestParameters += key to value
116 protected fun addRequestPart(key: String, value: String) {
117 requestParts += key to value
120 protected fun addNotification(vararg notifications: Notification) {
121 this.notifications += notifications
124 protected fun addSone(sone: Sone) {
125 remoteSones += sone.id to sone
128 protected fun addNewPost(id: String, soneId: String, time: Long, recipientId: String? = null) {
129 newPosts[id] = mock<Post>().apply {
130 whenever(this.id).thenReturn(id)
131 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
132 whenever(this.sone).thenReturn(sone)
133 whenever(this.time).thenReturn(time)
134 whenever(this.recipientId).thenReturn(recipientId.asOptional())
138 protected fun addNewReply(id: String, soneId: String, postId: String, postSoneId: String) {
139 newReplies[id] = mock<PostReply>().apply {
140 whenever(this.id).thenReturn(id)
141 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
142 whenever(this.sone).thenReturn(sone)
143 val postSone = mock<Sone>().apply { whenever(this.id).thenReturn(postSoneId) }
144 val post = mock<Post>().apply {
145 whenever(this.sone).thenReturn(postSone)
147 whenever(this.post).thenReturn(post.asOptional())
148 whenever(this.postId).thenReturn(postId)
152 protected fun addLinkedElement(link: String, loading: Boolean, failed: Boolean) {
153 linkedElements[link] = LinkedElement(link, failed, loading)