From c2c776f038ec312447ab64504efa88b1f3533b9a Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sun, 22 Jan 2017 03:01:59 +0100 Subject: [PATCH] Expand test for upload image page --- .../net/pterodactylus/sone/web/WebPageTest.java | 55 ++++++++++++++- .../pterodactylus/sone/web/UploadImagePageTest.kt | 74 ++++++++++++++++++++- .../resources/net/pterodactylus/sone/web/image.png | Bin 0 -> 3200 bytes .../net/pterodactylus/sone/web/no-image.png | 0 4 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/test/resources/net/pterodactylus/sone/web/image.png create mode 100644 src/test/resources/net/pterodactylus/sone/web/no-image.png diff --git a/src/test/java/net/pterodactylus/sone/web/WebPageTest.java b/src/test/java/net/pterodactylus/sone/web/WebPageTest.java index a6f7aa3..d8b9462 100644 --- a/src/test/java/net/pterodactylus/sone/web/WebPageTest.java +++ b/src/test/java/net/pterodactylus/sone/web/WebPageTest.java @@ -12,6 +12,7 @@ import static org.mockito.Mockito.when; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.net.URI; @@ -47,11 +48,14 @@ import net.pterodactylus.util.web.Response; import freenet.clients.http.ToadletContext; import freenet.l10n.BaseL10n; +import freenet.support.SimpleReadOnlyArrayBucket; +import freenet.support.api.Bucket; import freenet.support.api.HTTPRequest; +import freenet.support.api.HTTPUploadedFile; +import freenet.support.io.NullBucket; import com.google.common.base.Optional; import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.HashMultimap; import com.google.common.collect.ListMultimap; import com.google.common.collect.Multimap; import com.google.common.eventbus.EventBus; @@ -85,6 +89,9 @@ public abstract class WebPageTest { protected final HTTPRequest httpRequest = mock(HTTPRequest.class); protected final Multimap requestParameters = ArrayListMultimap.create(); protected final Map requestHeaders = new HashMap<>(); + private final Map uploadedFilesNames = new HashMap<>(); + private final Map uploadedFilesContentTypes = new HashMap<>(); + private final Map uploadedFilesSources = new HashMap<>(); protected final FreenetRequest freenetRequest = mock(FreenetRequest.class); private final PipedOutputStream responseOutputStream = new PipedOutputStream(); private final PipedInputStream responseInputStream; @@ -168,6 +175,36 @@ public abstract class WebPageTest { return requestHeaders.get(invocation.getArgument(0).toLowerCase()); } }); + when(httpRequest.getUploadedFile(anyString())).thenAnswer(new Answer() { + @Override + public HTTPUploadedFile answer(InvocationOnMock invocation) throws Throwable { + final String name = invocation.getArgument(0); + if (!uploadedFilesSources.containsKey(name)) { + return null; + } + return new HTTPUploadedFile() { + @Override + public String getContentType() { + return uploadedFilesContentTypes.get(name); + } + + @Override + public Bucket getData() { + try (InputStream inputStream = getClass().getResourceAsStream(uploadedFilesSources.get(name))) { + byte[] bytes = ByteStreams.toByteArray(inputStream); + return new SimpleReadOnlyArrayBucket(bytes, 0, bytes.length); + } catch (IOException ioe1) { + return new NullBucket(); + } + } + + @Override + public String getFilename() { + return uploadedFilesNames.get(name); + } + }; + } + }); } @Before @@ -204,6 +241,16 @@ public abstract class WebPageTest { } @Before + public void setupL10n() { + when(l10n.getString(anyString())).thenAnswer(new Answer() { + @Override + public String answer(InvocationOnMock invocation) throws Throwable { + return invocation.getArgument(0); + } + }); + } + + @Before public final void setupIdentityManager() { when(core.getIdentityManager().getAllOwnIdentities()).thenReturn(ownIdentities); } @@ -285,6 +332,12 @@ public abstract class WebPageTest { when(core.getTemporaryImage(eq(imageId))).thenReturn(temporaryImage); } + protected void addUploadedFile(@Nonnull String name, @Nonnull String filename, @Nonnull String contentType, @Nonnull String resource) { + uploadedFilesNames.put(name, filename); + uploadedFilesContentTypes.put(name, contentType); + uploadedFilesSources.put(name, resource); + } + protected byte[] getResponseBytes() throws IOException { response.getContent().close(); try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { diff --git a/src/test/kotlin/net/pterodactylus/sone/web/UploadImagePageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/UploadImagePageTest.kt index f63219f..0eb34d6 100644 --- a/src/test/kotlin/net/pterodactylus/sone/web/UploadImagePageTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/web/UploadImagePageTest.kt @@ -1,10 +1,20 @@ package net.pterodactylus.sone.web import net.pterodactylus.sone.data.Album +import net.pterodactylus.sone.data.Image +import net.pterodactylus.sone.data.Sone +import net.pterodactylus.sone.data.TemporaryImage import net.pterodactylus.sone.test.mock +import net.pterodactylus.sone.test.mockBuilder import net.pterodactylus.sone.test.whenever -import net.pterodactylus.util.web.Method +import net.pterodactylus.util.web.Method.POST +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo import org.junit.Test +import org.mockito.Mockito.any +import org.mockito.Mockito.eq +import org.mockito.Mockito.never +import org.mockito.Mockito.verify /** * Unit test for [UploadImagePage]. @@ -12,18 +22,78 @@ import org.junit.Test class UploadImagePageTest : WebPageTest() { private val parentAlbum = mock().apply { + whenever(id).thenReturn("parent-id") whenever(sone).thenReturn(currentSone) } override fun getPage() = UploadImagePage(template, webInterface) @Test + fun `get request does not redirect or upload anything`() { + page.handleRequest(freenetRequest, templateContext) + verify(core, never()).createTemporaryImage(any(), any()) + verify(core, never()).createImage(any(), any(), any()) + } + + @Test + fun `post request without parent results in no permission error page`() { + request("", POST) + verifyRedirect("noPermission.html") + } + + @Test + fun `post request with parent that is not the current sone results in no permission error page`() { + request("", POST) + addHttpRequestParameter("parent", "parent-id") + whenever(parentAlbum.sone).thenReturn(mock()) + addAlbum("parent-id", parentAlbum) + verifyRedirect("noPermission.html") + } + + @Test fun `post request with empty name redirects to error page`() { - request("", Method.POST) + request("", POST) addAlbum("parent-id", parentAlbum) addHttpRequestParameter("parent", "parent-id") addHttpRequestParameter("title", " ") verifyRedirect("emptyImageTitle.html") } + @Test + fun `uploading an invalid image results in no redirect and message set in template context`() { + request("", POST) + addAlbum("parent-id", parentAlbum) + addHttpRequestParameter("parent", "parent-id") + addHttpRequestParameter("title", "title") + addUploadedFile("image", "image.png", "image/png", "no-image.png") + page.handleRequest(freenetRequest, templateContext) + verify(core, never()).createTemporaryImage(any(), any()) + assertThat(templateContext["messages"] as String?, equalTo("Page.UploadImage.Error.InvalidImage")) + } + + @Test + fun `uploading a valid image uploads image and redirects to album browser`() { + request("", POST) + addAlbum("parent-id", parentAlbum) + addHttpRequestParameter("parent", "parent-id") + addHttpRequestParameter("title", "Title") + addHttpRequestParameter("description", "Description") + addUploadedFile("image", "image.png", "image/png", "image.png") + val temporaryImage = TemporaryImage("temp-image") + val imageModifier = mockBuilder() + val image = mock().apply { + whenever(modify()).thenReturn(imageModifier) + } + whenever(core.createTemporaryImage(eq("image/png"), any())).thenReturn(temporaryImage) + whenever(core.createImage(currentSone, parentAlbum, temporaryImage)).thenReturn(image) + verifyRedirect("imageBrowser.html?album=parent-id") { + verify(image).modify() + verify(imageModifier).setWidth(2) + verify(imageModifier).setHeight(1) + verify(imageModifier).setTitle("Title") + verify(imageModifier).setDescription("Description") + verify(imageModifier).update() + } + } + } diff --git a/src/test/resources/net/pterodactylus/sone/web/image.png b/src/test/resources/net/pterodactylus/sone/web/image.png new file mode 100644 index 0000000000000000000000000000000000000000..6daa8376daad7644939f0953b519de03c39ee803 GIT binary patch literal 3200 zcmZ`*cRUn+AHTDm?2$u-jI28=;~dW3>yi~`9uvvLoX=|WJ_^d+EW3K$6q5QW zLXTBM+c+$WmzN|a_lYn&)zz5LD_6*X1p+`{jJW7I437TF=I%ZSh*lmC={lk= z;D`>mxsE#VI|-p6XuI-~0^ZQtb6n0&kJx66XhtT_jr)P@Q34|@?PcC{Gj{CFgMU00 ztv8upw7**+4DglA8aziCs;!3aVbPSEQ`=Rukb>|@(#?8@T+<{|B%1|BT<>srFv<{I zhhpYzq#4$!q7tDv8IU4gI{qW%aCCJxh5TY(1fgzb=t_;3G zzdXJmD`rWMwdUd3dSTT?4XCwtsGhuFdvzHF$VmLgClm6Hg&x@UoiQ}*qNb!2`q~X; z|4^WM8?|p30|TWbg0UEg&85E|CSL)JZ)5cZhE$M>Ck8tvl_UQ^B?7BdAaZnuVNAw! zkWda!uymM=C+lwL4LgSWp|`i$_3y}UGgY(&RDe_%=<*Pz+Efoh7r0rqIrCJC5@{FC z`5}&t8Cd8#ReFX{D+~{5SP}fjCPuY*IJ zwl*}&4(hAGMJL#{>d6*(4iYIctLG^)O-kQBzb#ERyt z>5#XV?`5n}tZPd8jQL%{t9u!mVo#LvDqV%Gn4U+hg|; z_J^cg*?!POhBI~++uawZV^`Lf6JSk_6KXfLw-T3?m`{`M4-jSROSs;~VYgX%JaJ{? zqT9ti(OSl-xC@6h%S3*~8kz!G3k(4q;EvqB!a>P79OGrzko4s4akmM=XQ}SiHLHr=^pz~m3rk*t! z#1A3@fsF^3Bg^T^b;{B1!gXwQA_P&wMZ$%B>=yY&t^{}jtr3+G+gtK%PI$E`%k{{c z8fasB6DZOHx$Iln1ZtvdGHGgPO7*+vXBh|&d=;n^hzTqV96u;JG$HN~>4*} z8XgpFKcIRMRY|4Br&XY{kaR`#ndlnNE3Mt|mBf{*wEDCxi>3*1C8vYl9C2=G&SdWH zoXuP;lPUGJXzgg#=yfJ2-yxqEpCex^{}G=hG7q_j>_M_3JCLO#ppj1_=_7F?Mov+Z z(&^&qs_7{3qq2yy*bUUA|D=`|nS6$I#5ATMxPjG=+|Tx~V+XrK0}2PxfmT7^LDynf zG^9GoI(0jbbS?NZkToNgg^XwmOCx#J2GhfGP+8s!rV=kRv?*);&0>zHRwb|!O|xoa zJ(E)N$0p0>1hcoM9@jz&c}f{`Z>#3p&c_yIJKtZ@80fZwTg6+YTV+{!)TF!we<=L0 z?|lVU3!}t;@J6jaTZvrD9u3OXdWRcUC>t-`x12%bl+5I|x^mxQa58ol*O@PD7~XLu zjbvBT>mZFZr&Z=y<>Uun1^>&r%$W;o?b1}CVXwFHDE5Z4L4m=F0IR@g(SstDqGf}p z0|osn&MD4s`_cVs{iXfOVh=_0L?M<a|);%PGrc3;L<;3E!!Q z6Y!TQwX}85>(G;{lbe<6wcQg6lQ|VRcm|xE+!(BaiPq^bq!IWIw!!d*1bn_1g3~E_^&RTc4WqnCxzkr(IrO&QXY0yhsR~i)>kiTeZN%tLf1yDxr-py8at8luCpaOIH*CP zC7?vG$)%Ry@@1YgSaxf_VV`ye|4QDoZ|{9vaP09qsQ{_D2j|DFdbP$;nPTM$Sb^-= zPVy%sv5p@d&k3|!wF&I;_;`2lCWjQ~dV@>Qm-j*Uj_%Cg=++W!61=ESVQ8pKF@BtzaUIXz1C~wDV5C^pr0}+$4O)LdzP<`WAyXDM1^3=$8N0%k9Lsk>Bo@TQ`-^;0MIa>O&}m6ll}DD zNP#i6z*`vT!yG-Z5PK&N2Qv@U>0N}o`(<2s*x99f7y1C{C{X?nqRb^dHr$+KQjh1#`vP$ zEY&esv^(xJG$lz1adG%hKmSnu9qDgWi@&K-QZoNV{Y~{7^(+>ckrxJiTBfsNC`rJf z|B(HOheOXQ^;_kBwdJSuv@c2^IP|X`D}l7frz%d{PN$=;VoG(vkw{N=4gmmw4@i&u T=Jc7)UWAT@p?bNhUHHENe@dAd literal 0 HcmV?d00001 diff --git a/src/test/resources/net/pterodactylus/sone/web/no-image.png b/src/test/resources/net/pterodactylus/sone/web/no-image.png new file mode 100644 index 0000000..e69de29 -- 2.7.4