Create Guava optional utility collection
[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.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
27
28 /**
29  * Base class for tests for any [JsonPage] implementations.
30  */
31 open class JsonPageTest {
32
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)!! }
38
39         protected val toadletContext = mock<ToadletContext>()
40         protected val freenetRequest = mock<FreenetRequest>()
41         protected val httpRequest = mock<HTTPRequest>()
42         protected val currentSone = deepMock<Sone>()
43
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>()
52
53         @Before
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 }
61         }
62
63         @Before
64         fun setupCore() {
65                 whenever(core.getSone(anyString())).thenAnswer { (localSones + remoteSones)[it.getArgument(0)].asOptional() }
66         }
67
68         @Before
69         fun setupElementLoader() {
70                 whenever(elementLoader.loadElement(anyString())).thenAnswer {
71                         linkedElements[it.getArgument(0)] ?: LinkedElement(it.getArgument(0), loading = true)
72                 }
73         }
74
75         @Before
76         fun setupCurrentSone() {
77                 currentSone.mock("soneId", "Sone_Id", true, 1000, idle)
78         }
79
80         @Before
81         fun setupFreenetRequest() {
82                 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
83                 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
84         }
85
86         @Before
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 }
97         }
98
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)
105         }
106
107         protected fun unsetCurrentSone() {
108                 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(null)
109                 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(null)
110         }
111
112         protected fun addRequestParameter(key: String, value: String) {
113                 requestParameters += key to value
114         }
115
116         protected fun addRequestPart(key: String, value: String) {
117                 requestParts += key to value
118         }
119
120         protected fun addNotification(vararg notifications: Notification) {
121                 this.notifications += notifications
122         }
123
124         protected fun addSone(sone: Sone) {
125                 remoteSones += sone.id to sone
126         }
127
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())
135                 }
136         }
137
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)
146                         }
147                         whenever(this.post).thenReturn(post.asOptional())
148                         whenever(this.postId).thenReturn(postId)
149                 }
150         }
151
152         protected fun addLinkedElement(link: String, loading: Boolean, failed: Boolean) {
153                 linkedElements[link] = LinkedElement(link, failed, loading)
154         }
155
156 }