1 package net.pterodactylus.sone.web.ajax
3 import com.fasterxml.jackson.databind.ObjectMapper
4 import com.google.common.eventbus.EventBus
5 import freenet.clients.http.ToadletContext
6 import freenet.l10n.BaseL10n
7 import freenet.support.SimpleReadOnlyArrayBucket
8 import freenet.support.api.HTTPRequest
9 import net.pterodactylus.sone.core.Core
10 import net.pterodactylus.sone.core.ElementLoader
11 import net.pterodactylus.sone.core.LinkedElement
12 import net.pterodactylus.sone.core.Preferences
13 import net.pterodactylus.sone.core.UpdateChecker
14 import net.pterodactylus.sone.data.Album
15 import net.pterodactylus.sone.data.Image
16 import net.pterodactylus.sone.data.Post
17 import net.pterodactylus.sone.data.PostReply
18 import net.pterodactylus.sone.data.Profile
19 import net.pterodactylus.sone.data.Sone
20 import net.pterodactylus.sone.data.Sone.SoneStatus
21 import net.pterodactylus.sone.data.Sone.SoneStatus.idle
22 import net.pterodactylus.sone.data.SoneOptions.DefaultSoneOptions
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.NoSuchElementException
36 import javax.naming.SizeLimitExceededException
39 * Base class for tests that supplies commonly used objects.
41 open class TestObjects {
43 val objectMapper = ObjectMapper()
45 val webInterface = mock<WebInterface>()
46 var formPassword = "form-password"
47 val l10n = mock<BaseL10n>()
48 val core = mock<Core>()
49 val eventBus = mock<EventBus>()
50 val preferences = Preferences(eventBus)
51 val updateChecker = mock<UpdateChecker>()
52 val elementLoader = mock<ElementLoader>()
54 val toadletContext = mock<ToadletContext>()
55 val freenetRequest = mock<FreenetRequest>()
56 val httpRequest = mock<HTTPRequest>()
57 val currentSone = deepMock<Sone>()
58 val profile = Profile(currentSone)
60 val requestHeaders = mutableMapOf<String, String>()
61 val requestParameters = mutableMapOf<String, String>()
62 val requestParts = mutableMapOf<String, String>()
63 val localSones = mutableMapOf<String, Sone>()
64 val remoteSones = mutableMapOf<String, Sone>()
65 val posts = mutableMapOf<String, Post>()
66 val postLikes = mutableMapOf<Post, Set<Sone>>()
67 val newPosts = mutableMapOf<String, Post>()
68 val replies = mutableMapOf<String, PostReply>()
69 val replyLikes = mutableMapOf<PostReply, Set<Sone>>()
70 val newReplies = mutableMapOf<String, PostReply>()
71 val linkedElements = mutableMapOf<String, LinkedElement>()
72 val notifications = mutableMapOf<String, Notification>()
73 val albums = mutableMapOf<String, Album>()
74 val images = mutableMapOf<String, Image>()
75 val translations = mutableMapOf<String, String>()
78 whenever(webInterface.templateContextFactory).thenReturn(TemplateContextFactory())
79 whenever(webInterface.getCurrentSone(ArgumentMatchers.eq(toadletContext), ArgumentMatchers.anyBoolean())).thenReturn(currentSone)
80 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(currentSone)
81 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(currentSone)
82 whenever(webInterface.core).thenReturn(core)
83 whenever(webInterface.formPassword).then { formPassword }
84 whenever(webInterface.getNotifications(currentSone)).thenAnswer { notifications.values }
85 whenever(webInterface.getNotification(ArgumentMatchers.anyString())).then { notifications[it[0]].asOptional() }
86 whenever(webInterface.getNewPosts(currentSone)).thenAnswer { newPosts.values }
87 whenever(webInterface.getNewReplies(currentSone)).thenAnswer { newReplies.values }
88 whenever(webInterface.l10n).thenReturn(l10n)
90 whenever(l10n.getString(ArgumentMatchers.anyString())).then { translations[it[0]] }
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]] }
104 whenever(elementLoader.loadElement(ArgumentMatchers.anyString())).thenAnswer {
105 linkedElements[it.getArgument(0)] ?: LinkedElement(it.getArgument(0), loading = true)
108 whenever(currentSone.options).thenReturn(DefaultSoneOptions())
109 currentSone.mock("soneId", "Sone_Id", true, 1000, idle)
111 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
112 whenever(freenetRequest.method).thenReturn(GET)
113 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
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 }
128 whenever(currentSone.profile).thenReturn(profile)
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)
139 protected fun unsetCurrentSone() {
140 whenever(webInterface.getCurrentSone(ArgumentMatchers.eq(toadletContext), ArgumentMatchers.anyBoolean())).thenReturn(null)
141 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(null)
142 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(null)
145 protected fun postRequest() {
146 whenever(freenetRequest.method).thenReturn(POST)
147 whenever(httpRequest.method).thenReturn("POST")
150 protected fun addRequestHeader(key: String, value: String) {
151 requestHeaders += key.toLowerCase() to value
154 protected fun addRequestParameter(key: String, value: String) {
155 requestParameters += key to value
158 protected fun addRequestPart(key: String, value: String) {
159 requestParts += key to value
162 protected fun addNotification(notification: Notification, notificationId: String? = null) {
163 notifications[notificationId ?: notification.id] = notification
166 protected fun addSone(sone: Sone, soneId: String? = null) {
167 remoteSones += (soneId ?: sone.id) to sone
170 protected fun addLocalSone(sone: Sone, id: String? = null) {
171 localSones[id ?: sone.id] = sone
174 protected fun addPost(post: Post, id: String? = null) {
175 posts[id ?: post.id] = post
178 protected fun addLikes(post: Post, vararg sones: Sone) {
179 postLikes[post] = setOf(*sones)
182 protected fun addLikes(reply: PostReply, vararg sones: Sone) {
183 replyLikes[reply] = setOf(*sones)
186 protected fun addNewPost(id: String, soneId: String, time: Long, recipientId: String? = null) =
188 whenever(this.id).thenReturn(id)
189 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
190 whenever(this.sone).thenReturn(sone)
191 whenever(this.time).thenReturn(time)
192 whenever(this.recipientId).thenReturn(recipientId.asOptional())
193 }.also { newPosts[id] = it }
195 protected fun addReply(reply: PostReply, id: String? = null) {
196 replies[id ?: reply.id] = reply
199 protected fun addNewReply(id: String, soneId: String, postId: String, postSoneId: String) {
200 newReplies[id] = mock<PostReply>().apply {
201 whenever(this.id).thenReturn(id)
202 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
203 whenever(this.sone).thenReturn(sone)
204 val postSone = mock<Sone>().apply { whenever(this.id).thenReturn(postSoneId) }
205 val post = mock<Post>().apply {
206 whenever(this.sone).thenReturn(postSone)
208 whenever(this.post).thenReturn(post.asOptional())
209 whenever(this.postId).thenReturn(postId)
213 protected fun addLinkedElement(link: String, loading: Boolean, failed: Boolean) {
214 linkedElements[link] = LinkedElement(link, failed, loading)
217 protected fun addAlbum(album: Album, albumId: String? = null) {
218 albums[albumId ?: album.id] = album
221 protected fun addImage(image: Image, imageId: String? = null) {
222 images[imageId ?: image.id] = image
225 protected fun addTranslation(key: String, value: String) {
226 translations[key] = value