1 package net.pterodactylus.sone.core;
3 import static org.hamcrest.MatcherAssert.assertThat;
4 import static org.hamcrest.Matchers.containsInAnyOrder;
5 import static org.hamcrest.Matchers.instanceOf;
6 import static org.hamcrest.Matchers.is;
7 import static org.mockito.Matchers.any;
8 import static org.mockito.Matchers.argThat;
9 import static org.mockito.Matchers.eq;
10 import static org.mockito.Mockito.doAnswer;
11 import static org.mockito.Mockito.mock;
12 import static org.mockito.Mockito.never;
13 import static org.mockito.Mockito.times;
14 import static org.mockito.Mockito.verify;
15 import static org.mockito.Mockito.when;
17 import java.util.HashMap;
19 import net.pterodactylus.sone.core.SoneInserter.InsertInformation;
20 import net.pterodactylus.sone.core.SoneInserter.SetInsertionDelay;
21 import net.pterodactylus.sone.core.event.SoneEvent;
22 import net.pterodactylus.sone.core.event.SoneInsertAbortedEvent;
23 import net.pterodactylus.sone.core.event.SoneInsertedEvent;
24 import net.pterodactylus.sone.core.event.SoneInsertingEvent;
25 import net.pterodactylus.sone.data.Album;
26 import net.pterodactylus.sone.data.Sone;
28 import freenet.keys.FreenetURI;
30 import com.google.common.eventbus.EventBus;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.mockito.ArgumentCaptor;
34 import org.mockito.invocation.InvocationOnMock;
35 import org.mockito.stubbing.Answer;
38 * Unit test for {@link SoneInserter} and its subclasses.
40 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
42 public class SoneInserterTest {
44 private final Core core = mock(Core.class);
45 private final EventBus eventBus = mock(EventBus.class);
46 private final FreenetInterface freenetInterface = mock(FreenetInterface.class);
49 public void setupCore() {
50 UpdateChecker updateChecker = mock(UpdateChecker.class);
51 when(core.getUpdateChecker()).thenReturn(updateChecker);
55 public void insertionDelayIsForwardedToSoneInserter() {
56 SetInsertionDelay setInsertionDelay = new SetInsertionDelay();
57 setInsertionDelay.optionChanged(null, null, 15);
58 assertThat(SoneInserter.getInsertionDelay().get(), is(15));
62 /* this test is hilariously bad. */
63 public void manifestEntriesAreCreated() {
64 FreenetURI insertUri = mock(FreenetURI.class);
65 String fingerprint = "fingerprint";
66 Sone sone = createSone(insertUri, fingerprint);
67 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone);
68 InsertInformation insertInformation = soneInserter.new InsertInformation(sone);
69 HashMap<String, Object> manifestEntries = insertInformation.generateManifestEntries();
70 assertThat(manifestEntries.keySet(), containsInAnyOrder("index.html", "sone.xml"));
71 assertThat(insertInformation.getInsertUri(), is(insertUri));
72 assertThat(insertInformation.getFingerprint(), is(fingerprint));
75 private Sone createSone(FreenetURI insertUri, String fingerprint) {
76 Sone sone = mock(Sone.class);
77 when(sone.getInsertUri()).thenReturn(insertUri);
78 when(sone.getFingerprint()).thenReturn(fingerprint);
79 when(sone.getRootAlbum()).thenReturn(mock(Album.class));
83 @Test(expected = IllegalArgumentException.class)
84 public void soneOfSoneInserterCanNotBeSetToADifferentSone() {
85 Sone sone = mock(Sone.class);
86 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone);
87 soneInserter.setSone(mock(Sone.class));
91 public void soneCanBeSetToEqualSone() {
92 Sone sone = mock(Sone.class);
93 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone);
94 soneInserter.setSone(sone);
98 public void isModifiedIsTrueIfModificationDetectorSaysSo() {
99 Sone sone = mock(Sone.class);
100 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
101 when(soneModificationDetector.isModified()).thenReturn(true);
102 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector, 1);
103 assertThat(soneInserter.isModified(), is(true));
107 public void isModifiedIsFalseIfModificationDetectorSaysSo() {
108 Sone sone = mock(Sone.class);
109 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
110 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector, 1);
111 assertThat(soneInserter.isModified(), is(false));
115 public void lastFingerprintIsStoredCorrectly() {
116 Sone sone = mock(Sone.class);
117 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone);
118 soneInserter.setLastInsertFingerprint("last-fingerprint");
119 assertThat(soneInserter.getLastInsertFingerprint(), is("last-fingerprint"));
123 public void soneInserterStopsWhenItShould() {
124 Sone sone = mock(Sone.class);
125 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone);
127 soneInserter.serviceRun();
131 public void soneInserterInsertsASoneIfItIsEligible() throws SoneException {
132 FreenetURI insertUri = mock(FreenetURI.class);
133 final FreenetURI finalUri = mock(FreenetURI.class);
134 String fingerprint = "fingerprint";
135 Sone sone = createSone(insertUri, fingerprint);
136 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
137 when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
138 when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenReturn(finalUri);
139 final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector, 1);
140 doAnswer(new Answer<Void>() {
142 public Void answer(InvocationOnMock invocation) throws Throwable {
146 }).when(core).touchConfiguration();
147 soneInserter.serviceRun();
148 ArgumentCaptor<SoneEvent> soneEvents = ArgumentCaptor.forClass(SoneEvent.class);
149 verify(freenetInterface).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"));
150 verify(eventBus, times(2)).post(soneEvents.capture());
151 assertThat(soneEvents.getAllValues().get(0), instanceOf(SoneInsertingEvent.class));
152 assertThat(soneEvents.getAllValues().get(0).sone(), is(sone));
153 assertThat(soneEvents.getAllValues().get(1), instanceOf(SoneInsertedEvent.class));
154 assertThat(soneEvents.getAllValues().get(1).sone(), is(sone));
158 public void soneInserterBailsOutIfItIsStoppedWhileInserting() throws SoneException {
159 FreenetURI insertUri = mock(FreenetURI.class);
160 final FreenetURI finalUri = mock(FreenetURI.class);
161 String fingerprint = "fingerprint";
162 Sone sone = createSone(insertUri, fingerprint);
163 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
164 when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
165 final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector, 1);
166 when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenAnswer(new Answer<FreenetURI>() {
168 public FreenetURI answer(InvocationOnMock invocation) throws Throwable {
173 soneInserter.serviceRun();
174 ArgumentCaptor<SoneEvent> soneEvents = ArgumentCaptor.forClass(SoneEvent.class);
175 verify(freenetInterface).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"));
176 verify(eventBus, times(2)).post(soneEvents.capture());
177 assertThat(soneEvents.getAllValues().get(0), instanceOf(SoneInsertingEvent.class));
178 assertThat(soneEvents.getAllValues().get(0).sone(), is(sone));
179 assertThat(soneEvents.getAllValues().get(1), instanceOf(SoneInsertedEvent.class));
180 assertThat(soneEvents.getAllValues().get(1).sone(), is(sone));
181 verify(core, never()).touchConfiguration();
185 public void soneInserterDoesNotInsertSoneIfItIsNotEligible() throws SoneException {
186 FreenetURI insertUri = mock(FreenetURI.class);
187 String fingerprint = "fingerprint";
188 Sone sone = createSone(insertUri, fingerprint);
189 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
190 final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector, 1);
191 new Thread(new Runnable() {
196 } catch (InterruptedException ie1) {
197 throw new RuntimeException(ie1);
202 soneInserter.serviceRun();
203 verify(freenetInterface, never()).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"));
204 verify(eventBus, never()).post(argThat(org.hamcrest.Matchers.any(SoneEvent.class)));
208 public void soneInserterPostsAbortedEventIfAnExceptionOccurs() throws SoneException {
209 FreenetURI insertUri = mock(FreenetURI.class);
210 String fingerprint = "fingerprint";
211 Sone sone = createSone(insertUri, fingerprint);
212 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
213 when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
214 final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, sone, soneModificationDetector, 1);
215 final SoneException soneException = new SoneException(new Exception());
216 when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenAnswer(new Answer<FreenetURI>() {
218 public FreenetURI answer(InvocationOnMock invocation) throws Throwable {
223 soneInserter.serviceRun();
224 ArgumentCaptor<SoneEvent> soneEvents = ArgumentCaptor.forClass(SoneEvent.class);
225 verify(freenetInterface).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"));
226 verify(eventBus, times(2)).post(soneEvents.capture());
227 assertThat(soneEvents.getAllValues().get(0), instanceOf(SoneInsertingEvent.class));
228 assertThat(soneEvents.getAllValues().get(0).sone(), is(sone));
229 assertThat(soneEvents.getAllValues().get(1), instanceOf(SoneInsertAbortedEvent.class));
230 assertThat(soneEvents.getAllValues().get(1).sone(), is(sone));
231 verify(core, never()).touchConfiguration();