--- /dev/null
+package net.pterodactylus.sone.core;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.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}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+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<Sone>() {
+ @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;
+ }
+
+}