From: David ‘Bombe’ Roden Date: Mon, 24 Jul 2017 17:31:29 +0000 (+0200) Subject: Replace create reply ajax page with Kotlin version X-Git-Tag: 0.9.7^2~105 X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=ec7a80c007d6d759823d6d922e6c680c04d334cd;p=Sone.git Replace create reply ajax page with Kotlin version --- diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPage.java deleted file mode 100644 index fe2ae85..0000000 --- a/src/main/java/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPage.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Sone - CreateReplyAjaxPage.java - Copyright © 2010–2016 David Roden - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.pterodactylus.sone.web.ajax; - -import com.google.common.base.Optional; - -import net.pterodactylus.sone.data.Post; -import net.pterodactylus.sone.data.PostReply; -import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.sone.text.TextFilter; -import net.pterodactylus.sone.web.WebInterface; -import net.pterodactylus.sone.web.page.FreenetRequest; - -/** - * This AJAX page create a reply. - * - * @author David ‘Bombe’ Roden - */ -public class CreateReplyAjaxPage extends JsonPage { - - /** - * Creates a new “create reply” AJAX page. - * - * @param webInterface - * The Sone web interface - */ - public CreateReplyAjaxPage(WebInterface webInterface) { - super("createReply.ajax", webInterface); - } - - // - // JSONPAGE METHODS - // - - /** - * {@inheritDoc} - */ - @Override - protected JsonReturnObject createJsonObject(FreenetRequest request) { - String postId = request.getHttpRequest().getParam("post"); - String text = request.getHttpRequest().getParam("text").trim(); - String senderId = request.getHttpRequest().getParam("sender"); - Sone sender = webInterface.getCore().getLocalSone(senderId); - if (sender == null) { - sender = getCurrentSone(request.getToadletContext()); - } - Optional post = webInterface.getCore().getPost(postId); - if (!post.isPresent()) { - return createErrorJsonObject("invalid-post-id"); - } - text = TextFilter.filter(request.getHttpRequest().getHeader("host"), text); - PostReply reply = webInterface.getCore().createReply(sender, post.get(), text); - return createSuccessJsonObject().put("reply", reply.getId()).put("sone", sender.getId()); - } - -} diff --git a/src/main/kotlin/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPage.kt b/src/main/kotlin/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPage.kt new file mode 100644 index 0000000..7cf2e1e --- /dev/null +++ b/src/main/kotlin/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPage.kt @@ -0,0 +1,30 @@ +package net.pterodactylus.sone.web.ajax + +import net.pterodactylus.sone.text.TextFilter +import net.pterodactylus.sone.utils.emptyToNull +import net.pterodactylus.sone.utils.headers +import net.pterodactylus.sone.utils.let +import net.pterodactylus.sone.utils.parameters +import net.pterodactylus.sone.web.WebInterface +import net.pterodactylus.sone.web.page.FreenetRequest + +/** + * This AJAX page create a reply. + */ +class CreateReplyAjaxPage(webInterface: WebInterface) : JsonPage("createReply.ajax", webInterface) { + + override fun createJsonObject(request: FreenetRequest): JsonReturnObject = + request.parameters["post"].emptyToNull + ?.let(webInterface.core::getPost) + ?.let { post -> + val text = TextFilter.filter(request.headers["Host"], request.parameters["text"]) + val sender = request.parameters["sender"].let(webInterface.core::getLocalSone) ?: getCurrentSone(request.toadletContext) + val reply = webInterface.core.createReply(sender, post, text) + createSuccessJsonObject().apply { + put("reply", reply.id) + put("sone", sender.id) + } + } + ?: createErrorJsonObject("invalid-post-id") + +} diff --git a/src/test/kotlin/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPageTest.kt new file mode 100644 index 0000000..9d9008b --- /dev/null +++ b/src/test/kotlin/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPageTest.kt @@ -0,0 +1,80 @@ +package net.pterodactylus.sone.web.ajax + +import net.pterodactylus.sone.data.Post +import net.pterodactylus.sone.data.PostReply +import net.pterodactylus.sone.data.Sone +import net.pterodactylus.sone.test.mock +import net.pterodactylus.sone.test.whenever +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.Test + +/** + * Unit test for [CreateReplyAjaxPage]. + */ +class CreateReplyAjaxPageTest : JsonPageTest(::CreateReplyAjaxPage) { + + @Test + fun `page returns correct path`() { + assertThat(page.path, equalTo("createReply.ajax")) + } + + @Test + fun `page needs form password`() { + assertThat(page.needsFormPassword(), equalTo(true)) + } + + @Test + fun `page requires login`() { + assertThat(page.requiresLogin(), equalTo(true)) + } + + @Test + fun `invalid post ID results in error message`() { + assertThat(json.isSuccess, equalTo(false)) + assertThat(json.error, equalTo("invalid-post-id")) + } + + @Test + fun `valid post ID results in created reply`() { + val post = mock() + addPost("post-id", post) + val reply = mock().apply { whenever(id).thenReturn("reply-id") } + whenever(core.createReply(currentSone, post, "")).thenReturn(reply) + addRequestParameter("post", "post-id") + assertThat(json.isSuccess, equalTo(true)) + assertThat(json["reply"].asText(), equalTo("reply-id")) + assertThat(json["sone"].asText(), equalTo("soneId")) + } + + @Test + fun `text is filtered when creating reply`() { + val post = mock() + addPost("post-id", post) + val reply = mock().apply { whenever(id).thenReturn("reply-id") } + whenever(core.createReply(currentSone, post, "Text with KSK@foo.bar link")).thenReturn(reply) + addRequestParameter("post", "post-id") + addRequestParameter("text", "Text with http://127.0.0.1:8888/KSK@foo.bar link") + addRequestHeader("Host", "127.0.0.1:8888") + assertThat(json.isSuccess, equalTo(true)) + assertThat(json["reply"].asText(), equalTo("reply-id")) + assertThat(json["sone"].asText(), equalTo("soneId")) + } + + @Test + fun `sender can be chosen from local sones`() { + val sone = mock().apply { whenever(id).thenReturn("local-sone") } + addLocalSone("local-sone", sone) + val post = mock() + addPost("post-id", post) + val reply = mock().apply { whenever(id).thenReturn("reply-id") } + whenever(core.createReply(sone, post, "Text")).thenReturn(reply) + addRequestParameter("post", "post-id") + addRequestParameter("text", "Text") + addRequestParameter("sender", "local-sone") + assertThat(json.isSuccess, equalTo(true)) + assertThat(json["reply"].asText(), equalTo("reply-id")) + assertThat(json["sone"].asText(), equalTo("local-sone")) + } + +} 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 b0a67d4..87b2939 100644 --- a/src/test/kotlin/net/pterodactylus/sone/web/ajax/JsonPageTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/web/ajax/JsonPageTest.kt @@ -50,6 +50,7 @@ open class JsonPageTest(pageSupplier: (WebInterface) -> JsonPage = { _ -> mock() private val localSones = mutableMapOf() private val remoteSones = mutableMapOf() + private val posts = mutableMapOf() private val newPosts = mutableMapOf() private val newReplies = mutableMapOf() private val linkedElements = mutableMapOf() @@ -69,7 +70,8 @@ open class JsonPageTest(pageSupplier: (WebInterface) -> JsonPage = { _ -> mock JsonPage = { _ -> mock().apply { whenever(this.id).thenReturn(id)