Don’t set insert URI of a Sone, let it be generated from the identity.
[Sone.git] / src / test / java / net / pterodactylus / sone / core / SoneInserterTest.java
1 package net.pterodactylus.sone.core;
2
3 import static com.google.common.base.Optional.absent;
4 import static com.google.common.base.Optional.of;
5 import static org.hamcrest.MatcherAssert.assertThat;
6 import static org.hamcrest.Matchers.containsInAnyOrder;
7 import static org.hamcrest.Matchers.instanceOf;
8 import static org.hamcrest.Matchers.is;
9 import static org.mockito.Matchers.any;
10 import static org.mockito.Matchers.anyString;
11 import static org.mockito.Matchers.argThat;
12 import static org.mockito.Matchers.eq;
13 import static org.mockito.Mockito.doAnswer;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.never;
16 import static org.mockito.Mockito.times;
17 import static org.mockito.Mockito.verify;
18 import static org.mockito.Mockito.when;
19
20 import java.util.HashMap;
21
22 import net.pterodactylus.sone.core.SoneInserter.InsertInformation;
23 import net.pterodactylus.sone.core.SoneInserter.SetInsertionDelay;
24 import net.pterodactylus.sone.core.event.SoneEvent;
25 import net.pterodactylus.sone.core.event.SoneInsertAbortedEvent;
26 import net.pterodactylus.sone.core.event.SoneInsertedEvent;
27 import net.pterodactylus.sone.core.event.SoneInsertingEvent;
28 import net.pterodactylus.sone.data.Album;
29 import net.pterodactylus.sone.data.Sone;
30
31 import freenet.keys.FreenetURI;
32
33 import com.google.common.base.Optional;
34 import com.google.common.eventbus.EventBus;
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.mockito.ArgumentCaptor;
38 import org.mockito.invocation.InvocationOnMock;
39 import org.mockito.stubbing.Answer;
40
41 /**
42  * Unit test for {@link SoneInserter} and its subclasses.
43  *
44  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
45  */
46 public class SoneInserterTest {
47
48         private final Core core = mock(Core.class);
49         private final EventBus eventBus = mock(EventBus.class);
50         private final FreenetInterface freenetInterface = mock(FreenetInterface.class);
51
52         @Before
53         public void setupCore() {
54                 UpdateChecker updateChecker = mock(UpdateChecker.class);
55                 when(core.getUpdateChecker()).thenReturn(updateChecker);
56                 when(core.getSone(anyString())).thenReturn(Optional.<Sone>absent());
57         }
58
59         @Test
60         public void insertionDelayIsForwardedToSoneInserter() {
61                 SetInsertionDelay setInsertionDelay = new SetInsertionDelay();
62                 setInsertionDelay.optionChanged(null, null, 15);
63                 assertThat(SoneInserter.getInsertionDelay().get(), is(15));
64         }
65
66         @Test
67         /* this test is hilariously bad. */
68         public void manifestEntriesAreCreated() {
69                 FreenetURI insertUri = mock(FreenetURI.class);
70                 String fingerprint = "fingerprint";
71                 Sone sone = createSone(insertUri, fingerprint);
72                 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId");
73                 InsertInformation insertInformation = soneInserter.new InsertInformation(sone);
74                 HashMap<String, Object> manifestEntries = insertInformation.generateManifestEntries();
75                 assertThat(manifestEntries.keySet(), containsInAnyOrder("index.html", "sone.xml"));
76                 assertThat(insertInformation.getFingerprint(), is(fingerprint));
77         }
78
79         private Sone createSone(FreenetURI insertUri, String fingerprint) {
80                 Sone sone = mock(Sone.class);
81                 when(sone.getInsertUri()).thenReturn(insertUri);
82                 when(sone.getFingerprint()).thenReturn(fingerprint);
83                 when(sone.getRootAlbum()).thenReturn(mock(Album.class));
84                 when(core.getSone(anyString())).thenReturn(of(sone));
85                 return sone;
86         }
87
88         @Test
89         public void isModifiedIsTrueIfModificationDetectorSaysSo() {
90                 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
91                 when(soneModificationDetector.isModified()).thenReturn(true);
92                 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
93                 assertThat(soneInserter.isModified(), is(true));
94         }
95
96         @Test
97         public void isModifiedIsFalseIfModificationDetectorSaysSo() {
98                 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
99                 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
100                 assertThat(soneInserter.isModified(), is(false));
101         }
102
103         @Test
104         public void lastFingerprintIsStoredCorrectly() {
105                 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId");
106                 soneInserter.setLastInsertFingerprint("last-fingerprint");
107                 assertThat(soneInserter.getLastInsertFingerprint(), is("last-fingerprint"));
108         }
109
110         @Test
111         public void soneInserterStopsWhenItShould() {
112                 SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId");
113                 soneInserter.stop();
114                 soneInserter.serviceRun();
115         }
116
117         @Test
118         public void soneInserterInsertsASoneIfItIsEligible() throws SoneException {
119                 FreenetURI insertUri = mock(FreenetURI.class);
120                 final FreenetURI finalUri = mock(FreenetURI.class);
121                 String fingerprint = "fingerprint";
122                 Sone sone = createSone(insertUri, fingerprint);
123                 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
124                 when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
125                 when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenReturn(finalUri);
126                 final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
127                 doAnswer(new Answer<Void>() {
128                         @Override
129                         public Void answer(InvocationOnMock invocation) throws Throwable {
130                                 soneInserter.stop();
131                                 return null;
132                         }
133                 }).when(core).touchConfiguration();
134                 soneInserter.serviceRun();
135                 ArgumentCaptor<SoneEvent> soneEvents = ArgumentCaptor.forClass(SoneEvent.class);
136                 verify(freenetInterface).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"));
137                 verify(eventBus, times(2)).post(soneEvents.capture());
138                 assertThat(soneEvents.getAllValues().get(0), instanceOf(SoneInsertingEvent.class));
139                 assertThat(soneEvents.getAllValues().get(0).sone(), is(sone));
140                 assertThat(soneEvents.getAllValues().get(1), instanceOf(SoneInsertedEvent.class));
141                 assertThat(soneEvents.getAllValues().get(1).sone(), is(sone));
142         }
143
144         @Test
145         public void soneInserterBailsOutIfItIsStoppedWhileInserting() throws SoneException {
146                 FreenetURI insertUri = mock(FreenetURI.class);
147                 final FreenetURI finalUri = mock(FreenetURI.class);
148                 String fingerprint = "fingerprint";
149                 Sone sone = createSone(insertUri, fingerprint);
150                 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
151                 when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
152                 final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
153                 when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenAnswer(new Answer<FreenetURI>() {
154                         @Override
155                         public FreenetURI answer(InvocationOnMock invocation) throws Throwable {
156                                 soneInserter.stop();
157                                 return finalUri;
158                         }
159                 });
160                 soneInserter.serviceRun();
161                 ArgumentCaptor<SoneEvent> soneEvents = ArgumentCaptor.forClass(SoneEvent.class);
162                 verify(freenetInterface).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"));
163                 verify(eventBus, times(2)).post(soneEvents.capture());
164                 assertThat(soneEvents.getAllValues().get(0), instanceOf(SoneInsertingEvent.class));
165                 assertThat(soneEvents.getAllValues().get(0).sone(), is(sone));
166                 assertThat(soneEvents.getAllValues().get(1), instanceOf(SoneInsertedEvent.class));
167                 assertThat(soneEvents.getAllValues().get(1).sone(), is(sone));
168                 verify(core, never()).touchConfiguration();
169         }
170
171         @Test
172         public void soneInserterDoesNotInsertSoneIfItIsNotEligible() throws SoneException {
173                 FreenetURI insertUri = mock(FreenetURI.class);
174                 String fingerprint = "fingerprint";
175                 Sone sone = createSone(insertUri, fingerprint);
176                 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
177                 final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
178                 new Thread(new Runnable() {
179                         @Override
180                         public void run() {
181                                 try {
182                                         Thread.sleep(500);
183                                 } catch (InterruptedException ie1) {
184                                         throw new RuntimeException(ie1);
185                                 }
186                                 soneInserter.stop();
187                         }
188                 }).start();
189                 soneInserter.serviceRun();
190                 verify(freenetInterface, never()).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"));
191                 verify(eventBus, never()).post(argThat(org.hamcrest.Matchers.any(SoneEvent.class)));
192         }
193
194         @Test
195         public void soneInserterPostsAbortedEventIfAnExceptionOccurs() throws SoneException {
196                 FreenetURI insertUri = mock(FreenetURI.class);
197                 String fingerprint = "fingerprint";
198                 Sone sone = createSone(insertUri, fingerprint);
199                 SoneModificationDetector soneModificationDetector = mock(SoneModificationDetector.class);
200                 when(soneModificationDetector.isEligibleForInsert()).thenReturn(true);
201                 final SoneInserter soneInserter = new SoneInserter(core, eventBus, freenetInterface, "SoneId", soneModificationDetector, 1);
202                 final SoneException soneException = new SoneException(new Exception());
203                 when(freenetInterface.insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"))).thenAnswer(new Answer<FreenetURI>() {
204                         @Override
205                         public FreenetURI answer(InvocationOnMock invocation) throws Throwable {
206                                 soneInserter.stop();
207                                 throw soneException;
208                         }
209                 });
210                 soneInserter.serviceRun();
211                 ArgumentCaptor<SoneEvent> soneEvents = ArgumentCaptor.forClass(SoneEvent.class);
212                 verify(freenetInterface).insertDirectory(eq(insertUri), any(HashMap.class), eq("index.html"));
213                 verify(eventBus, times(2)).post(soneEvents.capture());
214                 assertThat(soneEvents.getAllValues().get(0), instanceOf(SoneInsertingEvent.class));
215                 assertThat(soneEvents.getAllValues().get(0).sone(), is(sone));
216                 assertThat(soneEvents.getAllValues().get(1), instanceOf(SoneInsertAbortedEvent.class));
217                 assertThat(soneEvents.getAllValues().get(1).sone(), is(sone));
218                 verify(core, never()).touchConfiguration();
219         }
220
221 }