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.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
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 core = mock<Core>()
48 val eventBus = mock<EventBus>()
49 val preferences = Preferences(eventBus)
50 val updateChecker = mock<UpdateChecker>()
51 val elementLoader = mock<ElementLoader>()
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)
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>()
76 private val translation = object : Translation {
77 override val currentLocale = Locale.ENGLISH
78 override fun translate(key: String) = translations[key] ?: ""
82 whenever(webInterface.templateContextFactory).thenReturn(TemplateContextFactory())
83 whenever(webInterface.getCurrentSone(ArgumentMatchers.eq(toadletContext), ArgumentMatchers.anyBoolean())).thenReturn(currentSone)
84 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(currentSone)
85 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(currentSone)
86 whenever(webInterface.core).thenReturn(core)
87 whenever(webInterface.formPassword).then { formPassword }
88 whenever(webInterface.getNotifications(currentSone)).thenAnswer { notifications.values }
89 whenever(webInterface.getNotification(ArgumentMatchers.anyString())).then { notifications[it[0]].asOptional() }
90 whenever(webInterface.getNewPosts(currentSone)).thenAnswer { newPosts.values }
91 whenever(webInterface.getNewReplies(currentSone)).thenAnswer { newReplies.values }
92 whenever(webInterface.translation).thenReturn(translation)
94 whenever(core.preferences).thenReturn(preferences)
95 whenever(core.updateChecker).thenReturn(updateChecker)
96 whenever(core.getSone(ArgumentMatchers.anyString())).thenAnswer { (localSones + remoteSones)[it.getArgument(0)] }
97 whenever(core.getLocalSone(ArgumentMatchers.anyString())).thenAnswer { localSones[it[0]] }
98 whenever(core.getPost(ArgumentMatchers.anyString())).thenAnswer { (posts + newPosts)[it[0]] }
99 whenever(core.getLikes(ArgumentMatchers.any<Post>())).then { postLikes[it[0]] ?: emptySet<Sone>() }
100 whenever(core.getLikes(ArgumentMatchers.any<PostReply>())).then { replyLikes[it[0]] ?: emptySet<Sone>() }
101 whenever(core.getPostReply(ArgumentMatchers.anyString())).then { replies[it[0]] }
102 whenever(core.getAlbum(ArgumentMatchers.anyString())).then { albums[it[0]] }
103 whenever(core.getImage(ArgumentMatchers.anyString())).then { images[it[0]] }
104 whenever(core.getImage(ArgumentMatchers.anyString(), ArgumentMatchers.anyBoolean())).then { images[it[0]] }
106 whenever(elementLoader.loadElement(ArgumentMatchers.anyString())).thenAnswer {
107 linkedElements[it.getArgument(0)] ?: LinkedElement(it.getArgument(0), loading = true)
110 whenever(currentSone.options).thenReturn(DefaultSoneOptions())
111 currentSone.mock("soneId", "Sone_Id", true, 1000, idle)
113 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
114 whenever(freenetRequest.method).thenReturn(GET)
115 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
117 whenever(httpRequest.method).thenReturn("GET")
118 whenever(httpRequest.getHeader(ArgumentMatchers.anyString())).thenAnswer { requestHeaders[it.get<String>(0).toLowerCase()] }
119 whenever(httpRequest.getParam(ArgumentMatchers.anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: "" }
120 whenever(httpRequest.getParam(ArgumentMatchers.anyString(), ArgumentMatchers.anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: it.getArgument(1) }
121 whenever(httpRequest.getParam(ArgumentMatchers.anyString(), ArgumentMatchers.isNull())).thenAnswer { requestParameters[it.getArgument(0)] }
122 whenever(httpRequest.getPart(ArgumentMatchers.anyString())).thenAnswer { requestParts[it.getArgument(0)]?.let { SimpleReadOnlyArrayBucket(it.toByteArray()) } }
123 whenever(httpRequest.getPartAsBytesFailsafe(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.toByteArray()?.copyOf(it.getArgument(1)) ?: ByteArray(0) }
124 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() }
125 whenever(httpRequest.getPartAsStringFailsafe(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.substring(0, it.getArgument(1)) ?: "" }
126 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() }
127 whenever(httpRequest.getIntPart(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.toIntOrNull() ?: invocation.getArgument(1) }
128 whenever(httpRequest.isPartSet(ArgumentMatchers.anyString())).thenAnswer { it.getArgument(0) in requestParts }
130 whenever(currentSone.profile).thenReturn(profile)
133 protected fun Sone.mock(id: String, name: String, local: Boolean = false, time: Long, status: SoneStatus = idle) = apply {
134 whenever(this.id).thenReturn(id)
135 whenever(this.name).thenReturn(name)
136 whenever(isLocal).thenReturn(local)
137 whenever(this.time).thenReturn(time)
138 whenever(this.status).thenReturn(status)
141 protected fun unsetCurrentSone() {
142 whenever(webInterface.getCurrentSone(ArgumentMatchers.eq(toadletContext), ArgumentMatchers.anyBoolean())).thenReturn(null)
143 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(null)
144 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(null)
147 protected fun postRequest() {
148 whenever(freenetRequest.method).thenReturn(POST)
149 whenever(httpRequest.method).thenReturn("POST")
152 protected fun addRequestHeader(key: String, value: String) {
153 requestHeaders += key.toLowerCase() to value
156 protected fun addRequestParameter(key: String, value: String) {
157 requestParameters += key to value
160 protected fun addRequestPart(key: String, value: String) {
161 requestParts += key to value
164 protected fun addNotification(notification: Notification, notificationId: String? = null) {
165 notifications[notificationId ?: notification.id] = notification
168 protected fun addSone(sone: Sone, soneId: String? = null) {
169 remoteSones += (soneId ?: sone.id) to sone
172 protected fun addLocalSone(sone: Sone, id: String? = null) {
173 localSones[id ?: sone.id] = sone
176 protected fun addPost(post: Post, id: String? = null) {
177 posts[id ?: post.id] = post
180 protected fun addLikes(post: Post, vararg sones: Sone) {
181 postLikes[post] = setOf(*sones)
184 protected fun addLikes(reply: PostReply, vararg sones: Sone) {
185 replyLikes[reply] = setOf(*sones)
188 protected fun addNewPost(id: String, soneId: String, time: Long, recipientId: String? = null) =
190 whenever(this.id).thenReturn(id)
191 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
192 whenever(this.sone).thenReturn(sone)
193 whenever(this.time).thenReturn(time)
194 whenever(this.recipientId).thenReturn(recipientId.asOptional())
195 }.also { newPosts[id] = it }
197 protected fun addReply(reply: PostReply, id: String? = null) {
198 replies[id ?: reply.id] = reply
201 protected fun addNewReply(id: String, soneId: String, postId: String, postSoneId: String) {
202 newReplies[id] = mock<PostReply>().apply {
203 whenever(this.id).thenReturn(id)
204 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
205 whenever(this.sone).thenReturn(sone)
206 val postSone = mock<Sone>().apply { whenever(this.id).thenReturn(postSoneId) }
207 val post = mock<Post>().apply {
208 whenever(this.sone).thenReturn(postSone)
210 whenever(this.post).thenReturn(post.asOptional())
211 whenever(this.postId).thenReturn(postId)
215 protected fun addLinkedElement(link: String, loading: Boolean, failed: Boolean) {
216 linkedElements[link] = LinkedElement(link, failed, loading)
219 protected fun addAlbum(album: Album, albumId: String? = null) {
220 albums[albumId ?: album.id] = album
223 protected fun addImage(image: Image, imageId: String? = null) {
224 images[imageId ?: image.id] = image
227 protected fun addTranslation(key: String, value: String) {
228 translations[key] = value