From 91e2eb453b5ad6345cb3587e7cc6326b6c3831f0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Fri, 15 Nov 2019 20:05:50 +0100 Subject: [PATCH] =?utf8?q?=E2=8F=AA=20Revert=20all=20changes=20to=20the=20?= =?utf8?q?rescue=20system?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../net/pterodactylus/sone/core/SoneRescuer.java | 28 +++-- .../net/pterodactylus/sone/web/pages/RescuePage.kt | 9 +- src/main/resources/i18n/sone.de.properties | 1 - src/main/resources/i18n/sone.en.properties | 1 - src/main/resources/i18n/sone.es.properties | 3 +- src/main/resources/i18n/sone.fr.properties | 3 +- src/main/resources/i18n/sone.ja.properties | 3 +- src/main/resources/i18n/sone.no.properties | 3 +- src/main/resources/i18n/sone.pl.properties | 3 +- src/main/resources/i18n/sone.ru.properties | 3 +- src/main/resources/templates/rescue.html | 10 +- .../pterodactylus/sone/core/SoneRescuerTest.java | 134 +++++++++++++++++++++ .../net/pterodactylus/sone/core/SoneRescuerTest.kt | 125 ------------------- .../pterodactylus/sone/web/pages/RescuePageTest.kt | 22 +++- 14 files changed, 184 insertions(+), 164 deletions(-) create mode 100644 src/test/java/net/pterodactylus/sone/core/SoneRescuerTest.java delete mode 100644 src/test/kotlin/net/pterodactylus/sone/core/SoneRescuerTest.kt diff --git a/src/main/java/net/pterodactylus/sone/core/SoneRescuer.java b/src/main/java/net/pterodactylus/sone/core/SoneRescuer.java index 6045127..2246ac9 100644 --- a/src/main/java/net/pterodactylus/sone/core/SoneRescuer.java +++ b/src/main/java/net/pterodactylus/sone/core/SoneRescuer.java @@ -108,6 +108,18 @@ public class SoneRescuer extends AbstractService { } /** + * Sets the edition to rescue. + * + * @param edition + * The edition to rescue + * @return This Sone rescuer + */ + public SoneRescuer setEdition(long edition) { + currentEdition = edition; + return this; + } + + /** * Sets whether the last fetch was successful. * * @return {@code true} if the last fetch was successful, {@code false} @@ -123,22 +135,15 @@ public class SoneRescuer extends AbstractService { // /** - * Starts the next fetch. + * Starts the next fetch. If you want to fetch a different edition than “the + * next older one,” remember to call {@link #setEdition(long)} before + * calling this method. */ public void startNextFetch() { fetching = true; notifySyncObject(); } - /** - * Starts the next fetch. - */ - public void startNextFetchWithSkip() { - currentEdition--; - fetching = true; - notifySyncObject(); - } - // // SERVICE METHODS // @@ -154,14 +159,13 @@ public class SoneRescuer extends AbstractService { } if (fetching) { core.lockSone(sone); - FreenetURI soneUri = sone.getRequestUri().setKeyType("SSK").setDocName("Sone-" + getNextEdition()).setMetaString(new String[] { "sone.xml" }); + FreenetURI soneUri = sone.getRequestUri().setKeyType("SSK").setDocName("Sone-" + currentEdition).setMetaString(new String[] { "sone.xml" }); System.out.println("URI: " + soneUri); Sone fetchedSone = soneDownloader.fetchSone(sone, soneUri, true); System.out.println("Sone: " + fetchedSone); lastFetchSuccessful = (fetchedSone != null); if (lastFetchSuccessful) { core.updateSone(fetchedSone, true); - currentEdition = getNextEdition(); } fetching = false; } diff --git a/src/main/kotlin/net/pterodactylus/sone/web/pages/RescuePage.kt b/src/main/kotlin/net/pterodactylus/sone/web/pages/RescuePage.kt index 1cbc725..2ed4940 100644 --- a/src/main/kotlin/net/pterodactylus/sone/web/pages/RescuePage.kt +++ b/src/main/kotlin/net/pterodactylus/sone/web/pages/RescuePage.kt @@ -21,12 +21,15 @@ class RescuePage @Inject constructor(webInterface: WebInterface, loaders: Loader val soneRescuer = soneRequest.core.getSoneRescuer(currentSone) templateContext["soneRescuer"] = soneRescuer if (soneRequest.isPOST) { + soneRequest.parameters["edition", 9]?.toIntOrNull()?.also { + if (it > -1) { + soneRescuer.setEdition(it.toLong()) + } + } if (soneRequest.parameters["fetch", 8] == "true") { soneRescuer.startNextFetch() - } else if (soneRequest.parameters["fetchSkip"] == "true") { - soneRescuer.startNextFetchWithSkip() } - redirectTo("rescue.html") + throw RedirectException("rescue.html") } } diff --git a/src/main/resources/i18n/sone.de.properties b/src/main/resources/i18n/sone.de.properties index 09e03a1..b4c68d7 100644 --- a/src/main/resources/i18n/sone.de.properties +++ b/src/main/resources/i18n/sone.de.properties @@ -307,7 +307,6 @@ Page.Rescue.Text.FetchedLast=Die Sonerettung hat die letzte verfügbare Version Page.Rescue.Text.NotFetched=Die Sonerettung konnte Version {0} Ihrer Sone nicht herunter laden. Bitte versuchen Sie erneut, Version {0} herunter zu laden, oder versuchen Sie die nächstältere Version. Page.Rescue.Label.NextEdition=Nächste Version Page.Rescue.Button.Fetch=Version herunter laden -Page.Rescue.Button.FetchSkip=Eine Version überspringen Page.NoPermission.Title=Unberechtigter Zugriff - Sone Page.NoPermission.Page.Title=Unberechtigter Zugriff diff --git a/src/main/resources/i18n/sone.en.properties b/src/main/resources/i18n/sone.en.properties index 4f874f6..c539fe2 100644 --- a/src/main/resources/i18n/sone.en.properties +++ b/src/main/resources/i18n/sone.en.properties @@ -309,7 +309,6 @@ Page.Rescue.Text.FetchedLast=The Sone rescuer has downloaded the last available Page.Rescue.Text.NotFetched=The Sone Rescuer could not download edition {0} of your Sone. Please either try again with edition {0}, or try the next older edition. Page.Rescue.Label.NextEdition=Next edition Page.Rescue.Button.Fetch=Fetch edition -Page.Rescue.Button.FetchSkip=Skip one edition Page.NoPermission.Title=Unauthorized Access - Sone Page.NoPermission.Page.Title=Unauthorized Access diff --git a/src/main/resources/i18n/sone.es.properties b/src/main/resources/i18n/sone.es.properties index 1eb698c..c280a7d 100644 --- a/src/main/resources/i18n/sone.es.properties +++ b/src/main/resources/i18n/sone.es.properties @@ -307,7 +307,6 @@ Page.Rescue.Text.FetchedLast=El rescatador de Sone ha descargado la última ver Page.Rescue.Text.NotFetched=El rescatador de Sone no ha podido descargar la edición {0} de tu Sone. Por favor, vuelve ha intentarlo con la edición {0}, o prueba con la siguiente versión antigua. Page.Rescue.Label.NextEdition=Siguiente edición Page.Rescue.Button.Fetch=Obtener edición -Page.Rescue.Button.FetchSkip=Skip one edition Page.NoPermission.Title=Acceso desautorizado - Sone Page.NoPermission.Page.Title=Acceso desautorizado @@ -472,4 +471,4 @@ Notification.Mention.Text=Has sido mencionado en las siguientes publicaciones: Notification.SoneIsInserting.Text=Tu Sone sone://{0} está siendo insertado. Notification.SoneIsInserted.Text=Tu Sone sone://{0} ha sido insertado en {1,number} {1,choice,0#segundos|1#segundo|1

