Add test for Sone downloader.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Thu, 7 Aug 2014 17:22:03 +0000 (19:22 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Thu, 7 Aug 2014 17:22:03 +0000 (19:22 +0200)
52 files changed:
src/test/java/net/pterodactylus/sone/core/SoneDownloaderTest.java
src/test/resources/net/pterodactylus/sone/core/sone-parser-missing-client-name.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-missing-client-version.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-missing-protocol-version.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-negative-protocol-version.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-no-payload.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-no-profile.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-no-time.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-not-xml.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-profile-duplicate-field-name.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-profile-empty-field-name.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-profile-missing-field-name.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-time-not-numeric.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-too-large-protocol-version.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-client-info.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-image.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-image-height.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-image-width.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-parent-album-id.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-post-reply-time.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-post-time.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-recipient.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-request-uri.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-liked-post-ids.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-liked-post-reply-ids.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-multiple-albums.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-profile.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-recipient.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-request-uri.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-valid-post-reply-time.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-valid-post-time.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-with-zero-time.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-album-id.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-album-title.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-albums.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-fields.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-height.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-id.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-key.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-time.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-title.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-width.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-images.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-liked-post-ids.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-liked-post-reply-ids.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-id.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-id.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-post-id.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-text.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-time.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-text.xml [new file with mode: 0644]
src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-time.xml [new file with mode: 0644]

index 21d01f6..31e83f7 100644 (file)
@@ -1,17 +1,66 @@
 package net.pterodactylus.sone.core;
 
+import static com.google.common.base.Optional.of;
+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 org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+import static org.mockito.ArgumentCaptor.forClass;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.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 java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import net.pterodactylus.sone.core.FreenetInterface.Fetched;
 import net.pterodactylus.sone.core.SoneDownloader.FetchSone;
 import net.pterodactylus.sone.core.SoneDownloader.FetchSoneWithUri;
+import net.pterodactylus.sone.data.Album;
+import net.pterodactylus.sone.data.AlbumImpl;
+import net.pterodactylus.sone.data.Client;
+import net.pterodactylus.sone.data.Image;
+import net.pterodactylus.sone.data.ImageImpl;
+import net.pterodactylus.sone.data.Post;
+import net.pterodactylus.sone.data.PostReply;
+import net.pterodactylus.sone.data.Profile;
 import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.data.Sone.SoneStatus;
+import net.pterodactylus.sone.database.PostBuilder;
+import net.pterodactylus.sone.database.PostReplyBuilder;
+import net.pterodactylus.sone.freenet.wot.Identity;
 
+import freenet.client.ClientMetadata;
+import freenet.client.FetchResult;
 import freenet.keys.FreenetURI;
+import freenet.support.api.Bucket;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+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.
@@ -20,6 +69,561 @@ import org.junit.Test;
  */
 public class SoneDownloaderTest {
 
+       private final Core core = mock(Core.class);
+       private final FreenetInterface freenetInterface = mock(FreenetInterface.class);
+       private final SoneDownloader soneDownloader = new SoneDownloader(core, freenetInterface);
+       private final FreenetURI requestUri = mock(FreenetURI.class);
+       private final Sone sone = mock(Sone.class);
+       private final PostBuilder postBuilder = mock(PostBuilder.class);
+       private final List<Post> createdPosts = new ArrayList<Post>();
+       private Post post = mock(Post.class);
+       private final PostReplyBuilder postReplyBuilder = mock(PostReplyBuilder.class);
+       private final Set<PostReply> createdPostReplies = new HashSet<PostReply>();
+       private PostReply postReply = mock(PostReply.class);
+       private final Map<String, Album> albums = new HashMap<String, Album>();
+
+       @Before
+       public void setupSone() {
+               Identity identity = mock(Identity.class);
+               when(identity.getId()).thenReturn("identity");
+               when(sone.getId()).thenReturn("identity");
+               when(sone.getIdentity()).thenReturn(identity);
+               when(sone.getRequestUri()).thenReturn(requestUri);
+       }
+
+       @Before
+       public void setupRequestUri() {
+               when(requestUri.setKeyType(anyString())).thenReturn(requestUri);
+               when(requestUri.sskForUSK()).thenReturn(requestUri);
+               when(requestUri.setDocName(anyString())).thenReturn(requestUri);
+               when(requestUri.setMetaString(any(String[].class))).thenReturn(requestUri);
+               when(requestUri.getKeyType()).thenReturn("USK");
+       }
+
+       @Before
+       public void setupPost() {
+               when(post.getRecipientId()).thenReturn(Optional.<String>absent());
+       }
+
+       @Before
+       public void setupPostBuilder() {
+               when(postBuilder.withId(anyString())).thenAnswer(new Answer<PostBuilder>() {
+                       @Override
+                       public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
+                               when(post.getId()).thenReturn((String) invocation.getArguments()[0]);
+                               return postBuilder;
+                       }
+               });
+               when(postBuilder.from(anyString())).thenAnswer(new Answer<PostBuilder>() {
+                       @Override
+                       public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
+                               final Sone sone = mock(Sone.class);
+                               when(sone.getId()).thenReturn((String) invocation.getArguments()[0]);
+                               when(post.getSone()).thenReturn(sone);
+                               return postBuilder;
+                       }
+               });
+               when(postBuilder.withTime(anyLong())).thenAnswer(new Answer<PostBuilder>() {
+                       @Override
+                       public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
+                               when(post.getTime()).thenReturn((Long) invocation.getArguments()[0]);
+                               return postBuilder;
+                       }
+               });
+               when(postBuilder.withText(anyString())).thenAnswer(new Answer<PostBuilder>() {
+                       @Override
+                       public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
+                               when(post.getText()).thenReturn((String) invocation.getArguments()[0]);
+                               return postBuilder;
+                       }
+               });
+               when(postBuilder.to(anyString())).thenAnswer(new Answer<PostBuilder>() {
+                       @Override
+                       public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
+                               when(post.getRecipientId()).thenReturn(of((String) invocation.getArguments()[0]));
+                               return postBuilder;
+                       }
+               });
+               when(postBuilder.build()).thenAnswer(new Answer<Post>() {
+                       @Override
+                       public Post answer(InvocationOnMock invocation) throws Throwable {
+                               Post post = SoneDownloaderTest.this.post;
+                               SoneDownloaderTest.this.post = mock(Post.class);
+                               setupPost();
+                               createdPosts.add(post);
+                               return post;
+                       }
+               });
+               when(core.postBuilder()).thenReturn(postBuilder);
+       }
+
+       @Before
+       public void setupPostReplyBuilder() {
+               when(postReplyBuilder.withId(anyString())).thenAnswer(new Answer<PostReplyBuilder>() {
+                       @Override
+                       public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable {
+                               when(postReply.getId()).thenReturn((String) invocation.getArguments()[0]);
+                               return postReplyBuilder;
+                       }
+               });
+               when(postReplyBuilder.from(anyString())).thenAnswer(new Answer<PostReplyBuilder>() {
+                       @Override
+                       public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable {
+                               Sone sone = when(mock(Sone.class).getId()).thenReturn((String) invocation.getArguments()[0]).getMock();
+                               when(postReply.getSone()).thenReturn(sone);
+                               return postReplyBuilder;
+                       }
+               });
+               when(postReplyBuilder.to(anyString())).thenAnswer(new Answer<PostReplyBuilder>() {
+                       @Override
+                       public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable {
+                               when(postReply.getPostId()).thenReturn((String) invocation.getArguments()[0]);
+                               Post post = when(mock(Post.class).getId()).thenReturn((String) invocation.getArguments()[0]).getMock();
+                               when(postReply.getPost()).thenReturn(of(post));
+                               return postReplyBuilder;
+                       }
+               });
+               when(postReplyBuilder.withTime(anyLong())).thenAnswer(new Answer<PostReplyBuilder>() {
+                       @Override
+                       public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable {
+                               when(postReply.getTime()).thenReturn((Long) invocation.getArguments()[0]);
+                               return postReplyBuilder;
+                       }
+               });
+               when(postReplyBuilder.withText(anyString())).thenAnswer(new Answer<PostReplyBuilder>() {
+                       @Override
+                       public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable {
+                               when(postReply.getText()).thenReturn((String) invocation.getArguments()[0]);
+                               return postReplyBuilder;
+                       }
+               });
+               when(postReplyBuilder.build()).thenAnswer(new Answer<PostReply>() {
+                       @Override
+                       public PostReply answer(InvocationOnMock invocation) throws Throwable {
+                               PostReply postReply = SoneDownloaderTest.this.postReply;
+                               createdPostReplies.add(postReply);
+                               SoneDownloaderTest.this.postReply = mock(PostReply.class);
+                               return postReply;
+                       }
+               });
+               when(core.postReplyBuilder()).thenReturn(postReplyBuilder);
+       }
+
+       @Before
+       public void setupAlbums() {
+               albums.put("album-id-1", new AlbumImpl("album-id-1"));
+               albums.put("album-id-2", new AlbumImpl("album-id-2"));
+               when(core.getAlbum(anyString())).thenAnswer(new Answer<Album>() {
+                       @Override
+                       public Album answer(InvocationOnMock invocation) throws Throwable {
+                               return albums.get(invocation.getArguments()[0]);
+                       }
+               });
+               when(core.getAlbum(anyString(), anyBoolean())).thenAnswer(new Answer<Album>() {
+                       @Override
+                       public Album answer(InvocationOnMock invocation) throws Throwable {
+                               return albums.get(invocation.getArguments()[0]);
+                       }
+               });
+       }
+
+       @Before
+       public void setupImages() {
+               Image image = new ImageImpl("image-id");
+               when(core.getImage("image-id")).thenReturn(image);
+               when(core.getImage(eq("image-id"), anyBoolean())).thenReturn(image);
+       }
+
+       @Test
+       public void addingASoneWillRegisterItsKey() {
+               soneDownloader.addSone(sone);
+               verify(freenetInterface).registerUsk(sone, soneDownloader);
+               verify(freenetInterface, never()).unregisterUsk(sone);
+       }
+
+       @Test
+       public void addingASoneTwiceWillAlsoDeregisterItsKey() {
+               soneDownloader.addSone(sone);
+               soneDownloader.addSone(sone);
+               verify(freenetInterface, times(2)).registerUsk(sone, soneDownloader);
+               verify(freenetInterface).unregisterUsk(sone);
+       }
+
+       @Test
+       public void parsingASoneFailsWhenDocumentIsNotXml() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-not-xml.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWhenDocumentHasNegativeProtocolVersion() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-negative-protocol-version.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWhenProtocolVersionIsTooLarge() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-too-large-protocol-version.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWhenThereIsNoTime() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-time.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWhenTimeIsNotNumeric() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-time-not-numeric.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWhenProfileIsMissing() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-profile.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWhenProfileFieldIsMissingAFieldName() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-missing-field-name.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWhenProfileFieldNameIsEmpty() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-empty-field-name.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWhenProfileFieldNameIsNotUnique() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-duplicate-field-name.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithoutPayload() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-payload.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream).getTime(), is(1407197508000L));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithoutProtocolVersion() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-protocol-version.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), not(nullValue()));
+       }
+
+       @Test
+       public void parsingASoneFailsWithMissingClientName() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-client-name.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithMissingClientVersion() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-client-version.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithClientInfo() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-client-info.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream).getClient(), is(new Client("some-client", "some-version")));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithRequestUri() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-request-uri.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream).getRequestUri().toString(), is("USK@w~RyTGmv12Lg9oO91q1Untupi7my9qczT1RheGkEkVE,E8ElVfUgukSCPHxIEJp-gHMiR80wpM7sID3Jo5O7w1s,AQACAAE/Sone/0"));
+       }
+
+       @Test
+       public void parsingASoneFailsWithInvalidRequestUri() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-request-uri.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void soneInsertUriIsCopiedToNewSone() throws SoneException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-payload.xml");
+               FreenetURI insertUri = mock(FreenetURI.class);
+               when(insertUri.setKeyType(anyString())).thenReturn(insertUri);
+               when(insertUri.setDocName(anyString())).thenReturn(insertUri);
+               when(insertUri.setMetaString(any(String[].class))).thenReturn(insertUri);
+               when(insertUri.setSuggestedEdition(anyLong())).thenReturn(insertUri);
+               when(sone.getInsertUri()).thenReturn(insertUri);
+               assertThat(soneDownloader.parseSone(sone, inputStream).getInsertUri(), is(insertUri));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithProfile() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-profile.xml");
+               final Profile profile = soneDownloader.parseSone(sone, inputStream).getProfile();
+               assertThat(profile.getFirstName(), is("first"));
+               assertThat(profile.getMiddleName(), is("middle"));
+               assertThat(profile.getLastName(), is("last"));
+               assertThat(profile.getBirthDay(), is(18));
+               assertThat(profile.getBirthMonth(), is(12));
+               assertThat(profile.getBirthYear(), is(1976));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithoutProfileFields() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-fields.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), notNullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutPostId() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-id.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutPostTime() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-time.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutPostText() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-text.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithInvalidPostTime() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-post-time.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithValidPostTime() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-valid-post-time.xml");
+               final List<Post> posts = soneDownloader.parseSone(sone, inputStream).getPosts();
+               assertThat(posts, is(createdPosts));
+               assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
+               assertThat(posts.get(0).getId(), is("post-id"));
+               assertThat(posts.get(0).getTime(), is(1407197508000L));
+               assertThat(posts.get(0).getRecipientId(), is(Optional.<String>absent()));
+               assertThat(posts.get(0).getText(), is("text"));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithRecipient() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-recipient.xml");
+               final List<Post> posts = soneDownloader.parseSone(sone, inputStream).getPosts();
+               assertThat(posts, is(createdPosts));
+               assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
+               assertThat(posts.get(0).getId(), is("post-id"));
+               assertThat(posts.get(0).getTime(), is(1407197508000L));
+               assertThat(posts.get(0).getRecipientId(), is(of("1234567890123456789012345678901234567890123")));
+               assertThat(posts.get(0).getText(), is("text"));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithInvalidRecipient() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-recipient.xml");
+               final List<Post> posts = soneDownloader.parseSone(sone, inputStream).getPosts();
+               assertThat(posts, is(createdPosts));
+               assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
+               assertThat(posts.get(0).getId(), is("post-id"));
+               assertThat(posts.get(0).getTime(), is(1407197508000L));
+               assertThat(posts.get(0).getRecipientId(), is(Optional.<String>absent()));
+               assertThat(posts.get(0).getText(), is("text"));
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutPostReplyId() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-id.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutPostReplyPostId() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-post-id.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutPostReplyTime() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-time.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutPostReplyText() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-text.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithInvalidPostReplyTime() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-post-reply-time.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithValidPostReplyTime() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-valid-post-reply-time.xml");
+               final Set<PostReply> postReplies = soneDownloader.parseSone(sone, inputStream).getReplies();
+               assertThat(postReplies, is(createdPostReplies));
+               PostReply postReply = createdPostReplies.iterator().next();
+               assertThat(postReply.getId(), is("reply-id"));
+               assertThat(postReply.getPostId(), is("post-id"));
+               assertThat(postReply.getPost().get().getId(), is("post-id"));
+               assertThat(postReply.getSone().getId(), is("identity"));
+               assertThat(postReply.getTime(), is(1407197508000L));
+               assertThat(postReply.getText(), is("reply-text"));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithoutLikedPostIds() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-liked-post-ids.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), not(nullValue()));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithLikedPostIds() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-liked-post-ids.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream).getLikedPostIds(), is((Set<String>) ImmutableSet.of("liked-post-id")));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithoutLikedPostReplyIds() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-liked-post-reply-ids.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), not(nullValue()));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithLikedPostReplyIds() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-liked-post-reply-ids.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream).getLikedReplyIds(), is((Set<String>) ImmutableSet.of("liked-post-reply-id")));
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithoutAlbums() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-albums.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), not(nullValue()));
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutAlbumId() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-album-id.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutAlbumTitle() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-album-title.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithNestedAlbums() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-multiple-albums.xml");
+               final Sone parsedSone = soneDownloader.parseSone(sone, inputStream);
+               assertThat(parsedSone, not(nullValue()));
+               assertThat(parsedSone.getRootAlbum().getAlbums(), hasSize(1));
+               Album album = parsedSone.getRootAlbum().getAlbums().get(0);
+               assertThat(album.getId(), is("album-id-1"));
+               assertThat(album.getTitle(), is("album-title"));
+               assertThat(album.getDescription(), is("album-description"));
+               assertThat(album.getAlbums(), hasSize(1));
+               Album nestedAlbum = album.getAlbums().get(0);
+               assertThat(nestedAlbum.getId(), is("album-id-2"));
+               assertThat(nestedAlbum.getTitle(), is("album-title-2"));
+               assertThat(nestedAlbum.getDescription(), is("album-description-2"));
+               assertThat(nestedAlbum.getAlbums(), hasSize(0));
+       }
+
+       @Test
+       public void parsingASoneFailsWithInvalidParentAlbumId() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-parent-album-id.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithoutImages() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-images.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), not(nullValue()));
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutImageId() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-id.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutImageTime() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-time.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutImageKey() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-key.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutImageTitle() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-title.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutImageWidth() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-width.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithoutImageHeight() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-height.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithInvalidImageWidth() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-image-width.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneFailsWithInvalidImageHeight() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-image-height.xml");
+               assertThat(soneDownloader.parseSone(sone, inputStream), nullValue());
+       }
+
+       @Test
+       public void parsingASoneSucceedsWithImage() throws SoneException, MalformedURLException {
+               InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-image.xml");
+               final Sone sone = soneDownloader.parseSone(this.sone, inputStream);
+               assertThat(sone, not(nullValue()));
+               assertThat(sone.getRootAlbum().getAlbums(), hasSize(1));
+               assertThat(sone.getRootAlbum().getAlbums().get(0).getImages(), hasSize(1));
+               Image image = sone.getRootAlbum().getAlbums().get(0).getImages().get(0);
+               assertThat(image.getId(), is("image-id"));
+               assertThat(image.getCreationTime(), is(1407197508000L));
+               assertThat(image.getKey(), is("KSK@GPLv3.txt"));
+               assertThat(image.getTitle(), is("image-title"));
+               assertThat(image.getDescription(), is("image-description"));
+               assertThat(image.getWidth(), is(1920));
+               assertThat(image.getHeight(), is(1080));
+               assertThat(sone.getProfile().getAvatar(), is("image-id"));
+       }
+
+       @Test
+       public void stoppingTheSoneDownloaderUnregistersTheSone() {
+               soneDownloader.addSone(sone);
+               soneDownloader.stop();
+               verify(freenetInterface).unregisterUsk(sone);
+       }
+
        @Test
        public void fetchSoneWithUriDownloadsSoneWithUri() {
                SoneDownloader soneDownloader = mock(SoneDownloader.class);
@@ -40,4 +644,119 @@ public class SoneDownloaderTest {
                verify(soneDownloader).fetchSone(eq(sone));
        }
 
+       @Test
+       public void notBeingAbleToFetchAnUnknownSoneDoesNotUpdateCore() {
+               soneDownloader.fetchSone(sone);
+               verify(freenetInterface).fetchUri(requestUri);
+               verifyThatSoneStatusWasChangedToDownloadingAndBackTo(unknown);
+               verify(core, never()).updateSone(any(Sone.class));
+       }
+
+       private void verifyThatSoneStatusWasChangedToDownloadingAndBackTo(SoneStatus soneStatus) {
+               ArgumentCaptor<SoneStatus> 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() {
+               when(sone.getTime()).thenReturn(1000L);
+               soneDownloader.fetchSone(sone);
+               verify(freenetInterface).fetchUri(requestUri);
+               verifyThatSoneStatusWasChangedToDownloadingAndBackTo(idle);
+               verify(core, never()).updateSone(any(Sone.class));
+       }
+
+       @Test(expected = NullPointerException.class)
+       public void exceptionWhileFetchingAnUnknownSoneDoesNotUpdateCore() {
+               when(freenetInterface.fetchUri(requestUri)).thenThrow(NullPointerException.class);
+               try {
+                       soneDownloader.fetchSone(sone);
+               } finally {
+                       verify(freenetInterface).fetchUri(requestUri);
+                       verifyThatSoneStatusWasChangedToDownloadingAndBackTo(unknown);
+                       verify(core, never()).updateSone(any(Sone.class));
+               }
+       }
+
+       @Test(expected = NullPointerException.class)
+       public void exceptionWhileFetchingAKnownSoneDoesNotUpdateCore() {
+               when(sone.getTime()).thenReturn(1000L);
+               when(freenetInterface.fetchUri(requestUri)).thenThrow(NullPointerException.class);
+               try {
+                       soneDownloader.fetchSone(sone);
+               } finally {
+                       verify(freenetInterface).fetchUri(requestUri);
+                       verifyThatSoneStatusWasChangedToDownloadingAndBackTo(idle);
+                       verify(core, never()).updateSone(any(Sone.class));
+               }
+       }
+
+       @Test
+       public void successfulFetchingOfSoneWithUskRequestUriUpdatesTheCoreWithASone() throws IOException {
+               final Fetched fetchResult = createFetchResult(requestUri, getClass().getResourceAsStream("sone-parser-no-payload.xml"));
+               when(freenetInterface.fetchUri(requestUri)).thenReturn(fetchResult);
+               soneDownloader.fetchSone(sone);
+               verifyThatParsedSoneHasTheSameIdAsTheOriginalSone();
+       }
+
+       private void verifyThatParsedSoneHasTheSameIdAsTheOriginalSone() {
+               ArgumentCaptor<Sone> soneCaptor = forClass(Sone.class);
+               verify(core).updateSone(soneCaptor.capture());
+               assertThat(soneCaptor.getValue().getId(), is(sone.getId()));
+       }
+
+       @Test
+       public void successfulFetchingOfSoneWithSskRequestUriUpdatesTheCoreWithASone() throws IOException {
+               when(requestUri.getKeyType()).thenReturn("SSK");
+               final Fetched fetchResult = createFetchResult(requestUri, getClass().getResourceAsStream("sone-parser-no-payload.xml"));
+               when(freenetInterface.fetchUri(requestUri)).thenReturn(fetchResult);
+               soneDownloader.fetchSone(sone);
+               verifyThatParsedSoneHasTheSameIdAsTheOriginalSone();
+       }
+
+       @Test
+       public void successfulFetchingAnUnknownSoneWithSskRequestUriUpdatesTheCoreWithASone() throws IOException {
+               when(requestUri.getKeyType()).thenReturn("SSK");
+               final Fetched fetchResult = createFetchResult(requestUri, getClass().getResourceAsStream("sone-parser-with-zero-time.xml"));
+               when(freenetInterface.fetchUri(requestUri)).thenReturn(fetchResult);
+               soneDownloader.fetchSone(sone);
+               verifyThatParsedSoneHasTheSameIdAsTheOriginalSone();
+       }
+
+       @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.fetchSone(sone);
+               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(sone.getId()).thenThrow(NullPointerException.class);
+               when(freenetInterface.fetchUri(requestUri)).thenReturn(fetchResult);
+               soneDownloader.fetchSone(sone);
+               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(unknown);
+       }
+
+       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);
+       }
+
 }
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-missing-client-name.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-missing-client-name.xml
new file mode 100644 (file)
index 0000000..04aab22
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <client></client>
+       <time>1407197508000</time>
+       <profile></profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-missing-client-version.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-missing-client-version.xml
new file mode 100644 (file)
index 0000000..cfcb3e6
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <client>
+               <name>some-client</name>
+       </client>
+       <time>1407197508000</time>
+       <profile></profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-missing-protocol-version.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-missing-protocol-version.xml
new file mode 100644 (file)
index 0000000..9a60f4f
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <time>1407197508000</time>
+       <profile></profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-negative-protocol-version.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-negative-protocol-version.xml
new file mode 100644 (file)
index 0000000..2907965
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>-1</protocol-version>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-no-payload.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-no-payload.xml
new file mode 100644 (file)
index 0000000..62db3ab
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-no-profile.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-no-profile.xml
new file mode 100644 (file)
index 0000000..b178772
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-no-time.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-no-time.xml
new file mode 100644 (file)
index 0000000..0ce3565
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-not-xml.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-not-xml.xml
new file mode 100644 (file)
index 0000000..0ced647
--- /dev/null
@@ -0,0 +1 @@
+Not an XML file.
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-profile-duplicate-field-name.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-profile-duplicate-field-name.xml
new file mode 100644 (file)
index 0000000..600886f
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile>
+               <fields>
+                       <field>
+                               <field-name>field</field-name>
+                               <field-name>value</field-name>
+                       </field>
+                       <field>
+                               <field-name>field</field-name>
+                               <field-name>value</field-name>
+                       </field>
+               </fields>
+       </profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-profile-empty-field-name.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-profile-empty-field-name.xml
new file mode 100644 (file)
index 0000000..a4abec4
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile>
+               <fields>
+                       <field>
+                               <field-name> </field-name>
+                       </field>
+               </fields>
+       </profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-profile-missing-field-name.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-profile-missing-field-name.xml
new file mode 100644 (file)
index 0000000..87ccb9f
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile>
+               <fields>
+                       <field></field>
+               </fields>
+       </profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-time-not-numeric.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-time-not-numeric.xml
new file mode 100644 (file)
index 0000000..367ef55
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>not-a-number</time>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-too-large-protocol-version.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-too-large-protocol-version.xml
new file mode 100644 (file)
index 0000000..c43c607
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>99999</protocol-version>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-client-info.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-client-info.xml
new file mode 100644 (file)
index 0000000..0cf4377
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <client>
+               <name>some-client</name>
+               <version>some-version</version>
+       </client>
+       <time>1407197508000</time>
+       <profile></profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-image.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-image.xml
new file mode 100644 (file)
index 0000000..40b221f
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile>
+               <avatar>image-id</avatar>
+       </profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+                       <images>
+                               <image>
+                                       <id>image-id</id>
+                                       <creation-time>1407197508000</creation-time>
+                                       <key>KSK@GPLv3.txt</key>
+                                       <title>image-title</title>
+                                       <description>image-description</description>
+                                       <width>1920</width>
+                                       <height>1080</height>
+                               </image>
+                       </images>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-image-height.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-image-height.xml
new file mode 100644 (file)
index 0000000..5344499
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+                       <images>
+                               <image>
+                                       <id>image-id</id>
+                                       <creation-time>1407197508000</creation-time>
+                                       <key>KSK@GPLv3.txt</key>
+                                       <title>image-title</title>
+                                       <width>1920</width>
+                                       <height>-1080</height>
+                               </image>
+                       </images>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-image-width.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-image-width.xml
new file mode 100644 (file)
index 0000000..5a0ae77
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+                       <images>
+                               <image>
+                                       <id>image-id</id>
+                                       <creation-time>1407197508000</creation-time>
+                                       <key>KSK@GPLv3.txt</key>
+                                       <title>image-title</title>
+                                       <width>-1920</width>
+                                       <height>1080</height>
+                               </image>
+                       </images>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-parent-album-id.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-parent-album-id.xml
new file mode 100644 (file)
index 0000000..af2a7eb
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <parent>album-id-7</parent>
+                       <title>album-title</title>
+                       <description>album-description</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-post-reply-time.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-post-reply-time.xml
new file mode 100644 (file)
index 0000000..751407a
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <replies>
+               <reply>
+                       <id>reply-id</id>
+                       <post-id>post-id</post-id>
+                       <time>not-a-time</time>
+                       <text>reply-text</text>
+               </reply>
+       </replies>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-post-time.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-post-time.xml
new file mode 100644 (file)
index 0000000..ad4df33
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <posts>
+               <post>
+                       <id>post-id</id>
+                       <time>invalid-time</time>
+                       <text>text</text>
+               </post>
+       </posts>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-recipient.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-recipient.xml
new file mode 100644 (file)
index 0000000..e627651
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <posts>
+               <post>
+                       <id>post-id</id>
+                       <time>1407197508000</time>
+                       <text>text</text>
+                       <recipient>123456789012345678901234567890123456789012</recipient>
+               </post>
+       </posts>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-request-uri.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-invalid-request-uri.xml
new file mode 100644 (file)
index 0000000..5bcb0cc
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <request-uri>invalid-request-uri</request-uri>
+       <profile></profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-liked-post-ids.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-liked-post-ids.xml
new file mode 100644 (file)
index 0000000..16a5af0
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <post-likes>
+               <post-like>liked-post-id</post-like>
+       </post-likes>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-liked-post-reply-ids.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-liked-post-reply-ids.xml
new file mode 100644 (file)
index 0000000..592da4c
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <reply-likes>
+               <reply-like>liked-post-reply-id</reply-like>
+       </reply-likes>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-multiple-albums.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-multiple-albums.xml
new file mode 100644 (file)
index 0000000..f27edab
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-profile.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-profile.xml
new file mode 100644 (file)
index 0000000..a57a698
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile>
+               <first-name>first</first-name>
+               <middle-name>middle</middle-name>
+               <last-name>last</last-name>
+               <birth-day>18</birth-day>
+               <birth-month>12</birth-month>
+               <birth-year>1976</birth-year>
+       </profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-recipient.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-recipient.xml
new file mode 100644 (file)
index 0000000..14dabe1
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <posts>
+               <post>
+                       <id>post-id</id>
+                       <time>1407197508000</time>
+                       <text>text</text>
+                       <recipient>1234567890123456789012345678901234567890123</recipient>
+               </post>
+       </posts>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-request-uri.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-request-uri.xml
new file mode 100644 (file)
index 0000000..5271c34
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <request-uri>USK@w~RyTGmv12Lg9oO91q1Untupi7my9qczT1RheGkEkVE,E8ElVfUgukSCPHxIEJp-gHMiR80wpM7sID3Jo5O7w1s,AQACAAE/Sone/0</request-uri>
+       <profile></profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-valid-post-reply-time.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-valid-post-reply-time.xml
new file mode 100644 (file)
index 0000000..4d77cb2
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <replies>
+               <reply>
+                       <id>reply-id</id>
+                       <post-id>post-id</post-id>
+                       <time>1407197508000</time>
+                       <text>reply-text</text>
+               </reply>
+       </replies>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-valid-post-time.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-valid-post-time.xml
new file mode 100644 (file)
index 0000000..fdfb493
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <posts>
+               <post>
+                       <id>post-id</id>
+                       <time>1407197508000</time>
+                       <text>text</text>
+               </post>
+       </posts>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-zero-time.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-with-zero-time.xml
new file mode 100644 (file)
index 0000000..90a4834
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>0</time>
+       <profile></profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-album-id.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-album-id.xml
new file mode 100644 (file)
index 0000000..f925496
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-album-title.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-album-title.xml
new file mode 100644 (file)
index 0000000..bacddeb
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-albums.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-albums.xml
new file mode 100644 (file)
index 0000000..ecf5d63
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-fields.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-fields.xml
new file mode 100644 (file)
index 0000000..09e8fab
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile>
+               <fields></fields>
+       </profile>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-height.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-height.xml
new file mode 100644 (file)
index 0000000..62d49cd
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+                       <images>
+                               <image>
+                                       <id>image-id</id>
+                                       <creation-time>1407197508000</creation-time>
+                                       <key>KSK@GPLv3.txt</key>
+                                       <title>image-title</title>
+                                       <width>1920</width>
+                               </image>
+                       </images>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-id.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-id.xml
new file mode 100644 (file)
index 0000000..d40c071
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+                       <images>
+                               <image>
+                               </image>
+                       </images>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-key.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-key.xml
new file mode 100644 (file)
index 0000000..ec53bca
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+                       <images>
+                               <image>
+                                       <id>image-id</id>
+                                       <creation-time>1407197508000</creation-time>
+                               </image>
+                       </images>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-time.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-time.xml
new file mode 100644 (file)
index 0000000..271e341
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+                       <images>
+                               <image>
+                                       <id>image-id</id>
+                               </image>
+                       </images>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-title.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-title.xml
new file mode 100644 (file)
index 0000000..bc1ce10
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+                       <images>
+                               <image>
+                                       <id>image-id</id>
+                                       <creation-time>1407197508000</creation-time>
+                                       <key>KSK@GPLv3.txt</key>
+                               </image>
+                       </images>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-width.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-image-width.xml
new file mode 100644 (file)
index 0000000..8426101
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+                       <images>
+                               <image>
+                                       <id>image-id</id>
+                                       <creation-time>1407197508000</creation-time>
+                                       <key>KSK@GPLv3.txt</key>
+                                       <title>image-title</title>
+                               </image>
+                       </images>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-images.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-images.xml
new file mode 100644 (file)
index 0000000..2b201e8
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <albums>
+               <album>
+                       <id>album-id-1</id>
+                       <title>album-title</title>
+                       <description>album-description</description>
+                       <images>
+                       </images>
+               </album>
+               <album>
+                       <id>album-id-2</id>
+                       <parent>album-id-1</parent>
+                       <title>album-title-2</title>
+                       <description>album-description-2</description>
+               </album>
+       </albums>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-liked-post-ids.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-liked-post-ids.xml
new file mode 100644 (file)
index 0000000..a8b9a6c
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <post-likes>
+       </post-likes>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-liked-post-reply-ids.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-liked-post-reply-ids.xml
new file mode 100644 (file)
index 0000000..511e214
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <reply-likes>
+       </reply-likes>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-id.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-id.xml
new file mode 100644 (file)
index 0000000..637a51f
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <posts>
+               <post>
+               </post>
+       </posts>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-id.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-id.xml
new file mode 100644 (file)
index 0000000..c54fca0
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <replies>
+               <reply>
+               </reply>
+       </replies>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-post-id.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-post-id.xml
new file mode 100644 (file)
index 0000000..321d857
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <replies>
+               <reply>
+                       <id>reply-id</id>
+               </reply>
+       </replies>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-text.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-text.xml
new file mode 100644 (file)
index 0000000..0ec68aa
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <replies>
+               <reply>
+                       <id>reply-id</id>
+                       <post-id>post-id</post-id>
+                       <time>1407197508000</time>
+               </reply>
+       </replies>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-time.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-reply-time.xml
new file mode 100644 (file)
index 0000000..ae6ffcb
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <replies>
+               <reply>
+                       <id>reply-id</id>
+                       <post-id>post-id</post-id>
+               </reply>
+       </replies>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-text.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-text.xml
new file mode 100644 (file)
index 0000000..062e2f8
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <posts>
+               <post>
+                       <id>post-id</id>
+                       <time>1407197508000</time>
+               </post>
+       </posts>
+</sone>
diff --git a/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-time.xml b/src/test/resources/net/pterodactylus/sone/core/sone-parser-without-post-time.xml
new file mode 100644 (file)
index 0000000..83477e5
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sone>
+       <protocol-version>0</protocol-version>
+       <time>1407197508000</time>
+       <profile></profile>
+       <posts>
+               <post>
+                       <id>post-id</id>
+               </post>
+       </posts>
+</sone>