1 package net.pterodactylus.sone.web.ajax
3 import com.google.common.eventbus.EventBus
4 import freenet.clients.http.ToadletContext
5 import freenet.l10n.BaseL10n
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.test.deepMock
23 import net.pterodactylus.sone.test.get
24 import net.pterodactylus.sone.test.mock
25 import net.pterodactylus.sone.test.whenever
26 import net.pterodactylus.sone.utils.asOptional
27 import net.pterodactylus.sone.web.WebInterface
28 import net.pterodactylus.sone.web.page.FreenetRequest
29 import net.pterodactylus.util.notify.Notification
30 import net.pterodactylus.util.template.TemplateContextFactory
31 import net.pterodactylus.util.web.Method.GET
32 import net.pterodactylus.util.web.Method.POST
33 import org.mockito.ArgumentMatchers
34 import java.util.NoSuchElementException
35 import javax.naming.SizeLimitExceededException
38 * Base class for tests that supplies commonly used objects.
40 open class TestObjects {
42 val webInterface = mock<WebInterface>()
43 var formPassword = "form-password"
44 val l10n = mock<BaseL10n>()
45 val core = mock<Core>()
46 val eventBus = mock<EventBus>()
47 val preferences = Preferences(eventBus)
48 val updateChecker = mock<UpdateChecker>()
49 val elementLoader = mock<ElementLoader>()
51 val toadletContext = mock<ToadletContext>()
52 val freenetRequest = mock<FreenetRequest>()
53 val httpRequest = mock<HTTPRequest>()
54 val currentSone = deepMock<Sone>()
55 val profile = Profile(currentSone)
57 val requestHeaders = mutableMapOf<String, String>()
58 val requestParameters = mutableMapOf<String, String>()
59 val requestParts = mutableMapOf<String, String>()
60 val localSones = mutableMapOf<String, Sone>()
61 val remoteSones = mutableMapOf<String, Sone>()
62 val posts = mutableMapOf<String, Post>()
63 val postLikes = mutableMapOf<Post, Set<Sone>>()
64 val newPosts = mutableMapOf<String, Post>()
65 val replies = mutableMapOf<String, PostReply>()
66 val replyLikes = mutableMapOf<PostReply, Set<Sone>>()
67 val newReplies = mutableMapOf<String, PostReply>()
68 val linkedElements = mutableMapOf<String, LinkedElement>()
69 val notifications = mutableMapOf<String, Notification>()
70 val albums = mutableMapOf<String, Album>()
71 val images = mutableMapOf<String, Image>()
72 val translations = mutableMapOf<String, String>()
75 whenever(webInterface.templateContextFactory).thenReturn(TemplateContextFactory())
76 whenever(webInterface.getCurrentSone(ArgumentMatchers.eq(toadletContext), ArgumentMatchers.anyBoolean())).thenReturn(currentSone)
77 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(currentSone)
78 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(currentSone)
79 whenever(webInterface.core).thenReturn(core)
80 whenever(webInterface.formPassword).then { formPassword }
81 whenever(webInterface.getNotifications(currentSone)).thenAnswer { notifications.values }
82 whenever(webInterface.getNotification(ArgumentMatchers.anyString())).then { notifications[it[0]].asOptional() }
83 whenever(webInterface.getNewPosts(currentSone)).thenAnswer { newPosts.values }
84 whenever(webInterface.getNewReplies(currentSone)).thenAnswer { newReplies.values }
85 whenever(webInterface.l10n).thenReturn(l10n)
87 whenever(l10n.getString(ArgumentMatchers.anyString())).then { translations[it[0]] }
89 whenever(core.preferences).thenReturn(preferences)
90 whenever(core.updateChecker).thenReturn(updateChecker)
91 whenever(core.getSone(ArgumentMatchers.anyString())).thenAnswer { (localSones + remoteSones)[it.getArgument(0)].asOptional() }
92 whenever(core.getLocalSone(ArgumentMatchers.anyString())).thenAnswer { localSones[it[0]] }
93 whenever(core.getPost(ArgumentMatchers.anyString())).thenAnswer { (posts + newPosts)[it[0]].asOptional() }
94 whenever(core.getLikes(ArgumentMatchers.any<Post>())).then { postLikes[it[0]] ?: emptySet<Sone>() }
95 whenever(core.getLikes(ArgumentMatchers.any<PostReply>())).then { replyLikes[it[0]] ?: emptySet<Sone>() }
96 whenever(core.getPostReply(ArgumentMatchers.anyString())).then { replies[it[0]].asOptional() }
97 whenever(core.getAlbum(ArgumentMatchers.anyString())).then { albums[it[0]] }
98 whenever(core.getImage(ArgumentMatchers.anyString())).then { images[it[0]] }
99 whenever(core.getImage(ArgumentMatchers.anyString(), ArgumentMatchers.anyBoolean())).then { images[it[0]] }
101 whenever(elementLoader.loadElement(ArgumentMatchers.anyString())).thenAnswer {
102 linkedElements[it.getArgument(0)] ?: LinkedElement(it.getArgument(0), loading = true)
105 whenever(currentSone.options).thenReturn(DefaultSoneOptions())
106 currentSone.mock("soneId", "Sone_Id", true, 1000, idle)
108 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
109 whenever(freenetRequest.method).thenReturn(GET)
110 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
112 whenever(httpRequest.method).thenReturn("GET")
113 whenever(httpRequest.getHeader(ArgumentMatchers.anyString())).thenAnswer { requestHeaders[it.get<String>(0).toLowerCase()] }
114 whenever(httpRequest.getParam(ArgumentMatchers.anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: "" }
115 whenever(httpRequest.getParam(ArgumentMatchers.anyString(), ArgumentMatchers.anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: it.getArgument(1) }
116 whenever(httpRequest.getParam(ArgumentMatchers.anyString(), ArgumentMatchers.isNull())).thenAnswer { requestParameters[it.getArgument(0)] }
117 whenever(httpRequest.getPart(ArgumentMatchers.anyString())).thenAnswer { requestParts[it.getArgument(0)]?.let { SimpleReadOnlyArrayBucket(it.toByteArray()) } }
118 whenever(httpRequest.getPartAsBytesFailsafe(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.toByteArray()?.copyOf(it.getArgument(1)) ?: ByteArray(0) }
119 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() }
120 whenever(httpRequest.getPartAsStringFailsafe(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.substring(0, it.getArgument(1)) ?: "" }
121 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() }
122 whenever(httpRequest.getIntPart(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.toIntOrNull() ?: invocation.getArgument(1) }
123 whenever(httpRequest.isPartSet(ArgumentMatchers.anyString())).thenAnswer { it.getArgument(0) in requestParts }
125 whenever(currentSone.profile).thenReturn(profile)
128 protected fun Sone.mock(id: String, name: String, local: Boolean = false, time: Long, status: SoneStatus = idle) = apply {
129 whenever(this.id).thenReturn(id)
130 whenever(this.name).thenReturn(name)
131 whenever(isLocal).thenReturn(local)
132 whenever(this.time).thenReturn(time)
133 whenever(this.status).thenReturn(status)
136 protected fun unsetCurrentSone() {
137 whenever(webInterface.getCurrentSone(ArgumentMatchers.eq(toadletContext), ArgumentMatchers.anyBoolean())).thenReturn(null)
138 whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(null)
139 whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(null)
142 protected fun postRequest() {
143 whenever(freenetRequest.method).thenReturn(POST)
144 whenever(httpRequest.method).thenReturn("POST")
147 protected fun addRequestHeader(key: String, value: String) {
148 requestHeaders += key.toLowerCase() to value
151 protected fun addRequestParameter(key: String, value: String) {
152 requestParameters += key to value
155 protected fun addRequestPart(key: String, value: String) {
156 requestParts += key to value
159 protected fun addNotification(notification: Notification, notificationId: String? = null) {
160 notifications[notificationId ?: notification.id] = notification
163 protected fun addSone(sone: Sone, soneId: String? = null) {
164 remoteSones += (soneId ?: sone.id) to sone
167 protected fun addLocalSone(sone: Sone, id: String? = null) {
168 localSones[id ?: sone.id] = sone
171 protected fun addPost(post: Post, id: String? = null) {
172 posts[id ?: post.id] = post
175 protected fun addLikes(post: Post, vararg sones: Sone) {
176 postLikes[post] = setOf(*sones)
179 protected fun addLikes(reply: PostReply, vararg sones: Sone) {
180 replyLikes[reply] = setOf(*sones)
183 protected fun addNewPost(id: String, soneId: String, time: Long, recipientId: String? = null) =
185 whenever(this.id).thenReturn(id)
186 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
187 whenever(this.sone).thenReturn(sone)
188 whenever(this.time).thenReturn(time)
189 whenever(this.recipientId).thenReturn(recipientId.asOptional())
190 }.also { newPosts[id] = it }
192 protected fun addReply(reply: PostReply, id: String? = null) {
193 replies[id ?: reply.id] = reply
196 protected fun addNewReply(id: String, soneId: String, postId: String, postSoneId: String) {
197 newReplies[id] = mock<PostReply>().apply {
198 whenever(this.id).thenReturn(id)
199 val sone = mock<Sone>().apply { whenever(this.id).thenReturn(soneId) }
200 whenever(this.sone).thenReturn(sone)
201 val postSone = mock<Sone>().apply { whenever(this.id).thenReturn(postSoneId) }
202 val post = mock<Post>().apply {
203 whenever(this.sone).thenReturn(postSone)
205 whenever(this.post).thenReturn(post.asOptional())
206 whenever(this.postId).thenReturn(postId)
210 protected fun addLinkedElement(link: String, loading: Boolean, failed: Boolean) {
211 linkedElements[link] = LinkedElement(link, failed, loading)
214 protected fun addAlbum(album: Album, albumId: String? = null) {
215 albums[albumId ?: album.id] = album
218 protected fun addImage(image: Image, imageId: String? = null) {
219 images[imageId ?: image.id] = image
222 protected fun addTranslation(key: String, value: String) {
223 translations[key] = value