--- /dev/null
+package net.pterodactylus.sone.web;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Map;
+
+import net.pterodactylus.sone.core.Core;
+import net.pterodactylus.sone.data.Album;
+import net.pterodactylus.sone.data.IdBuilder;
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.web.page.FreenetRequest;
+import net.pterodactylus.sone.web.page.FreenetTemplatePage.RedirectException;
+import net.pterodactylus.util.template.Template;
+import net.pterodactylus.util.template.TemplateContext;
+import net.pterodactylus.util.web.Method;
+
+import freenet.support.api.HTTPRequest;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang.StringUtils;
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+/**
+ * Unit test for {@link DeleteAlbumPageTest}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class DeleteAlbumPageTest {
+
+ private static final String SONE_ID = StringUtils.repeat("s", 43);
+ private static final String ALBUM_ID = StringUtils.repeat("a", IdBuilder.ID_STRING_LENGTH);
+ private static final String PARENT_ALBUM_ID = StringUtils.repeat("b", IdBuilder.ID_STRING_LENGTH);
+ private final Template template = mock(Template.class);
+ private final Core core = mock(Core.class);
+ private final WebInterface webInterface = mock(WebInterface.class);
+ private final DeleteAlbumPage deleteAlbumPage = new DeleteAlbumPage(template, webInterface);
+ private final TemplateContext templateContext = new TemplateContext();
+ private final Album parentAlbum = mock(Album.class);
+ private final Album album = mock(Album.class);
+ private final Sone sone = mock(Sone.class);
+
+ @Before
+ public void setupCore() {
+ when(core.getAlbum(anyString())).thenAnswer(new Answer<Optional<Album>>() {
+ @Override
+ public Optional<Album> answer(InvocationOnMock invocation) throws Throwable {
+ return ALBUM_ID.equals(invocation.getArguments()[0]) ? Optional.of(album) : Optional.<Album>absent();
+ }
+ });
+ }
+
+ @Before
+ public void setupWebInterface() {
+ when(webInterface.getCore()).thenReturn(core);
+ }
+
+ @Before
+ public void setupAlbums() {
+ when(album.getId()).thenReturn(ALBUM_ID);
+ when(album.getSone()).thenReturn(sone);
+ when(album.getParent()).thenReturn(parentAlbum);
+ when(parentAlbum.getId()).thenReturn(PARENT_ALBUM_ID);
+ }
+
+ @Before
+ public void setupSone() {
+ when(sone.getId()).thenReturn(SONE_ID);
+ when(sone.getRootAlbum()).thenReturn(parentAlbum);
+ }
+
+ @Test
+ public void gettingAValidAlbumStoresAlbumInTemplateContext() throws RedirectException {
+ FreenetRequest request = createFreenetRequest(Method.GET, ImmutableMap.of("album", ALBUM_ID));
+ deleteAlbumPage.processSonePage(request, templateContext);
+ assertThat(templateContext.get("album"), Matchers.<Object>is(album));
+ }
+
+ @Test(expected = RedirectException.class)
+ public void gettingAnInvalidAlbumThrowsRedirectException() throws RedirectException {
+ try {
+ FreenetRequest request = createFreenetRequest(Method.GET, ImmutableMap.of("album", "foo"));
+ deleteAlbumPage.processSonePage(request, templateContext);
+ } catch (RedirectException e) {
+ assertThat(e.getTarget(), is("invalid.html"));
+ throw e;
+ }
+ }
+
+ @Test(expected = RedirectException.class)
+ public void postingAnInvalidAlbumIdWillRedirect() throws RedirectException {
+ try {
+ FreenetRequest request = createFreenetRequest(Method.POST, ImmutableMap.of("album", "foo"));
+ deleteAlbumPage.processSonePage(request, templateContext);
+ } catch (RedirectException e) {
+ assertThat(e.getTarget(), is("invalid.html"));
+ throw e;
+ }
+ }
+
+ @Test(expected = RedirectException.class)
+ public void deletingAnAlbumOfARemoteSoneWillRedirect() throws RedirectException {
+ try {
+ FreenetRequest request = createFreenetRequest(Method.POST, ImmutableMap.of("album", ALBUM_ID));
+ deleteAlbumPage.processSonePage(request, templateContext);
+ } catch (RedirectException e) {
+ assertThat(e.getTarget(), is("noPermission.html"));
+ throw e;
+ }
+ }
+
+ @Test(expected = RedirectException.class)
+ public void abortingTheDeleteWillRedirect() throws RedirectException {
+ try {
+ when(sone.isLocal()).thenReturn(true);
+ FreenetRequest request = createFreenetRequest(Method.POST, ImmutableMap.of("album", ALBUM_ID, "abortDelete", "true"));
+ deleteAlbumPage.processSonePage(request, templateContext);
+ } catch (RedirectException e) {
+ assertThat(e.getTarget(), is(String.format("imageBrowser.html?album=%s", ALBUM_ID)));
+ throw e;
+ }
+ }
+
+ @Test(expected = RedirectException.class)
+ public void deletingAnAlbumFromTheRootAlbumRedirectsToSoneImageBrowser() throws RedirectException {
+ try {
+ when(sone.isLocal()).thenReturn(true);
+ FreenetRequest request = createFreenetRequest(Method.POST, ImmutableMap.of("album", ALBUM_ID));
+ deleteAlbumPage.processSonePage(request, templateContext);
+ } catch (RedirectException e) {
+ assertThat(e.getTarget(), is(String.format("imageBrowser.html?sone=%s", SONE_ID)));
+ verify(core).deleteAlbum(album);
+ throw e;
+ }
+ }
+
+ @Test(expected = RedirectException.class)
+ public void deletingAnAlbumNotFromTheRootAlbumRedirectsToParentAlbumImageBrowser() throws RedirectException {
+ try {
+ when(sone.isLocal()).thenReturn(true);
+ when(sone.getRootAlbum()).thenReturn(mock(Album.class));
+ FreenetRequest request = createFreenetRequest(Method.POST, ImmutableMap.of("album", ALBUM_ID));
+ deleteAlbumPage.processSonePage(request, templateContext);
+ } catch (RedirectException e) {
+ assertThat(e.getTarget(), is(String.format("imageBrowser.html?album=%s", PARENT_ALBUM_ID)));
+ verify(core).deleteAlbum(album);
+ throw e;
+ }
+ }
+
+ private static FreenetRequest createFreenetRequest(Method method, final Map<String, String> parameters) {
+ HTTPRequest httpRequest = mock(HTTPRequest.class);
+ when(httpRequest.getParam(anyString())).thenAnswer(new Answer<String>() {
+ @Override
+ public String answer(InvocationOnMock invocation) throws Throwable {
+ if (parameters.containsKey(invocation.getArguments()[0])) {
+ return parameters.get(invocation.getArguments()[0]);
+ }
+ return "";
+ }
+ });
+ when(httpRequest.getParam(anyString(), anyString())).thenAnswer(new Answer<String>() {
+ @Override
+ public String answer(InvocationOnMock invocation) throws Throwable {
+ if (parameters.containsKey(invocation.getArguments()[0])) {
+ return parameters.get(invocation.getArguments()[0]);
+ }
+ return (String) invocation.getArguments()[1];
+ }
+ });
+ when(httpRequest.getPartAsStringFailsafe(anyString(), anyInt())).thenAnswer(new Answer<String>() {
+ @Override
+ public String answer(InvocationOnMock invocation) throws Throwable {
+ if (parameters.containsKey(invocation.getArguments()[0])) {
+ return StringUtils.left(parameters.get(invocation.getArguments()[0]), (Integer) invocation.getArguments()[1]);
+ }
+ return "";
+ }
+ });
+ when(httpRequest.isPartSet(anyString())).thenAnswer(new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ return parameters.containsKey(invocation.getArguments()[0]);
+ }
+ });
+ return new FreenetRequest(null, method, httpRequest, null);
+ }
+
+}