From 8dd998006410b230392c0df06a29f95be1571b6f Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Fri, 25 Nov 2016 23:13:20 +0100 Subject: [PATCH] Add unit test for edit album page --- .../net/pterodactylus/sone/web/WebPageTest.java | 15 +++ .../net/pterodactylus/sone/test/Mockotlin.kt | 1 + .../pterodactylus/sone/web/EditAlbumPageTest.kt | 121 +++++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 src/test/kotlin/net/pterodactylus/sone/web/EditAlbumPageTest.kt diff --git a/src/test/java/net/pterodactylus/sone/web/WebPageTest.java b/src/test/java/net/pterodactylus/sone/web/WebPageTest.java index 2825a20..b759a6d 100644 --- a/src/test/java/net/pterodactylus/sone/web/WebPageTest.java +++ b/src/test/java/net/pterodactylus/sone/web/WebPageTest.java @@ -11,10 +11,14 @@ import static org.mockito.Mockito.when; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import javax.annotation.Nonnull; + import net.pterodactylus.sone.core.Core; import net.pterodactylus.sone.core.Preferences; import net.pterodactylus.sone.core.UpdateChecker; @@ -60,6 +64,7 @@ public abstract class WebPageTest { protected final TemplateContext templateContext = new TemplateContext(); protected final HTTPRequest httpRequest = mock(HTTPRequest.class); + protected final Map requestHeaders = new HashMap<>(); protected final FreenetRequest freenetRequest = mock(FreenetRequest.class); protected final ToadletContext toadletContext = mock(ToadletContext.class); @@ -78,6 +83,12 @@ public abstract class WebPageTest { }); when(httpRequest.getParam(anyString())).thenReturn(""); when(httpRequest.getParam(anyString(), anyString())).thenReturn(""); + when(httpRequest.getHeader(anyString())).thenAnswer(new Answer() { + @Override + public String answer(InvocationOnMock invocation) throws Throwable { + return requestHeaders.get(invocation.getArgument(0).toLowerCase()); + } + }); } @Before @@ -126,6 +137,10 @@ public abstract class WebPageTest { when(freenetRequest.getMethod()).thenReturn(method); } + protected void addHttpRequestHeader(@Nonnull String name, String value) { + requestHeaders.put(name.toLowerCase(), value); + } + protected void addHttpRequestParameter(String name, final String value) { when(httpRequest.getPartAsStringFailsafe(eq(name), anyInt())).thenAnswer(new Answer() { @Override diff --git a/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt b/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt index eba2012..b30e98c 100644 --- a/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt +++ b/src/test/kotlin/net/pterodactylus/sone/test/Mockotlin.kt @@ -5,6 +5,7 @@ import org.mockito.ArgumentCaptor import org.mockito.Mockito 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 capture(): ArgumentCaptor = ArgumentCaptor.forClass(T::class.java) diff --git a/src/test/kotlin/net/pterodactylus/sone/web/EditAlbumPageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/EditAlbumPageTest.kt new file mode 100644 index 0000000..963ab1e --- /dev/null +++ b/src/test/kotlin/net/pterodactylus/sone/web/EditAlbumPageTest.kt @@ -0,0 +1,121 @@ +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.test.mock +import net.pterodactylus.sone.test.mockBuilder +import net.pterodactylus.sone.test.whenever +import net.pterodactylus.sone.web.WebTestUtils.redirectsTo +import net.pterodactylus.util.web.Method.GET +import net.pterodactylus.util.web.Method.POST +import org.junit.Before +import org.junit.Test +import org.mockito.Mockito.verify + +/** + * Unit test for [EditAlbumPage]. + */ +class EditAlbumPageTest : WebPageTest() { + + private val page = EditAlbumPage(template, webInterface) + + private val album = mock() + private val parentAlbum = mock() + private val modifier = mockBuilder() + private val sone = mock() + + @Before + fun setup() { + whenever(album.id).thenReturn("album-id") + whenever(album.sone).thenReturn(sone) + whenever(album.parent).thenReturn(parentAlbum) + whenever(album.modify()).thenReturn(modifier) + whenever(modifier.update()).thenReturn(album) + whenever(parentAlbum.id).thenReturn("parent-id") + whenever(sone.isLocal).thenReturn(true) + addHttpRequestHeader("Host", "www.te.st") + } + + @Test + fun `get request does not redirect`() { + request("", GET) + page.handleRequest(freenetRequest, templateContext) + } + + @Test + fun `post request with invalid album redirects to invalid page`() { + request("", POST) + expectedException.expect(redirectsTo("invalid.html")) + page.handleRequest(freenetRequest, templateContext) + } + + @Test + fun `post request with album of non-local sone redirects to no permissions page`() { + request("", POST) + whenever(sone.isLocal).thenReturn(false) + addAlbum("album-id", album) + addHttpRequestParameter("album", "album-id") + expectedException.expect(redirectsTo("noPermission.html")) + page.handleRequest(freenetRequest, templateContext) + } + + @Test + fun `post request with move left requested moves album to the left and redirects to album browser`() { + request("", POST) + addAlbum("album-id", album) + addHttpRequestParameter("album", "album-id") + addHttpRequestParameter("moveLeft", "true") + expectedException.expect(redirectsTo("imageBrowser.html?album=parent-id")) + try { + page.handleRequest(freenetRequest, templateContext) + } finally { + verify(parentAlbum).moveAlbumUp(album) + verify(core).touchConfiguration() + } + } + + @Test + fun `post request with move right requested moves album to the left and redirects to album browser`() { + request("", POST) + addAlbum("album-id", album) + addHttpRequestParameter("album", "album-id") + addHttpRequestParameter("moveRight", "true") + expectedException.expect(redirectsTo("imageBrowser.html?album=parent-id")) + try { + page.handleRequest(freenetRequest, templateContext) + } finally { + verify(parentAlbum).moveAlbumDown(album) + verify(core).touchConfiguration() + } + } + + @Test + fun `post request with empty album title redirects to empty album title page`() { + request("", POST) + addAlbum("album-id", album) + addHttpRequestParameter("album", "album-id") + whenever(modifier.setTitle("")).thenThrow(AlbumTitleMustNotBeEmpty()) + expectedException.expect(redirectsTo("emptyAlbumTitle.html")) + page.handleRequest(freenetRequest, templateContext) + } + + @Test + fun `post request with non-empty album title and description redirects to album browser`() { + request("", POST) + addAlbum("album-id", album) + addHttpRequestParameter("album", "album-id") + addHttpRequestParameter("title", "title") + addHttpRequestParameter("description", "description") + expectedException.expect(redirectsTo("imageBrowser.html?album=album-id")) + try { + page.handleRequest(freenetRequest, templateContext) + } finally { + verify(modifier).setTitle("title") + verify(modifier).setDescription("description") + verify(modifier).update() + verify(core).touchConfiguration() + } + } + +} -- 2.7.4