🔀 Merge branch 'release/v82'
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / ajax / TestObjects.kt
1 package net.pterodactylus.sone.web.ajax
2
3 import com.fasterxml.jackson.databind.ObjectMapper
4 import com.google.common.eventbus.EventBus
5 import freenet.clients.http.ToadletContext
6 import freenet.support.SimpleReadOnlyArrayBucket
7 import freenet.support.api.HTTPRequest
8 import net.pterodactylus.sone.core.Core
9 import net.pterodactylus.sone.core.ElementLoader
10 import net.pterodactylus.sone.core.LinkedElement
11 import net.pterodactylus.sone.core.Preferences
12 import net.pterodactylus.sone.core.UpdateChecker
13 import net.pterodactylus.sone.data.Album
14 import net.pterodactylus.sone.data.Image
15 import net.pterodactylus.sone.data.Post
16 import net.pterodactylus.sone.data.PostReply
17 import net.pterodactylus.sone.data.Profile
18 import net.pterodactylus.sone.data.Sone
19 import net.pterodactylus.sone.data.Sone.SoneStatus
20 import net.pterodactylus.sone.data.Sone.SoneStatus.idle
21 import net.pterodactylus.sone.data.SoneOptions.DefaultSoneOptions
22 import net.pterodactylus.sone.freenet.*
23 import net.pterodactylus.sone.test.deepMock
24 import net.pterodactylus.sone.test.get
25 import net.pterodactylus.sone.test.mock
26 import net.pterodactylus.sone.test.whenever
27 import net.pterodactylus.sone.utils.asOptional
28 import net.pterodactylus.sone.web.WebInterface
29 import net.pterodactylus.sone.web.page.FreenetRequest
30 import net.pterodactylus.util.notify.Notification
31 import net.pterodactylus.util.template.TemplateContextFactory
32 import net.pterodactylus.util.web.Method.GET
33 import net.pterodactylus.util.web.Method.POST
34 import org.mockito.ArgumentMatchers
35 import java.util.*
36 import javax.naming.SizeLimitExceededException
37
38 /**
39  * Base class for tests that supplies commonly used objects.
40  */
41 open class TestObjects {
42
43         val objectMapper = ObjectMapper()
44
45         val webInterface = mock<WebInterface>()
46         var formPassword = "form-password"
47         val core = mock<Core>()
48         val eventBus = mock<EventBus>()
49         val preferences = Preferences(eventBus)
50         val updateChecker = mock<UpdateChecker>()
51         val elementLoader = mock<ElementLoader>()
52
53         val toadletContext = mock<ToadletContext>()
54         val freenetRequest = mock<FreenetRequest>()
55         val httpRequest = mock<HTTPRequest>()
56         val currentSone = deepMock<Sone>()
57         val profile = Profile(currentSone)
58
59         val requestHeaders = mutableMapOf<String, String>()
60         val requestParameters = mutableMapOf<String, String>()
61         val requestParts = mutableMapOf<String, String>()
62         val localSones = mutableMapOf<String, Sone>()
63         val remoteSones = mutableMapOf<String, Sone>()
64         val posts = mutableMapOf<String, Post>()
65         val postLikes = mutableMapOf<Post, Set<Sone>>()
66         val newPosts = mutableMapOf<String, Post>()
67         val replies = mutableMapOf<String, PostReply>()
68         val replyLikes = mutableMapOf<PostReply, Set<Sone>>()
69         val newReplies = mutableMapOf<String, PostReply>()
70         val linkedElements = mutableMapOf<String, LinkedElement>()
71         val notifications = mutableMapOf<String, Notification>()
72         val albums = mutableMapOf<String, Album>()
73         val images = mutableMapOf<String, Image>()
74         val translations = mutableMapOf<String, String>()
75
76         private val translation = object : Translation {
77                 override val currentLocale = Locale.ENGLISH
78                 override fun translate(key: String) = translations[key] ?: ""
79         }
80
81         init {
82                 whenever(webInterface.templateContextFactory).thenReturn(TemplateContextFactory())
83                 whenever(webInterface.getCurrentSone(ArgumentMatchers.eq(toadletContext))).thenReturn(currentSone)
84                 whenever(webInterface.core).thenReturn(core)
85                 whenever(webInterface.formPassword).then { formPassword }
86                 whenever(webInterface.getNotifications(currentSone)).thenAnswer { notifications.values }
87                 whenever(webInterface.getNotification(ArgumentMatchers.anyString())).then { notifications[it[0]].asOptional() }
88                 whenever(webInterface.getNewPosts(currentSone)).thenAnswer { newPosts.values }
89                 whenever(webInterface.getNewReplies(currentSone)).thenAnswer { newReplies.values }
90                 whenever(webInterface.translation).thenReturn(translation)
91
92                 whenever(core.preferences).thenReturn(preferences)
93                 whenever(core.updateChecker).thenReturn(updateChecker)
94                 whenever(core.getSone(ArgumentMatchers.anyString())).thenAnswer { (localSones + remoteSones)[it.getArgument(0)] }
95                 whenever(core.getLocalSone(ArgumentMatchers.anyString())).thenAnswer { localSones[it[0]] }
96                 whenever(core.getPost(ArgumentMatchers.anyString())).thenAnswer { (posts + newPosts)[it[0]] }
97                 whenever(core.getLikes(ArgumentMatchers.any<Post>())).then { postLikes[it[0]] ?: emptySet<Sone>() }
98                 whenever(core.getLikes(ArgumentMatchers.any<PostReply>())).then { replyLikes[it[0]] ?: emptySet<Sone>() }
99                 whenever(core.getPostReply(ArgumentMatchers.anyString())).then { replies[it[0]] }
100                 whenever(core.getAlbum(ArgumentMatchers.anyString())).then { albums[it[0]] }
101                 whenever(core.getImage(ArgumentMatchers.anyString())).then { images[it[0]] }
102                 whenever(core.getImage(ArgumentMatchers.anyString(), ArgumentMatchers.anyBoolean())).then { images[it[0]] }
103
104                 whenever(elementLoader.loadElement(ArgumentMatchers.anyString())).thenAnswer {
105                         linkedElements[it.getArgument(0)] ?: LinkedElement(it.getArgument(0), loading = true)
106                 }
107
108                 whenever(currentSone.options).thenReturn(DefaultSoneOptions())
109                 currentSone.mock("soneId", "Sone_Id", true, 1000, idle)
110
111                 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
112                 whenever(freenetRequest.method).thenReturn(GET)
113                 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
114
115                 whenever(httpRequest.method).thenReturn("GET")
116                 whenever(httpRequest.getHeader(ArgumentMatchers.anyString())).thenAnswer { requestHeaders[it.get<String>(0).toLowerCase()] }
117                 whenever(httpRequest.getParam(ArgumentMatchers.anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: "" }
118                 whenever(httpRequest.getParam(ArgumentMatchers.anyString(), ArgumentMatchers.anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: it.getArgument(1) }
119                 whenever(httpRequest.getParam(ArgumentMatchers.anyString(), ArgumentMatchers.isNull())).thenAnswer { requestParameters[it.getArgument(0)] }
120                 whenever(httpRequest.getPart(ArgumentMatchers.anyString())).thenAnswer { requestParts[it.getArgument(0)]?.let { SimpleReadOnlyArrayBucket(it.toByteArray()) } }
121                 whenever(httpRequest.getPartAsBytesFailsafe(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.toByteArray()?.copyOf(it.getArgument(1)) ?: ByteArray(0) }
122                 whenever(httpRequest.getPartAsBytesThrowing(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.let { it.toByteArray().let { if (it.size > invocation.getArgument<Int>(1)) throw SizeLimitExceededException() else it } } ?: throw NoSuchElementException() }
123                 whenever(httpRequest.getPartAsStringFailsafe(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.substring(0, it.getArgument(1)) ?: "" }
124                 whenever(httpRequest.getPartAsStringThrowing(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.let { if (it.length > invocation.getArgument<Int>(1)) throw SizeLimitExceededException() else it } ?: throw NoSuchElementException() }
125                 whenever(httpRequest.getIntPart(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.toIntOrNull() ?: invocation.getArgument(1) }
126                 whenever(httpRequest.isPartSet(ArgumentMatchers.anyString())).thenAnswer { it.getArgument(0) in requestParts }
127
128                 whenever(currentSone.profile).thenReturn(profile)
129         }
130
131         protected fun Sone.mock(id: String, name: String, local: Boolean = false, time: Long, status: SoneStatus = idle) = apply {
132                 whenever(this.id).thenReturn(id)
133                 whenever(this.name).thenReturn(name)
134                 whenever(isLocal).thenReturn(local)
135                 whenever(this.time).thenReturn(time)
136                 whenever(this.status).thenReturn(status)
137         }
138
139         protected fun unsetCurrentSone() {
140                 whenever(webInterface.getCurrentSone(ArgumentMatchers.eq(toadletContext))).thenReturn(null)
141         }
142
143         protected fun postRequest() {
144                 whenever(freenetRequest.method).thenReturn(POST)
145                 whenever(httpRequest.method).thenReturn("POST")
146         }
147
148         protected fun addRequestHeader(key: String, value: String) {
149                 requestHeaders += key.toLowerCase() to value
150         }
151
152         protected fun addRequestParameter(key: String, value: String) {
153                 requestParameters += key to value
154         }
155
156         protected fun addRequestPart(key: String, value: String) {
157                 requestParts += key to value
158         }
159
160         protected fun addNotification(notification: Notification, notificationId: String? = null) {
161                 notifications[notificationId ?: notification.id] = notification
162         }
163
164         protected fun addSone(sone: Sone, soneId: String? = null) {
165                 remoteSones += (soneId ?: sone.id) to sone
166         }
167
168         protected fun addLocalSone(sone: Sone, id: String? = null) {
169                 localSones[id ?: sone.id] = sone
170         }
171
172         protected fun addPost(post: Post, id: String? = null) {
173                 posts[id ?: post.id] = post
174         }
175
176         protected fun addLikes(post: Post, vararg sones: Sone) {
177                 postLikes[post] = setOf(*sones)
178         }
179
180         protected fun addLikes(reply: PostReply, vararg sones: Sone) {
181                 replyLikes[reply] = setOf(*sones)
182         }
183
184         protected fun addNewPost(id: String, soneId: String, time: Long, recipientId: String? = null) =
185                         mock<Post>().apply {
186                                 whenever(this.id).thenReturn(id)
187                                 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
188                                 whenever(this.sone).thenReturn(sone)
189                                 whenever(this.time).thenReturn(time)
190                                 whenever(this.recipientId).thenReturn(recipientId.asOptional())
191                         }.also { newPosts[id] = it }
192
193         protected fun addReply(reply: PostReply, id: String? = null) {
194                 replies[id ?: reply.id] = reply
195         }
196
197         protected fun addNewReply(id: String, soneId: String, postId: String, postSoneId: String) {
198                 newReplies[id] = mock<PostReply>().apply {
199                         whenever(this.id).thenReturn(id)
200                         val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
201                         whenever(this.sone).thenReturn(sone)
202                         val postSone = mock<Sone>().apply { whenever(this.id).thenReturn(postSoneId) }
203                         val post = mock<Post>().apply {
204                                 whenever(this.sone).thenReturn(postSone)
205                         }
206                         whenever(this.post).thenReturn(post.asOptional())
207                         whenever(this.postId).thenReturn(postId)
208                 }
209         }
210
211         protected fun addLinkedElement(link: String, loading: Boolean, failed: Boolean) {
212                 linkedElements[link] = LinkedElement(link, failed, loading)
213         }
214
215         protected fun addAlbum(album: Album, albumId: String? = null) {
216                 albums[albumId ?: album.id] = album
217         }
218
219         protected fun addImage(image: Image, imageId: String? = null) {
220                 images[imageId ?: image.id] = image
221         }
222
223         protected fun addTranslation(key: String, value: String) {
224                 translations[key] = value
225         }
226
227 }