From: David ‘Bombe’ Roden Date: Thu, 9 Feb 2017 17:07:49 +0000 (+0100) Subject: Replace create album page and test with Kotlin version X-Git-Tag: 0.9.7^2~301 X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=commitdiff_plain;h=fe8a83bdb1d644d4d1bf4342feab4c58115409b3 Replace create album page and test with Kotlin version --- diff --git a/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java b/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java deleted file mode 100644 index 7423b67..0000000 --- a/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Sone - CreateAlbumPage.java - Copyright © 2011–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; - -import net.pterodactylus.sone.data.Album; -import net.pterodactylus.sone.data.Album.Modifier.AlbumTitleMustNotBeEmpty; -import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.sone.text.TextFilter; -import net.pterodactylus.sone.web.page.FreenetRequest; -import net.pterodactylus.util.template.Template; -import net.pterodactylus.util.template.TemplateContext; -import net.pterodactylus.util.web.Method; - -/** - * Page that lets the user create a new album. - * - * @author David ‘Bombe’ Roden - */ -public class CreateAlbumPage extends SoneTemplatePage { - - /** - * Creates a new “create album” page. - * - * @param template - * The template to render - * @param webInterface - * The Sone web interface - */ - public CreateAlbumPage(Template template, WebInterface webInterface) { - super("createAlbum.html", template, "Page.CreateAlbum.Title", webInterface, true); - } - - // - // SONETEMPLATEPAGE METHODS - // - - /** - * {@inheritDoc} - */ - @Override - protected void handleRequest(FreenetRequest request, TemplateContext templateContext) throws RedirectException { - if (request.getMethod() == Method.POST) { - String name = request.getHttpRequest().getPartAsStringFailsafe("name", 64).trim(); - if (name.length() == 0) { - templateContext.set("nameMissing", true); - return; - } - String description = request.getHttpRequest().getPartAsStringFailsafe("description", 256).trim(); - Sone currentSone = getCurrentSone(request.getToadletContext()); - String parentId = request.getHttpRequest().getPartAsStringFailsafe("parent", 36); - Album parent = webInterface.getCore().getAlbum(parentId); - if (parentId.equals("")) { - parent = currentSone.getRootAlbum(); - } - Album album = webInterface.getCore().createAlbum(currentSone, parent); - try { - album.modify().setTitle(name).setDescription(TextFilter.filter(request.getHttpRequest().getHeader("host"), description)).update(); - } catch (AlbumTitleMustNotBeEmpty atmnbe) { - throw new RedirectException("emptyAlbumTitle.html"); - } - webInterface.getCore().touchConfiguration(); - throw new RedirectException("imageBrowser.html?album=" + album.getId()); - } - } - -} diff --git a/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.kt b/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.kt new file mode 100644 index 0000000..5d47641 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.kt @@ -0,0 +1,41 @@ +package net.pterodactylus.sone.web + +import net.pterodactylus.sone.data.Album.Modifier.AlbumTitleMustNotBeEmpty +import net.pterodactylus.sone.text.TextFilter +import net.pterodactylus.sone.web.page.FreenetRequest +import net.pterodactylus.util.template.Template +import net.pterodactylus.util.template.TemplateContext +import net.pterodactylus.util.web.Method.POST + +/** + * Page that lets the user create a new album. + */ +class CreateAlbumPage(template: Template, webInterface: WebInterface): + SoneTemplatePage("createAlbum.html", template, "Page.CreateAlbum.Title", webInterface, true) { + + override fun handleRequest(request: FreenetRequest, templateContext: TemplateContext) { + if (request.method == POST) { + val name = request.httpRequest.getPartAsStringFailsafe("name", 64).trim() + if (name.isEmpty()) { + templateContext["nameMissing"] = true + return + } + val description = request.httpRequest.getPartAsStringFailsafe("description", 256).trim() + val currentSone = webInterface.getCurrentSoneCreatingSession(request.toadletContext) + val parentId = request.httpRequest.getPartAsStringFailsafe("parent", 36) + val parent = if (parentId == "") currentSone.rootAlbum else webInterface.core.getAlbum(parentId) + val album = webInterface.core.createAlbum(currentSone, parent) + try { + album.modify().apply { + setTitle(name) + setDescription(TextFilter.filter(request.httpRequest.getHeader("Host"), description)) + }.update() + } catch (e: AlbumTitleMustNotBeEmpty) { + throw RedirectException("emptyAlbumTitle.html") + } + webInterface.core.touchConfiguration() + throw RedirectException("imageBrowser.html?album=${album.id}") + } + } + +} diff --git a/src/test/java/net/pterodactylus/sone/web/CreateAlbumPageTest.java b/src/test/java/net/pterodactylus/sone/web/CreateAlbumPageTest.java deleted file mode 100644 index da0ec0c..0000000 --- a/src/test/java/net/pterodactylus/sone/web/CreateAlbumPageTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package net.pterodactylus.sone.web; - -import static net.pterodactylus.sone.web.WebTestUtils.redirectsTo; -import static net.pterodactylus.util.web.Method.POST; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.mockito.Answers.RETURNS_DEEP_STUBS; -import static org.mockito.Answers.RETURNS_SELF; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import net.pterodactylus.sone.data.Album; -import net.pterodactylus.sone.data.Album.Modifier; -import net.pterodactylus.sone.data.Album.Modifier.AlbumTitleMustNotBeEmpty; -import net.pterodactylus.sone.test.Dirty; - -import org.junit.Test; - -/** - * Unit test for {@link CreateAlbumPage}. - * - * @author David ‘Bombe’ Roden - */ -public class CreateAlbumPageTest extends WebPageTest { - - private final CreateAlbumPage page = new CreateAlbumPage(template, webInterface); - - @Test - public void pageReturnsCorrectPath() { - assertThat(page.getPath(), is("createAlbum.html")); - } - - @Test - public void getRequestShowsTemplate() throws Exception { - page.processTemplate(freenetRequest, templateContext); - } - - @Test - public void missingNameResultsInAttributeSetInTemplateContext() throws Exception { - request("", POST); - page.processTemplate(freenetRequest, templateContext); - assertThat(templateContext.get("nameMissing"), is((Object) true)); - } - - @Test - public void titleAndDescriptionAreSetCorrectlyOnTheAlbum() throws Exception { - request("", POST); - Album parentAlbum = createAlbum("parent-id"); - when(core.getAlbum("parent-id")).thenReturn(parentAlbum); - Album newAlbum = createAlbum("album-id"); - when(core.createAlbum(currentSone, parentAlbum)).thenReturn(newAlbum); - addHttpRequestParameter("name", "new name"); - addHttpRequestParameter("description", "new description"); - addHttpRequestParameter("parent", "parent-id"); - expectedException.expect(redirectsTo("imageBrowser.html?album=album-id")); - try { - page.processTemplate(freenetRequest, templateContext); - } finally { - verify(newAlbum).modify(); - verify(newAlbum.modify()).setTitle("new name"); - verify(newAlbum.modify()).setDescription("new description"); - verify(newAlbum.modify()).update(); - verify(core).touchConfiguration(); - } - } - - private Album createAlbum(String albumId) { - Album newAlbum = mock(Album.class, RETURNS_DEEP_STUBS); - when(newAlbum.getId()).thenReturn(albumId); - Modifier albumModifier = mock(Modifier.class, RETURNS_SELF); - when(newAlbum.modify()).thenReturn(albumModifier); - when(albumModifier.update()).thenReturn(newAlbum); - return newAlbum; - } - - @Test - public void rootAlbumIsUsedIfNoParentIsSpecified() throws Exception { - request("", POST); - Album parentAlbum = createAlbum("root-id"); - when(currentSone.getRootAlbum()).thenReturn(parentAlbum); - Album newAlbum = createAlbum("album-id"); - when(core.createAlbum(currentSone, parentAlbum)).thenReturn(newAlbum); - addHttpRequestParameter("name", "new name"); - addHttpRequestParameter("description", "new description"); - expectedException.expect(redirectsTo("imageBrowser.html?album=album-id")); - page.processTemplate(freenetRequest, templateContext); - } - - @Test - @Dirty("that exception can never happen") - public void emptyAlbumTitleRedirectsToErrorPage() throws Exception { - request("", POST); - Album parentAlbum = createAlbum("root-id"); - when(currentSone.getRootAlbum()).thenReturn(parentAlbum); - Album newAlbum = createAlbum("album-id"); - when(core.createAlbum(currentSone, parentAlbum)).thenReturn(newAlbum); - when(newAlbum.modify().update()).thenThrow(AlbumTitleMustNotBeEmpty.class); - addHttpRequestParameter("name", "new name"); - addHttpRequestParameter("description", "new description"); - expectedException.expect(redirectsTo("emptyAlbumTitle.html")); - page.processTemplate(freenetRequest, templateContext); - } - -} diff --git a/src/test/java/net/pterodactylus/sone/web/CreateAlbumPageTest.kt b/src/test/java/net/pterodactylus/sone/web/CreateAlbumPageTest.kt new file mode 100644 index 0000000..054917d --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/web/CreateAlbumPageTest.kt @@ -0,0 +1,102 @@ +package net.pterodactylus.sone.web + +import net.pterodactylus.sone.data.Album +import net.pterodactylus.sone.data.Album.Modifier.AlbumTitleMustNotBeEmpty +import net.pterodactylus.sone.test.deepMock +import net.pterodactylus.sone.test.selfMock +import net.pterodactylus.sone.test.whenever +import net.pterodactylus.util.web.Method.POST +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.Before +import org.junit.Test +import org.mockito.Mockito.verify + +/** + * Unit test for [CreateAlbumPage]. + */ +class CreateAlbumPageTest: WebPageTest() { + + private val page = CreateAlbumPage(template, webInterface) + + override fun getPage() = page + + private val parentAlbum = createAlbum("parent-id") + private val newAlbum = createAlbum("album-id") + + @Before + fun setupAlbums() { + whenever(core.createAlbum(currentSone, parentAlbum)).thenReturn(newAlbum) + whenever(currentSone.rootAlbum).thenReturn(parentAlbum) + } + + @Test + fun `page returns correct path`() { + assertThat(page.path, equalTo("createAlbum.html")) + } + + @Test + fun `get request shows template`() { + page.processTemplate(freenetRequest, templateContext) + } + + @Test + fun `missing name results in attribute being set in template context`() { + request("", POST) + page.processTemplate(freenetRequest, templateContext) + assertThat(templateContext["nameMissing"], equalTo(true)) + } + + private fun createAlbum(albumId: String) = deepMock().apply { + whenever(id).thenReturn(albumId) + selfMock().let { modifier -> + whenever(modifier.update()).thenReturn(this@apply) + whenever(this@apply.modify()).thenReturn(modifier) + } + } + + @Test + fun `title and description are set correctly on the album`() { + request("", POST) + addAlbum("parent-id", parentAlbum) + addHttpRequestParameter("name", "new name") + addHttpRequestParameter("description", "new description") + addHttpRequestParameter("parent", "parent-id") + verifyRedirect("imageBrowser.html?album=album-id") { + verify(newAlbum).modify() + verify(newAlbum.modify()).setTitle("new name") + verify(newAlbum.modify()).setDescription("new description") + verify(newAlbum.modify()).update() + verify(core).touchConfiguration() + } + } + + @Test + fun `root album is used if no parent is specified`() { + request("", POST) + addHttpRequestParameter("name", "new name") + addHttpRequestParameter("description", "new description") + verifyRedirect("imageBrowser.html?album=album-id") + } + + @Test + fun `empty album title redirects to error page`() { + request("", POST) + whenever(newAlbum.modify().update()).thenThrow(AlbumTitleMustNotBeEmpty::class.java) + addHttpRequestParameter("name", "new name") + addHttpRequestParameter("description", "new description") + verifyRedirect("emptyAlbumTitle.html") + } + + @Test + fun `album description is filtered`() { + request("", POST) + addHttpRequestParameter("name", "new name") + addHttpRequestParameter("description", "new http://localhost:12345/KSK@foo description") + addHttpRequestHeader("Host", "localhost:12345") + verifyRedirect("imageBrowser.html?album=album-id") { + verify(newAlbum.modify()).setDescription("new KSK@foo description") + } + } + +} diff --git a/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt b/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt index 38625ea..dada6eb 100644 --- a/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt +++ b/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt @@ -8,6 +8,7 @@ import org.mockito.stubbing.OngoingStubbing inline fun mock(): T = Mockito.mock(T::class.java)!! inline fun mockBuilder(): T = Mockito.mock(T::class.java, Mockito.RETURNS_SELF)!! inline fun deepMock(): T = Mockito.mock(T::class.java, Mockito.RETURNS_DEEP_STUBS)!! +inline fun selfMock(): T = Mockito.mock(T::class.java, Mockito.RETURNS_SELF)!! inline fun capture(): ArgumentCaptor = ArgumentCaptor.forClass(T::class.java) inline fun bind(implementation: T): Module =