1 package net.pterodactylus.sone.core;
3 import static java.lang.Long.MAX_VALUE;
4 import static net.pterodactylus.sone.main.SonePlugin.VERSION;
5 import static org.hamcrest.MatcherAssert.assertThat;
6 import static org.hamcrest.Matchers.instanceOf;
7 import static org.hamcrest.Matchers.is;
8 import static org.mockito.ArgumentCaptor.forClass;
9 import static org.mockito.Matchers.any;
10 import static org.mockito.Matchers.argThat;
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.io.IOException;
18 import java.io.InputStream;
20 import net.pterodactylus.sone.core.FreenetInterface.Callback;
21 import net.pterodactylus.sone.core.FreenetInterface.Fetched;
22 import net.pterodactylus.sone.core.event.UpdateFoundEvent;
23 import net.pterodactylus.util.version.Version;
25 import freenet.client.ClientMetadata;
26 import freenet.client.FetchResult;
27 import freenet.keys.FreenetURI;
28 import freenet.support.api.Bucket;
29 import freenet.support.io.ArrayBucket;
31 import com.google.common.eventbus.EventBus;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.mockito.ArgumentCaptor;
35 import org.mockito.invocation.InvocationOnMock;
36 import org.mockito.stubbing.Answer;
39 * Unit test for {@link UpdateChecker}.
41 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
43 public class UpdateCheckerTest {
45 private final EventBus eventBus = mock(EventBus.class);
46 private final FreenetInterface freenetInterface = mock(FreenetInterface.class);
47 private final UpdateChecker updateChecker = new UpdateChecker(eventBus, freenetInterface);
50 public void startUpdateChecker() {
51 updateChecker.start();
55 public void newUpdateCheckerDoesNotHaveALatestVersion() {
56 assertThat(updateChecker.hasLatestVersion(), is(false));
57 assertThat(updateChecker.getLatestVersion(), is(VERSION));
61 public void startingAnUpdateCheckerRegisterAUsk() {
62 verify(freenetInterface).registerUsk(any(FreenetURI.class), any(Callback.class));
66 public void stoppingAnUpdateCheckerUnregistersAUsk() {
68 verify(freenetInterface).unregisterUsk(any(FreenetURI.class));
72 public void callbackDoesNotDownloadIfNewEditionIsNotFound() {
73 setupCallbackWithEdition(MAX_VALUE, false, false);
74 verify(freenetInterface, never()).fetchUri(any(FreenetURI.class));
75 verify(eventBus, never()).post(argThat(instanceOf(UpdateFoundEvent.class)));
78 private void setupCallbackWithEdition(long edition, boolean newKnownGood, boolean newSlot) {
79 ArgumentCaptor<FreenetURI> uri = forClass(FreenetURI.class);
80 ArgumentCaptor<Callback> callback = forClass(Callback.class);
81 verify(freenetInterface).registerUsk(uri.capture(), callback.capture());
82 callback.getValue().editionFound(uri.getValue(), edition, newKnownGood, newSlot);
86 public void callbackStartsIfNewEditionIsFound() {
87 setupFetchResult(createFutureFetchResult());
88 setupCallbackWithEdition(MAX_VALUE, true, false);
89 verifyAFreenetUriIsFetched();
90 ArgumentCaptor<UpdateFoundEvent> updateFoundEvent = forClass(UpdateFoundEvent.class);
91 verify(eventBus, times(1)).post(updateFoundEvent.capture());
92 assertThat(updateFoundEvent.getValue().version(), is(new Version(99, 0, 0)));
93 assertThat(updateFoundEvent.getValue().releaseTime(), is(11865368297000L));
94 assertThat(updateChecker.getLatestVersion(), is(new Version(99, 0, 0)));
95 assertThat(updateChecker.getLatestVersionDate(), is(11865368297000L));
96 assertThat(updateChecker.hasLatestVersion(), is(true));
99 private FetchResult createFutureFetchResult() {
100 ClientMetadata clientMetadata = new ClientMetadata("application/xml");
101 Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
102 "CurrentVersion/Version: 99.0.0\n" +
103 "CurrentVersion/ReleaseTime: 11865368297000").getBytes());
104 return new FetchResult(clientMetadata, fetched);
108 public void callbackDoesNotStartIfNoNewEditionIsFound() {
109 setupFetchResult(createPastFetchResult());
110 setupCallbackWithEdition(updateChecker.getLatestEdition(), true, false);
111 verifyAFreenetUriIsFetched();
112 verifyNoUpdateFoundEventIsFired();
115 private void setupFetchResult(final FetchResult pastFetchResult) {
116 when(freenetInterface.fetchUri(any(FreenetURI.class))).thenAnswer(new Answer<Fetched>() {
118 public Fetched answer(InvocationOnMock invocation) throws Throwable {
119 FreenetURI freenetUri = (FreenetURI) invocation.getArguments()[0];
120 return new Fetched(freenetUri, pastFetchResult);
125 private FetchResult createPastFetchResult() {
126 ClientMetadata clientMetadata = new ClientMetadata("application/xml");
127 Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
128 "CurrentVersion/Version: 0.2\n" +
129 "CurrentVersion/ReleaseTime: 1289417883000").getBytes());
130 return new FetchResult(clientMetadata, fetched);
134 public void invalidUpdateFileDoesNotStartCallback() {
135 setupFetchResult(createInvalidFetchResult());
136 setupCallbackWithEdition(MAX_VALUE, true, false);
137 verifyAFreenetUriIsFetched();
138 verifyNoUpdateFoundEventIsFired();
141 private FetchResult createInvalidFetchResult() {
142 ClientMetadata clientMetadata = new ClientMetadata("text/plain");
143 Bucket fetched = new ArrayBucket("Some other data.".getBytes());
144 return new FetchResult(clientMetadata, fetched);
148 public void nonExistingPropertiesWillNotCauseUpdateToBeFound() {
149 setupCallbackWithEdition(MAX_VALUE, true, false);
150 verifyAFreenetUriIsFetched();
151 verifyNoUpdateFoundEventIsFired();
154 private void verifyNoUpdateFoundEventIsFired() {
155 verify(eventBus, never()).post(any(UpdateFoundEvent.class));
158 private void verifyAFreenetUriIsFetched() {
159 verify(freenetInterface).fetchUri(any(FreenetURI.class));
163 public void brokenBucketDoesNotCauseUpdateToBeFound() {
164 setupFetchResult(createBrokenBucketFetchResult());
165 setupCallbackWithEdition(MAX_VALUE, true, false);
166 verifyAFreenetUriIsFetched();
167 verifyNoUpdateFoundEventIsFired();
170 private FetchResult createBrokenBucketFetchResult() {
171 ClientMetadata clientMetadata = new ClientMetadata("text/plain");
172 Bucket fetched = new ArrayBucket("Some other data.".getBytes()) {
174 public InputStream getInputStream() {
176 return when(mock(InputStream.class).read()).thenThrow(IOException.class).getMock();
177 } catch (IOException ioe1) {
178 /* won’t throw here. */
183 return new FetchResult(clientMetadata, fetched);
187 public void invalidTimeDoesNotCauseAnUpdateToBeFound() {
188 setupFetchResult(createInvalidTimeFetchResult());
189 setupCallbackWithEdition(MAX_VALUE, true, false);
190 verifyAFreenetUriIsFetched();
191 verifyNoUpdateFoundEventIsFired();
194 private FetchResult createInvalidTimeFetchResult() {
195 ClientMetadata clientMetadata = new ClientMetadata("application/xml");
196 Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
197 "CurrentVersion/Version: 0.2\n" +
198 "CurrentVersion/ReleaseTime: invalid").getBytes());
199 return new FetchResult(clientMetadata, fetched);
203 public void invalidPropertiesDoesNotCauseAnUpdateToBeFound() {
204 setupFetchResult(createMissingTimeFetchResult());
205 setupCallbackWithEdition(MAX_VALUE, true, false);
206 verifyAFreenetUriIsFetched();
207 verifyNoUpdateFoundEventIsFired();
210 private FetchResult createMissingTimeFetchResult() {
211 ClientMetadata clientMetadata = new ClientMetadata("application/xml");
212 Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
213 "CurrentVersion/Version: 0.2\n").getBytes());
214 return new FetchResult(clientMetadata, fetched);
218 public void invalidVersionDoesNotCauseAnUpdateToBeFound() {
219 setupFetchResult(createInvalidVersionFetchResult());
220 setupCallbackWithEdition(MAX_VALUE, true, false);
221 verifyAFreenetUriIsFetched();
222 verifyNoUpdateFoundEventIsFired();
225 private FetchResult createInvalidVersionFetchResult() {
226 ClientMetadata clientMetadata = new ClientMetadata("application/xml");
227 Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
228 "CurrentVersion/Version: foo\n" +
229 "CurrentVersion/ReleaseTime: 1289417883000").getBytes());
230 return new FetchResult(clientMetadata, fetched);