X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Ftest%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FSoneDownloaderTest.java;h=be697b3c6abd335f774655694e0cf56f48229dea;hp=73920ff93fdab514d7b5f5db20e68b15e18335a3;hb=534abb5d5dba7f0377856d2d067ae48538226680;hpb=fa06db9c6e864183b2582a3cc3ed93df74d8a8cb diff --git a/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java b/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java index 73920ff..be697b3 100644 --- a/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java +++ b/src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java @@ -1,33 +1,203 @@ package net.pterodactylus.sone.core; -import static org.mockito.Matchers.eq; +import static freenet.keys.InsertableClientSSK.createRandom; +import static java.lang.System.currentTimeMillis; +import static java.util.concurrent.TimeUnit.DAYS; +import static net.pterodactylus.sone.data.Sone.SoneStatus.downloading; +import static net.pterodactylus.sone.data.Sone.SoneStatus.idle; +import static net.pterodactylus.sone.data.Sone.SoneStatus.unknown; +import static net.pterodactylus.sone.web.AllPagesTestKt.getBaseInjector; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.mockito.ArgumentCaptor.forClass; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import net.pterodactylus.sone.core.SoneDownloader.FetchSoneWithUri; +import java.io.IOException; +import java.io.InputStream; + +import net.pterodactylus.sone.core.FreenetInterface.Fetched; import net.pterodactylus.sone.data.Sone; +import net.pterodactylus.sone.data.Sone.SoneStatus; +import net.pterodactylus.sone.freenet.wot.Identity; +import freenet.client.ClientMetadata; +import freenet.client.FetchResult; +import freenet.client.async.USKCallback; +import freenet.crypt.DummyRandomSource; import freenet.keys.FreenetURI; +import freenet.keys.InsertableClientSSK; +import freenet.support.api.Bucket; +import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; /** - * Unit test for {@link SoneDownloader} and its subclasses. + * Unit test for {@link SoneDownloaderImpl} and its subclasses. * * @author David ‘Bombe’ Roden */ public class SoneDownloaderTest { + private final Core core = mock(Core.class); + private final FreenetInterface freenetInterface = mock(FreenetInterface.class); + private final SoneParser soneParser = mock(SoneParser.class); + private final SoneDownloaderImpl soneDownloader = new SoneDownloaderImpl(core, freenetInterface, soneParser); + private FreenetURI requestUri = mock(FreenetURI.class); + private Sone sone = mock(Sone.class); + + @Before + public void setupSone() { + Sone sone = SoneDownloaderTest.this.sone; + Identity identity = mock(Identity.class); + InsertableClientSSK clientSSK = createRandom(new DummyRandomSource(), "WoT"); + when(identity.getRequestUri()).thenReturn(clientSSK.getURI().toString()); + when(identity.getId()).thenReturn("identity"); + when(sone.getId()).thenReturn("identity"); + when(sone.getIdentity()).thenReturn(identity); + requestUri = clientSSK.getURI().setKeyType("USK").setDocName("Sone"); + when(sone.getRequestUri()).thenAnswer(new Answer() { + @Override + public FreenetURI answer(InvocationOnMock invocation) + throws Throwable { + return requestUri; + } + }); + when(sone.getTime()).thenReturn(currentTimeMillis() - DAYS.toMillis(1)); + } + + private void setupSoneAsUnknown() { + when(sone.getTime()).thenReturn(0L); + } + + @Test + public void addingASoneWillRegisterItsKey() { + soneDownloader.addSone(sone); + verify(freenetInterface).registerActiveUsk(eq(sone.getRequestUri()), any( + USKCallback.class)); + verify(freenetInterface, never()).unregisterUsk(sone); + } + + @Test + public void addingASoneTwiceWillAlsoDeregisterItsKey() { + soneDownloader.addSone(sone); + soneDownloader.addSone(sone); + verify(freenetInterface, times(2)).registerActiveUsk(eq( + sone.getRequestUri()), any(USKCallback.class)); + verify(freenetInterface).unregisterUsk(sone); + } + + + @Test + public void stoppingTheSoneDownloaderUnregistersTheSone() { + soneDownloader.addSone(sone); + soneDownloader.stop(); + verify(freenetInterface).unregisterUsk(sone); + } + + @Test + public void notBeingAbleToFetchAnUnknownSoneDoesNotUpdateCore() { + FreenetURI finalRequestUri = requestUri.sskForUSK() + .setMetaString(new String[] { "sone.xml" }); + setupSoneAsUnknown(); + soneDownloader.fetchSoneAction(sone).run(); + verify(freenetInterface).fetchUri(finalRequestUri); + verifyThatSoneStatusWasChangedToDownloadingAndBackTo(unknown); + verify(core, never()).updateSone(any(Sone.class)); + } + + private void verifyThatSoneStatusWasChangedToDownloadingAndBackTo(SoneStatus soneStatus) { + ArgumentCaptor soneStatuses = forClass(SoneStatus.class); + verify(sone, times(2)).setStatus(soneStatuses.capture()); + assertThat(soneStatuses.getAllValues().get(0), is(downloading)); + assertThat(soneStatuses.getAllValues().get(1), is(soneStatus)); + } + + @Test + public void notBeingAbleToFetchAKnownSoneDoesNotUpdateCore() { + FreenetURI finalRequestUri = requestUri.sskForUSK() + .setMetaString(new String[] { "sone.xml" }); + soneDownloader.fetchSoneAction(sone).run(); + verify(freenetInterface).fetchUri(finalRequestUri); + verifyThatSoneStatusWasChangedToDownloadingAndBackTo(idle); + verify(core, never()).updateSone(any(Sone.class)); + } + + @Test(expected = NullPointerException.class) + public void exceptionWhileFetchingAnUnknownSoneDoesNotUpdateCore() { + FreenetURI finalRequestUri = requestUri.sskForUSK() + .setMetaString(new String[] { "sone.xml" }); + setupSoneAsUnknown(); + when(freenetInterface.fetchUri(finalRequestUri)).thenThrow(NullPointerException.class); + try { + soneDownloader.fetchSoneAction(sone).run(); + } finally { + verify(freenetInterface).fetchUri(finalRequestUri); + verifyThatSoneStatusWasChangedToDownloadingAndBackTo(unknown); + verify(core, never()).updateSone(any(Sone.class)); + } + } + + @Test(expected = NullPointerException.class) + public void exceptionWhileFetchingAKnownSoneDoesNotUpdateCore() { + FreenetURI finalRequestUri = requestUri.sskForUSK() + .setMetaString(new String[] { "sone.xml" }); + when(freenetInterface.fetchUri(finalRequestUri)).thenThrow( NullPointerException.class); + try { + soneDownloader.fetchSoneAction(sone).run(); + } finally { + verify(freenetInterface).fetchUri(finalRequestUri); + verifyThatSoneStatusWasChangedToDownloadingAndBackTo(idle); + verify(core, never()).updateSone(any(Sone.class)); + } + } + + @Test + public void fetchingSoneWithInvalidXmlWillNotUpdateTheCore() throws IOException { + final Fetched fetchResult = createFetchResult(requestUri, getClass().getResourceAsStream("sone-parser-not-xml.xml")); + when(freenetInterface.fetchUri(requestUri)).thenReturn(fetchResult); + soneDownloader.fetchSoneAction(sone).run(); + verify(core, never()).updateSone(any(Sone.class)); + } + + @Test + public void exceptionWhileFetchingSoneWillNotUpdateTheCore() throws IOException { + final Fetched fetchResult = createFetchResult(requestUri, getClass().getResourceAsStream("sone-parser-no-payload.xml")); + when(core.soneBuilder()).thenReturn(null); + when(freenetInterface.fetchUri(requestUri)).thenReturn(fetchResult); + soneDownloader.fetchSoneAction(sone).run(); + verify(core, never()).updateSone(any(Sone.class)); + } + + @Test + public void onlyFetchingASoneWillNotUpdateTheCore() throws IOException { + final Fetched fetchResult = createFetchResult(requestUri, getClass().getResourceAsStream("sone-parser-no-payload.xml")); + when(freenetInterface.fetchUri(requestUri)).thenReturn(fetchResult); + soneDownloader.fetchSone(sone, sone.getRequestUri(), true); + verify(core, never()).updateSone(any(Sone.class)); + verifyThatSoneStatusWasChangedToDownloadingAndBackTo(idle); + } + + private Fetched createFetchResult(FreenetURI uri, InputStream inputStream) throws IOException { + ClientMetadata clientMetadata = new ClientMetadata("application/xml"); + Bucket bucket = mock(Bucket.class); + when(bucket.getInputStream()).thenReturn(inputStream); + FetchResult fetchResult = new FetchResult(clientMetadata, bucket); + return new Fetched(uri, fetchResult); + } + @Test - public void fetchSoneWithUriDownloadsSoneWithUri() { - SoneDownloader soneDownloader = mock(SoneDownloader.class); - Sone sone = mock(Sone.class); - FreenetURI soneUri = mock(FreenetURI.class); - when(sone.getRequestUri()).thenReturn(soneUri); - FetchSoneWithUri fetchSoneWithUri = soneDownloader.new FetchSoneWithUri(sone); - fetchSoneWithUri.run(); - verify(soneDownloader).fetchSone(eq(sone), eq(soneUri)); + public void soneDownloaderCanBeCreatedByDependencyInjection() { + assertThat(getBaseInjector().getInstance(SoneDownloader.class), notNullValue()); } }