Extract test fixtures into their own base class
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / ajax / TestObjects.kt
1 package net.pterodactylus.sone.web.ajax
2
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
36
37 /**
38  * Base class for tests that supplies commonly used objects.
39  */
40 open class TestObjects {
41
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>()
50
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)
56
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>()
73
74         init {
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)
86
87                 whenever(l10n.getString(ArgumentMatchers.anyString())).then { translations[it[0]] }
88
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]] }
100
101                 whenever(elementLoader.loadElement(ArgumentMatchers.anyString())).thenAnswer {
102                         linkedElements[it.getArgument(0)] ?: LinkedElement(it.getArgument(0), loading = true)
103                 }
104
105                 whenever(currentSone.options).thenReturn(DefaultSoneOptions())
106                 currentSone.mock("soneId", "Sone_Id", true, 1000, idle)
107
108                 whenever(freenetRequest.toadletContext).thenReturn(toadletContext)
109                 whenever(freenetRequest.method).thenReturn(GET)
110                 whenever(freenetRequest.httpRequest).thenReturn(httpRequest)
111
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 }
124
125                 whenever(currentSone.profile).thenReturn(profile)
126         }
127
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)
134         }
135
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)
140         }
141
142         protected fun postRequest() {
143                 whenever(freenetRequest.method).thenReturn(POST)
144                 whenever(httpRequest.method).thenReturn("POST")
145         }
146
147         protected fun addRequestHeader(key: String, value: String) {
148                 requestHeaders += key.toLowerCase() to value
149         }
150
151         protected fun addRequestParameter(key: String, value: String) {
152                 requestParameters += key to value
153         }
154
155         protected fun addRequestPart(key: String, value: String) {
156                 requestParts += key to value
157         }
158
159         protected fun addNotification(notification: Notification, notificationId: String? = null) {
160                 notifications[notificationId ?: notification.id] = notification
161         }
162
163         protected fun addSone(sone: Sone, soneId: String? = null) {
164                 remoteSones += (soneId ?: sone.id) to sone
165         }
166
167         protected fun addLocalSone(sone: Sone, id: String? = null) {
168                 localSones[id ?: sone.id] = sone
169         }
170
171         protected fun addPost(post: Post, id: String? = null) {
172                 posts[id ?: post.id] = post
173         }
174
175         protected fun addLikes(post: Post, vararg sones: Sone) {
176                 postLikes[post] = setOf(*sones)
177         }
178
179         protected fun addLikes(reply: PostReply, vararg sones: Sone) {
180                 replyLikes[reply] = setOf(*sones)
181         }
182
183         protected fun addNewPost(id: String, soneId: String, time: Long, recipientId: String? = null) =
184                         mock<Post>().apply {
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 }
191
192         protected fun addReply(reply: PostReply, id: String? = null) {
193                 replies[id ?: reply.id] = reply
194         }
195
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)
204                         }
205                         whenever(this.post).thenReturn(post.asOptional())
206                         whenever(this.postId).thenReturn(postId)
207                 }
208         }
209
210         protected fun addLinkedElement(link: String, loading: Boolean, failed: Boolean) {
211                 linkedElements[link] = LinkedElement(link, failed, loading)
212         }
213
214         protected fun addAlbum(album: Album, albumId: String? = null) {
215                 albums[albumId ?: album.id] = album
216         }
217
218         protected fun addImage(image: Image, imageId: String? = null) {
219                 images[imageId ?: image.id] = image
220         }
221
222         protected fun addTranslation(key: String, value: String) {
223                 translations[key] = value
224         }
225
226 }