Replace bookmark ajax page with Kotlin version
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / ajax / JsonPageTest.kt
1 package net.pterodactylus.sone.web.ajax
2
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 net.pterodactylus.util.web.Method.GET
23 import org.junit.Before
24 import org.mockito.ArgumentMatchers.anyInt
25 import org.mockito.ArgumentMatchers.anyString
26 import org.mockito.ArgumentMatchers.isNull
27 import java.util.NoSuchElementException
28 import javax.naming.SizeLimitExceededException
29
30 /**
31  * Base class for tests for any [JsonPage] implementations.
32  */
33 open class JsonPageTest(pageSupplier: (WebInterface) -> JsonPage = { _ -> mock<JsonPage>() }) {
34
35         protected val webInterface = mock<WebInterface>()
36         protected val core = mock<Core>()
37         protected val elementLoader = mock<ElementLoader>()
38         protected open val page: JsonPage by lazy { pageSupplier(webInterface) }
39         protected val json by lazy { page.createJsonObject(freenetRequest)!! }
40
41         protected val toadletContext = mock<ToadletContext>()
42         protected val freenetRequest = mock<FreenetRequest>()
43         protected val httpRequest = mock<HTTPRequest>()
44         protected val currentSone = deepMock<Sone>()
45
46         private val requestParameters = mutableMapOf<String, String>()
47         private val requestParts = mutableMapOf<String, String>()
48         private val localSones = mutableMapOf<String, Sone>()
49         private val remoteSones = mutableMapOf<String, Sone>()
50         private val newPosts = mutableMapOf<String, Post>()
51         private val newReplies = mutableMapOf<String, PostReply>()
52         private val linkedElements = mutableMapOf<String, LinkedElement>()
53         private val notifications = mutableListOf<Notification>()
54
55         @Before
56         fun setupWebInterface() {
57                 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(currentSone)
58                 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(currentSone)
59                 whenever(webInterface.core).thenReturn(core)
60                 whenever(webInterface.getNotifications(currentSone)).thenAnswer { notifications }
61                 whenever(webInterface.getNewPosts(currentSone)).thenAnswer { newPosts.values }
62                 whenever(webInterface.getNewReplies(currentSone)).thenAnswer { newReplies.values }
63         }
64
65         @Before
66         fun setupCore() {
67                 whenever(core.getSone(anyString())).thenAnswer { (localSones + remoteSones)[it.getArgument(0)].asOptional() }
68                 whenever(core.getPost(anyString())).thenAnswer { newPosts[it[0]].asOptional() }
69         }
70
71         @Before
72         fun setupElementLoader() {
73                 whenever(elementLoader.loadElement(anyString())).thenAnswer {
74                         linkedElements[it.getArgument(0)] ?: LinkedElement(it.getArgument(0), loading = true)
75                 }
76         }
77
78         @Before
79         fun setupCurrentSone() {
80                 currentSone.mock("soneId", "Sone_Id", true, 1000, idle)
81         }
82
83         @Before
84         fun setupFreenetRequest() {
85                 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
86                 whenever(freenetRequest.method).thenReturn(GET)
87                 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
88         }
89
90         @Before
91         fun setupHttpRequest() {
92                 whenever(httpRequest.method).thenReturn("GET")
93                 whenever(httpRequest.getParam(anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: "" }
94                 whenever(httpRequest.getParam(anyString(), anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: it.getArgument(1) }
95                 whenever(httpRequest.getParam(anyString(), isNull())).thenAnswer { requestParameters[it.getArgument(0)] }
96                 whenever(httpRequest.getPart(anyString())).thenAnswer { requestParts[it.getArgument(0)]?.let { SimpleReadOnlyArrayBucket(it.toByteArray()) } }
97                 whenever(httpRequest.getPartAsBytesFailsafe(anyString(), anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.toByteArray()?.copyOf(it.getArgument(1)) ?: ByteArray(0) }
98                 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() }
99                 whenever(httpRequest.getPartAsStringFailsafe(anyString(), anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.substring(0, it.getArgument(1)) ?: "" }
100                 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() }
101                 whenever(httpRequest.getIntPart(anyString(), anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.toIntOrNull() ?: invocation.getArgument(1) }
102                 whenever(httpRequest.isPartSet(anyString())).thenAnswer { it.getArgument(0) in requestParts }
103         }
104
105         protected fun Sone.mock(id: String, name: String, local: Boolean = false, time: Long, status: SoneStatus = idle) = apply {
106                 whenever(this.id).thenReturn(id)
107                 whenever(this.name).thenReturn(name)
108                 whenever(isLocal).thenReturn(local)
109                 whenever(this.time).thenReturn(time)
110                 whenever(this.status).thenReturn(status)
111         }
112
113         protected fun unsetCurrentSone() {
114                 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(null)
115                 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(null)
116         }
117
118         protected fun addRequestParameter(key: String, value: String) {
119                 requestParameters += key to value
120         }
121
122         protected fun addRequestPart(key: String, value: String) {
123                 requestParts += key to value
124         }
125
126         protected fun addNotification(vararg notifications: Notification) {
127                 this.notifications += notifications
128         }
129
130         protected fun addSone(sone: Sone) {
131                 remoteSones += sone.id to sone
132         }
133
134         protected fun addNewPost(id: String, soneId: String, time: Long, recipientId: String? = null) =
135                         mock<Post>().apply {
136                                 whenever(this.id).thenReturn(id)
137                                 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
138                                 whenever(this.sone).thenReturn(sone)
139                                 whenever(this.time).thenReturn(time)
140                                 whenever(this.recipientId).thenReturn(recipientId.asOptional())
141                         }.also { newPosts[id] = it }
142
143         protected fun addNewReply(id: String, soneId: String, postId: String, postSoneId: String) {
144                 newReplies[id] = mock<PostReply>().apply {
145                         whenever(this.id).thenReturn(id)
146                         val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
147                         whenever(this.sone).thenReturn(sone)
148                         val postSone = mock<Sone>().apply { whenever(this.id).thenReturn(postSoneId) }
149                         val post = mock<Post>().apply {
150                                 whenever(this.sone).thenReturn(postSone)
151                         }
152                         whenever(this.post).thenReturn(post.asOptional())
153                         whenever(this.postId).thenReturn(postId)
154                 }
155         }
156
157         protected fun addLinkedElement(link: String, loading: Boolean, failed: Boolean) {
158                 linkedElements[link] = LinkedElement(link, failed, loading)
159         }
160
161 }