<%= Page.Rescue.Text.Fetched|l10n 0=soneRescuer.currentEdition|html>

<%else> -

<%= Page.Rescue.Text.NotFetched|l10n 0=soneRescuer.nextEdition|html>

+

<%= Page.Rescue.Text.NotFetched|l10n 0=soneRescuer.currentEdition|html>

<%/if>
-
- <%= Page.Rescue.Label.NextEdition|l10n|html>: <%soneRescuer.nextEdition> - - -
+ + +
<%else> <%if soneRescuer.lastFetchSuccessful> diff --git a/src/test/java/net/pterodactylus/sone/core/SoneRescuerTest.java b/src/test/java/net/pterodactylus/sone/core/SoneRescuerTest.java new file mode 100644 index 0000000..ff49a4c --- /dev/null +++ b/src/test/java/net/pterodactylus/sone/core/SoneRescuerTest.java @@ -0,0 +1,134 @@ +package net.pterodactylus.sone.core; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import net.pterodactylus.sone.data.Sone; + +import freenet.keys.FreenetURI; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +/** + * Unit test for {@link SoneRescuer}. + */ +public class SoneRescuerTest { + + private static final long CURRENT_EDITION = 12L; + private static final long SOME_OTHER_EDITION = 15L; + private final Core core = mock(Core.class); + private final SoneDownloader soneDownloader = mock(SoneDownloader.class); + private final Sone sone = mock(Sone.class); + private SoneRescuer soneRescuer; + + @Before + public void setupSone() { + FreenetURI soneUri = mock(FreenetURI.class); + when(soneUri.getEdition()).thenReturn(CURRENT_EDITION); + when(sone.getRequestUri()).thenReturn(soneUri); + } + + @Before + public void setupSoneRescuer() { + soneRescuer = new SoneRescuer(core, soneDownloader, sone); + } + + @Test + public void newSoneRescuerIsNotFetchingAnything() { + assertThat(soneRescuer.isFetching(), is(false)); + } + + @Test + public void newSoneRescuerStartsAtCurrentEditionOfSone() { + assertThat(soneRescuer.getCurrentEdition(), is(CURRENT_EDITION)); + } + + @Test + public void newSoneRescuerHasANextEditionToGet() { + assertThat(soneRescuer.hasNextEdition(), is(true)); + } + + @Test + public void soneRescuerDoesNotHaveANextEditionIfCurrentEditionIsZero() { + when(sone.getRequestUri().getEdition()).thenReturn(0L); + soneRescuer = new SoneRescuer(core, soneDownloader, sone); + assertThat(soneRescuer.hasNextEdition(), is(false)); + } + + @Test + public void nextEditionIsOneSmallerThanTheCurrentEdition() { + assertThat(soneRescuer.getNextEdition(), is(CURRENT_EDITION - 1)); + } + + @Test + public void currentEditionCanBeSet() { + soneRescuer.setEdition(SOME_OTHER_EDITION); + assertThat(soneRescuer.getCurrentEdition(), is(SOME_OTHER_EDITION)); + } + + @Test + public void lastFetchOfANewSoneRescuerWasSuccessful() { + assertThat(soneRescuer.isLastFetchSuccessful(), is(true)); + } + + @Test + public void mainLoopStopsWhenItShould() { + soneRescuer.stop(); + soneRescuer.serviceRun(); + } + + @Test + public void successfulInsert() { + final Sone fetchedSone = mock(Sone.class); + returnUriOnInsert(fetchedSone); + soneRescuer.startNextFetch(); + soneRescuer.serviceRun(); + verify(core).lockSone(eq(sone)); + verify(core).updateSone(eq(fetchedSone), eq(true)); + assertThat(soneRescuer.isLastFetchSuccessful(), is(true)); + assertThat(soneRescuer.isFetching(), is(false)); + } + + @Test + public void nonSuccessfulInsertIsRecognized() { + returnUriOnInsert(null); + soneRescuer.startNextFetch(); + soneRescuer.serviceRun(); + verify(core).lockSone(eq(sone)); + verify(core, never()).updateSone(any(Sone.class), eq(true)); + assertThat(soneRescuer.isLastFetchSuccessful(), is(false)); + assertThat(soneRescuer.isFetching(), is(false)); + } + + private void returnUriOnInsert(final Sone fetchedSone) { + FreenetURI keyWithMetaStrings = setupFreenetUri(); + doAnswer(new Answer() { + @Override + public Sone answer(InvocationOnMock invocation) throws Throwable { + soneRescuer.stop(); + return fetchedSone; + } + }).when(soneDownloader).fetchSone(eq(sone), eq(keyWithMetaStrings), eq(true)); + } + + private FreenetURI setupFreenetUri() { + FreenetURI sskKey = mock(FreenetURI.class); + FreenetURI keyWithDocName = mock(FreenetURI.class); + FreenetURI keyWithMetaStrings = mock(FreenetURI.class); + when(keyWithDocName.setMetaString(eq(new String[] { "sone.xml" }))).thenReturn(keyWithMetaStrings); + when(sskKey.setDocName(eq("Sone-" + CURRENT_EDITION))).thenReturn(keyWithDocName); + when(sone.getRequestUri().setKeyType(eq("SSK"))).thenReturn(sskKey); + return keyWithMetaStrings; + } + +} diff --git a/src/test/kotlin/net/pterodactylus/sone/core/SoneRescuerTest.kt b/src/test/kotlin/net/pterodactylus/sone/core/SoneRescuerTest.kt deleted file mode 100644 index 1fd2553..0000000 --- a/src/test/kotlin/net/pterodactylus/sone/core/SoneRescuerTest.kt +++ /dev/null @@ -1,125 +0,0 @@ -package net.pterodactylus.sone.core - -import freenet.keys.* -import net.pterodactylus.sone.data.* -import net.pterodactylus.sone.test.* -import org.hamcrest.MatcherAssert.* -import org.hamcrest.Matchers.equalTo -import org.mockito.ArgumentMatchers.any -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mockito.doAnswer -import org.mockito.Mockito.never -import org.mockito.Mockito.verify -import kotlin.test.Test - -/** - * Unit test for [SoneRescuer]. - */ -class SoneRescuerTest { - - private val core = mock() - private val soneDownloader = mock() - private val sone = mock().apply { - val soneUri = mock() - whenever(soneUri.edition).thenReturn(currentEdition) - whenever(requestUri).thenReturn(soneUri) - } - private val soneRescuer = SoneRescuer(core, soneDownloader, sone) - - @Test - fun newSoneRescuerIsNotFetchingAnything() { - assertThat(soneRescuer.isFetching, equalTo(false)) - } - - @Test - fun newSoneRescuerStartsAtCurrentEditionOfSone() { - assertThat(soneRescuer.currentEdition, equalTo(currentEdition)) - } - - @Test - fun newSoneRescuerHasANextEditionToGet() { - assertThat(soneRescuer.hasNextEdition(), equalTo(true)) - } - - @Test - fun soneRescuerDoesNotHaveANextEditionIfCurrentEditionIsZero() { - whenever(sone.requestUri.edition).thenReturn(0L) - val soneRescuer = SoneRescuer(core, soneDownloader, sone) - assertThat(soneRescuer.hasNextEdition(), equalTo(false)) - } - - @Test - fun nextEditionIsOneSmallerThanTheCurrentEdition() { - assertThat(soneRescuer.nextEdition, equalTo(currentEdition - 1)) - } - - @Test - fun lastFetchOfANewSoneRescuerWasSuccessful() { - assertThat(soneRescuer.isLastFetchSuccessful, equalTo(true)) - } - - @Test - fun mainLoopStopsWhenItShould() { - soneRescuer.stop() - soneRescuer.serviceRun() - } - - @Test - fun successfulInsert() { - val fetchedSone = mock() - returnUriOnInsert(fetchedSone, currentEdition - 1) - soneRescuer.startNextFetch() - soneRescuer.serviceRun() - verify(core).lockSone(eq(sone)) - verify(core).updateSone(eq(fetchedSone), eq(true)) - assertThat(soneRescuer.isLastFetchSuccessful, equalTo(true)) - assertThat(soneRescuer.isFetching, equalTo(false)) - assertThat(soneRescuer.currentEdition, equalTo(currentEdition - 1)) - } - - @Test - fun `starting fetch with skipping one edition skips one edition`() { - val fetchedSone = mock() - returnUriOnInsert(fetchedSone, currentEdition - 2) - soneRescuer.startNextFetchWithSkip() - soneRescuer.serviceRun() - verify(core).lockSone(eq(sone)) - verify(core).updateSone(eq(fetchedSone), eq(true)) - assertThat(soneRescuer.isLastFetchSuccessful, equalTo(true)) - assertThat(soneRescuer.isFetching, equalTo(false)) - assertThat(soneRescuer.currentEdition, equalTo(currentEdition - 2)) - } - - @Test - fun nonSuccessfulInsertIsRecognized() { - returnUriOnInsert(null, (currentEdition - 1)) - soneRescuer.startNextFetch() - soneRescuer.serviceRun() - verify(core).lockSone(eq(sone)) - verify(core, never()).updateSone(any(Sone::class.java), eq(true)) - assertThat(soneRescuer.isLastFetchSuccessful, equalTo(false)) - assertThat(soneRescuer.isFetching, equalTo(false)) - assertThat(soneRescuer.currentEdition, equalTo(currentEdition)) - } - - private fun returnUriOnInsert(fetchedSone: Sone?, edition: Long) { - val keyWithMetaStrings = setupFreenetUri(edition) - doAnswer { - soneRescuer.stop() - fetchedSone - }.whenever(soneDownloader).fetchSone(eq(sone), eq(keyWithMetaStrings), eq(true)) - } - - private fun setupFreenetUri(edition: Long): FreenetURI { - val sskKey = mock() - val keyWithDocName = mock() - val keyWithMetaStrings = mock() - whenever(keyWithDocName.setMetaString(eq(arrayOf("sone.xml")))).thenReturn(keyWithMetaStrings) - whenever(sskKey.setDocName(eq("Sone-" + edition))).thenReturn(keyWithDocName) - whenever(sone.requestUri.setKeyType(eq("SSK"))).thenReturn(sskKey) - return keyWithMetaStrings - } - -} - -private const val currentEdition = 12L diff --git a/src/test/kotlin/net/pterodactylus/sone/web/pages/RescuePageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/pages/RescuePageTest.kt index e653bbe..d11352f 100644 --- a/src/test/kotlin/net/pterodactylus/sone/web/pages/RescuePageTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/web/pages/RescuePageTest.kt @@ -54,20 +54,34 @@ class RescuePageTest : WebPageTest(::RescuePage) { } @Test - fun `post request with fetch starts next fetch`() { + fun `post request with fetch and invalid edition starts next fetch`() { setMethod(POST) addHttpRequestPart("fetch", "true") verifyRedirect("rescue.html") { + verify(soneRescuer, never()).setEdition(anyLong()) verify(soneRescuer).startNextFetch() } } @Test - fun `post request with skipping fetch starts next skipping fetch`() { + fun `post request with fetch and valid edition sets edition and starts next fetch`() { setMethod(POST) - addHttpRequestPart("fetchSkip", "true") + addHttpRequestPart("fetch", "true") + addHttpRequestPart("edition", "123") + verifyRedirect("rescue.html") { + verify(soneRescuer).setEdition(123L) + verify(soneRescuer).startNextFetch() + } + } + + @Test + fun `post request with negative edition will not set edition`() { + setMethod(POST) + addHttpRequestPart("fetch", "true") + addHttpRequestPart("edition", "-123") verifyRedirect("rescue.html") { - verify(soneRescuer).startNextFetchWithSkip() + verify(soneRescuer, never()).setEdition(anyLong()) + verify(soneRescuer).startNextFetch() } } -- 2.7.4