X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Ftest%2Fkotlin%2Fnet%2Fpterodactylus%2Fsone%2Fweb%2Fajax%2FJsonPageTest.kt;h=d5314c5ae27862b9992ffea8a9fb45711a8f33bd;hp=11d5291f3d2c755dc426c827172dcfa88fce9059;hb=c3407a682f9f81b27d0354e59fe9e3d3d6dffcd6;hpb=5a54ea664e862c910b1766d8ba0dd5efb6ea0151 diff --git a/src/test/kotlin/net/pterodactylus/sone/web/ajax/JsonPageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/ajax/JsonPageTest.kt index 11d5291..d5314c5 100644 --- a/src/test/kotlin/net/pterodactylus/sone/web/ajax/JsonPageTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/web/ajax/JsonPageTest.kt @@ -1,68 +1,106 @@ package net.pterodactylus.sone.web.ajax +import com.google.common.eventbus.EventBus import freenet.clients.http.ToadletContext import freenet.support.SimpleReadOnlyArrayBucket import freenet.support.api.HTTPRequest import net.pterodactylus.sone.core.Core import net.pterodactylus.sone.core.ElementLoader import net.pterodactylus.sone.core.LinkedElement +import net.pterodactylus.sone.core.Preferences +import net.pterodactylus.sone.data.Album +import net.pterodactylus.sone.data.Image import net.pterodactylus.sone.data.Post import net.pterodactylus.sone.data.PostReply +import net.pterodactylus.sone.data.Profile import net.pterodactylus.sone.data.Sone import net.pterodactylus.sone.data.Sone.SoneStatus import net.pterodactylus.sone.data.Sone.SoneStatus.idle import net.pterodactylus.sone.test.deepMock +import net.pterodactylus.sone.test.get import net.pterodactylus.sone.test.mock import net.pterodactylus.sone.test.whenever import net.pterodactylus.sone.utils.asOptional import net.pterodactylus.sone.web.WebInterface import net.pterodactylus.sone.web.page.FreenetRequest import net.pterodactylus.util.notify.Notification +import net.pterodactylus.util.web.Method.GET +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo import org.junit.Before +import org.junit.Test +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyString +import org.mockito.ArgumentMatchers.eq +import org.mockito.ArgumentMatchers.isNull import java.util.NoSuchElementException import javax.naming.SizeLimitExceededException -import kotlin.coroutines.experimental.EmptyCoroutineContext.plus /** * Base class for tests for any [JsonPage] implementations. */ -open class JsonPageTest { +abstract class JsonPageTest( + private val expectedPath: String, + private val requiresLogin: Boolean = true, + private val needsFormPassword: Boolean = true, + pageSupplier: (WebInterface) -> JsonPage = { _ -> mock() }) { protected val webInterface = mock() protected val core = mock() + protected val eventBus = mock() + protected val preferences = Preferences(eventBus) protected val elementLoader = mock() - protected open lateinit var page: JsonPage - protected val json by lazy { page.createJsonObject(freenetRequest)!! } + protected open val page: JsonPage by lazy { pageSupplier(webInterface) } + protected val json by lazy { page.createJsonObject(freenetRequest) } protected val toadletContext = mock() protected val freenetRequest = mock() protected val httpRequest = mock() protected val currentSone = deepMock() + protected val profile = Profile(currentSone) + private val requestHeaders = mutableMapOf() private val requestParameters = mutableMapOf() private val requestParts = mutableMapOf() private val localSones = mutableMapOf() private val remoteSones = mutableMapOf() + private val posts = mutableMapOf() + private val postLikes = mutableMapOf>() private val newPosts = mutableMapOf() + private val replies = mutableMapOf() + private val replyLikes = mutableMapOf>() private val newReplies = mutableMapOf() private val linkedElements = mutableMapOf() - private val notifications = mutableListOf() + private val notifications = mutableMapOf() + private val albums = mutableMapOf() + private val images = mutableMapOf() @Before fun setupWebInterface() { + whenever(webInterface.getCurrentSone(eq(toadletContext), anyBoolean())).thenReturn(currentSone) whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(currentSone) whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(currentSone) whenever(webInterface.core).thenReturn(core) - whenever(webInterface.getNotifications(currentSone)).thenAnswer { notifications } + whenever(webInterface.getNotifications(currentSone)).thenAnswer { notifications.values } + whenever(webInterface.getNotification(anyString())).then { notifications[it[0]].asOptional() } whenever(webInterface.getNewPosts(currentSone)).thenAnswer { newPosts.values } whenever(webInterface.getNewReplies(currentSone)).thenAnswer { newReplies.values } } @Before fun setupCore() { + whenever(core.preferences).thenReturn(preferences) whenever(core.getSone(anyString())).thenAnswer { (localSones + remoteSones)[it.getArgument(0)].asOptional() } + whenever(core.getLocalSone(anyString())).thenAnswer { localSones[it[0]] } + whenever(core.getPost(anyString())).thenAnswer { (posts + newPosts)[it[0]].asOptional() } + whenever(core.getLikes(any())).then { postLikes[it[0]] ?: emptySet() } + whenever(core.getLikes(any())).then { replyLikes[it[0]] ?: emptySet() } + whenever(core.getPostReply(anyString())).then { replies[it[0]].asOptional() } + whenever(core.getAlbum(anyString())).then { albums[it[0]] } + whenever(core.getImage(anyString())).then { images[it[0]] } + whenever(core.getImage(anyString(), anyBoolean())).then { images[it[0]] } } @Before @@ -80,13 +118,17 @@ open class JsonPageTest { @Before fun setupFreenetRequest() { whenever(freenetRequest.toadletContext).thenReturn(toadletContext) + whenever(freenetRequest.method).thenReturn(GET) whenever(freenetRequest.httpRequest).thenReturn(httpRequest) } @Before fun setupHttpRequest() { + whenever(httpRequest.method).thenReturn("GET") + whenever(httpRequest.getHeader(anyString())).thenAnswer { requestHeaders[it.get(0).toLowerCase()] } whenever(httpRequest.getParam(anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: "" } whenever(httpRequest.getParam(anyString(), anyString())).thenAnswer { requestParameters[it.getArgument(0)] ?: it.getArgument(1) } + whenever(httpRequest.getParam(anyString(), isNull())).thenAnswer { requestParameters[it.getArgument(0)] } whenever(httpRequest.getPart(anyString())).thenAnswer { requestParts[it.getArgument(0)]?.let { SimpleReadOnlyArrayBucket(it.toByteArray()) } } whenever(httpRequest.getPartAsBytesFailsafe(anyString(), anyInt())).thenAnswer { requestParts[it.getArgument(0)]?.toByteArray()?.copyOf(it.getArgument(1)) ?: ByteArray(0) } whenever(httpRequest.getPartAsBytesThrowing(anyString(), anyInt())).thenAnswer { invocation -> requestParts[invocation.getArgument(0)]?.let { it.toByteArray().let { if (it.size > invocation.getArgument(1)) throw SizeLimitExceededException() else it } } ?: throw NoSuchElementException() } @@ -96,6 +138,13 @@ open class JsonPageTest { whenever(httpRequest.isPartSet(anyString())).thenAnswer { it.getArgument(0) in requestParts } } + @Before + fun setupProfile() { + whenever(currentSone.profile).thenReturn(profile) + } + + protected val JsonReturnObject.error get() = if (this is JsonErrorReturnObject) this.error else null + protected fun Sone.mock(id: String, name: String, local: Boolean = false, time: Long, status: SoneStatus = idle) = apply { whenever(this.id).thenReturn(id) whenever(this.name).thenReturn(name) @@ -105,10 +154,15 @@ open class JsonPageTest { } protected fun unsetCurrentSone() { + whenever(webInterface.getCurrentSone(eq(toadletContext), anyBoolean())).thenReturn(null) whenever(webInterface.getCurrentSoneWithoutCreatingSession(toadletContext)).thenReturn(null) whenever(webInterface.getCurrentSoneCreatingSession(toadletContext)).thenReturn(null) } + protected fun addRequestHeader(key: String, value: String) { + requestHeaders += key.toLowerCase() to value + } + protected fun addRequestParameter(key: String, value: String) { requestParameters += key to value } @@ -117,22 +171,41 @@ open class JsonPageTest { requestParts += key to value } - protected fun addNotification(vararg notifications: Notification) { - this.notifications += notifications + protected fun addNotification(notification: Notification, notificationId: String? = null) { + notifications[notificationId ?: notification.id] = notification } - protected fun addSone(sone: Sone) { - remoteSones += sone.id to sone + protected fun addSone(sone: Sone, soneId: String? = null) { + remoteSones += (soneId ?: sone.id) to sone } - protected fun addNewPost(id: String, soneId: String, time: Long, recipientId: String? = null) { - newPosts[id] = mock().apply { - whenever(this.id).thenReturn(id) - val sone = mock().apply { whenever(this.id).thenReturn(soneId) } - whenever(this.sone).thenReturn(sone) - whenever(this.time).thenReturn(time) - whenever(this.recipientId).thenReturn(recipientId.asOptional()) - } + protected fun addLocalSone(id: String, sone: Sone) { + localSones += id to sone + } + + protected fun addPost(post: Post, id: String? = null) { + posts[id ?: post.id] = post + } + + protected fun addLikes(post: Post, vararg sones: Sone) { + postLikes[post] = setOf(*sones) + } + + protected fun addLikes(reply: PostReply, vararg sones: Sone) { + replyLikes[reply] = setOf(*sones) + } + + protected fun addNewPost(id: String, soneId: String, time: Long, recipientId: String? = null) = + mock().apply { + whenever(this.id).thenReturn(id) + val sone = mock().apply { whenever(this.id).thenReturn(soneId) } + whenever(this.sone).thenReturn(sone) + whenever(this.time).thenReturn(time) + whenever(this.recipientId).thenReturn(recipientId.asOptional()) + }.also { newPosts[id] = it } + + protected fun addReply(reply: PostReply, id: String? = null) { + replies[id ?: reply.id] = reply } protected fun addNewReply(id: String, soneId: String, postId: String, postSoneId: String) { @@ -153,4 +226,27 @@ open class JsonPageTest { linkedElements[link] = LinkedElement(link, failed, loading) } + protected fun addAlbum(album: Album, albumId: String? = null) { + albums[albumId ?: album.id] = album + } + + protected fun addImage(image: Image, imageId: String? = null) { + images[imageId ?: image.id] = image + } + + @Test + fun `page returns correct path`() { + assertThat(page.path, equalTo(expectedPath)) + } + + @Test + fun `page needs form password`() { + assertThat(page.needsFormPassword(), equalTo(needsFormPassword)) + } + + @Test + fun `page requires login`() { + assertThat(page.requiresLogin(), equalTo(requiresLogin)) + } + }