1 package net.pterodactylus.sone.core;
3 import static com.google.common.base.Optional.of;
4 import static freenet.keys.InsertableClientSSK.createRandom;
5 import static java.lang.System.currentTimeMillis;
6 import static java.util.UUID.randomUUID;
7 import static java.util.concurrent.TimeUnit.DAYS;
8 import static org.hamcrest.MatcherAssert.assertThat;
9 import static org.hamcrest.Matchers.hasSize;
10 import static org.hamcrest.Matchers.is;
11 import static org.hamcrest.Matchers.not;
12 import static org.hamcrest.Matchers.notNullValue;
13 import static org.hamcrest.Matchers.nullValue;
14 import static org.mockito.ArgumentMatchers.any;
15 import static org.mockito.ArgumentMatchers.anyLong;
16 import static org.mockito.ArgumentMatchers.anyString;
17 import static org.mockito.Mockito.doAnswer;
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.when;
21 import java.io.InputStream;
22 import java.net.MalformedURLException;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
30 import net.pterodactylus.sone.data.Album;
31 import net.pterodactylus.sone.data.Album.Modifier;
32 import net.pterodactylus.sone.data.Client;
33 import net.pterodactylus.sone.data.Image;
34 import net.pterodactylus.sone.data.Post;
35 import net.pterodactylus.sone.data.PostReply;
36 import net.pterodactylus.sone.data.Profile;
37 import net.pterodactylus.sone.data.Sone;
38 import net.pterodactylus.sone.database.AlbumBuilder;
39 import net.pterodactylus.sone.database.Database;
40 import net.pterodactylus.sone.database.ImageBuilder;
41 import net.pterodactylus.sone.database.PostBuilder;
42 import net.pterodactylus.sone.database.PostReplyBuilder;
43 import net.pterodactylus.sone.database.SoneBuilder;
44 import net.pterodactylus.sone.database.memory.MemorySoneBuilder;
45 import net.pterodactylus.sone.freenet.wot.Identity;
46 import net.pterodactylus.sone.freenet.wot.OwnIdentity;
48 import freenet.crypt.DummyRandomSource;
49 import freenet.keys.FreenetURI;
50 import freenet.keys.InsertableClientSSK;
52 import com.google.common.base.Optional;
53 import com.google.common.collect.ArrayListMultimap;
54 import com.google.common.collect.ImmutableSet;
55 import com.google.common.collect.ListMultimap;
56 import org.junit.Before;
57 import org.junit.Test;
58 import org.mockito.invocation.InvocationOnMock;
59 import org.mockito.stubbing.Answer;
62 * Unit test for {@link SoneParser}.
64 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
66 public class SoneParserTest {
68 private final Database database = mock(Database.class);
69 private final SoneParser soneParser = new SoneParser(database);
70 private final Sone sone = mock(Sone.class);
71 private FreenetURI requestUri = mock(FreenetURI.class);
72 private final PostBuilder postBuilder = mock(PostBuilder.class);
73 private final List<Post> createdPosts = new ArrayList<Post>();
74 private Post post = mock(Post.class);
75 private final PostReplyBuilder postReplyBuilder = mock(PostReplyBuilder.class);
76 private final Set<PostReply> createdPostReplies = new HashSet<PostReply>();
77 private PostReply postReply = mock(PostReply.class);
78 private final AlbumBuilder albumBuilder = mock(AlbumBuilder.class);
79 private final ListMultimap<Album, Album>
80 nestedAlbums = ArrayListMultimap.create();
81 private final ListMultimap<Album, Image> albumImages = ArrayListMultimap.create();
82 private Album album = mock(Album.class);
83 private final Map<String, Album> albums = new HashMap<String, Album>();
84 private final ImageBuilder imageBuilder = mock(ImageBuilder.class);
85 private Image image = mock(Image.class);
86 private final Map<String, Image> images = new HashMap<String, Image>();
89 public void setupSone() {
90 setupSone(this.sone, Identity.class);
93 private void setupSone(Sone sone, Class<? extends Identity> identityClass) {
94 Identity identity = mock(identityClass);
95 InsertableClientSSK clientSSK =
96 createRandom(new DummyRandomSource(), "WoT");
97 when(identity.getRequestUri()).thenReturn(clientSSK.getURI().toString());
98 when(identity.getId()).thenReturn("identity");
99 when(sone.getId()).thenReturn("identity");
100 when(sone.getIdentity()).thenReturn(identity);
101 requestUri = clientSSK.getURI().setKeyType("USK").setDocName("Sone");
102 when(sone.getRequestUri()).thenAnswer(new Answer<FreenetURI>() {
104 public FreenetURI answer(InvocationOnMock invocation)
110 .thenReturn(currentTimeMillis() - DAYS.toMillis(1));
114 public void setupSoneBuilder() {
115 when(database.newSoneBuilder()).thenAnswer(new Answer<SoneBuilder>() {
117 public SoneBuilder answer(InvocationOnMock invocation) {
118 return new MemorySoneBuilder(null);
124 public void setupPost() {
125 when(post.getRecipientId()).thenReturn(Optional.<String>absent());
129 public void setupPostBuilder() {
130 when(postBuilder.withId(anyString())).thenAnswer(new Answer<PostBuilder>() {
132 public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
133 when(post.getId()).thenReturn((String) invocation.getArguments()[0]);
137 when(postBuilder.from(anyString())).thenAnswer(new Answer<PostBuilder>() {
139 public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
140 final Sone sone = mock(Sone.class);
141 when(sone.getId()).thenReturn((String) invocation.getArguments()[0]);
142 when(post.getSone()).thenReturn(sone);
146 when(postBuilder.withTime(anyLong())).thenAnswer(new Answer<PostBuilder>() {
148 public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
149 when(post.getTime()).thenReturn((Long) invocation.getArguments()[0]);
153 when(postBuilder.withText(anyString())).thenAnswer(new Answer<PostBuilder>() {
155 public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
156 when(post.getText()).thenReturn((String) invocation.getArguments()[0]);
160 when(postBuilder.to(anyString())).thenAnswer(new Answer<PostBuilder>() {
162 public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
163 when(post.getRecipientId()).thenReturn(of((String) invocation.getArguments()[0]));
167 when(postBuilder.build()).thenAnswer(new Answer<Post>() {
169 public Post answer(InvocationOnMock invocation) throws Throwable {
170 Post post = SoneParserTest.this.post;
171 SoneParserTest.this.post = mock(Post.class);
173 createdPosts.add(post);
177 when(database.newPostBuilder()).thenReturn(postBuilder);
181 public void setupPostReplyBuilder() {
182 when(postReplyBuilder.withId(anyString())).thenAnswer(new Answer<PostReplyBuilder>() {
184 public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable {
185 when(postReply.getId()).thenReturn((String) invocation.getArguments()[0]);
186 return postReplyBuilder;
189 when(postReplyBuilder.from(anyString())).thenAnswer(
190 new Answer<PostReplyBuilder>() {
192 public PostReplyBuilder answer(
193 InvocationOnMock invocation) throws Throwable {
194 Sone sone = when(mock(Sone.class).getId()).thenReturn(
195 (String) invocation.getArguments()[0])
197 when(postReply.getSone()).thenReturn(sone);
198 return postReplyBuilder;
201 when(postReplyBuilder.to(anyString())).thenAnswer(
202 new Answer<PostReplyBuilder>() {
204 public PostReplyBuilder answer(
205 InvocationOnMock invocation) throws Throwable {
206 when(postReply.getPostId()).thenReturn(
207 (String) invocation.getArguments()[0]);
208 Post post = when(mock(Post.class).getId()).thenReturn(
209 (String) invocation.getArguments()[0])
211 when(postReply.getPost()).thenReturn(of(post));
212 return postReplyBuilder;
215 when(postReplyBuilder.withTime(anyLong())).thenAnswer(
216 new Answer<PostReplyBuilder>() {
218 public PostReplyBuilder answer(
219 InvocationOnMock invocation) throws Throwable {
220 when(postReply.getTime()).thenReturn(
221 (Long) invocation.getArguments()[0]);
222 return postReplyBuilder;
225 when(postReplyBuilder.withText(anyString())).thenAnswer(new Answer<PostReplyBuilder>() {
227 public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable {
228 when(postReply.getText()).thenReturn((String) invocation.getArguments()[0]);
229 return postReplyBuilder;
232 when(postReplyBuilder.build()).thenAnswer(new Answer<PostReply>() {
234 public PostReply answer(InvocationOnMock invocation) throws Throwable {
235 PostReply postReply = SoneParserTest.this.postReply;
236 createdPostReplies.add(postReply);
237 SoneParserTest.this.postReply = mock(PostReply.class);
241 when(database.newPostReplyBuilder()).thenReturn(postReplyBuilder);
245 public void setupAlbum() {
246 final Album album = SoneParserTest.this.album;
247 doAnswer(new Answer<Void>() {
249 public Void answer(InvocationOnMock invocation) {
250 nestedAlbums.put(album, (Album) invocation.getArguments()[0]);
253 }).when(album).addAlbum(any(Album.class));
254 doAnswer(new Answer<Void>() {
256 public Void answer(InvocationOnMock invocation) {
257 albumImages.put(album, (Image) invocation.getArguments()[0]);
260 }).when(album).addImage(any(Image.class));
261 when(album.getAlbums()).thenAnswer(new Answer<List<Album>>() {
263 public List<Album> answer(InvocationOnMock invocation) {
264 return nestedAlbums.get(album);
267 when(album.getImages()).thenAnswer(new Answer<List<Image>>() {
269 public List<Image> answer(InvocationOnMock invocation) {
270 return albumImages.get(album);
273 final Modifier albumModifier = new Modifier() {
274 private String title = album.getTitle();
275 private String description = album.getDescription();
278 public Modifier setTitle(String title) {
284 public Modifier setDescription(String description) {
285 this.description = description;
290 public Album update() throws IllegalStateException {
291 when(album.getTitle()).thenReturn(title);
292 when(album.getDescription()).thenReturn(description);
296 when(album.modify()).thenReturn(albumModifier);
300 public void setupAlbumBuilder() {
301 when(albumBuilder.withId(anyString())).thenAnswer(new Answer<AlbumBuilder>() {
303 public AlbumBuilder answer(InvocationOnMock invocation) {
304 when(album.getId()).thenReturn((String) invocation.getArguments()[0]);
308 when(albumBuilder.randomId()).thenAnswer(new Answer<AlbumBuilder>() {
310 public AlbumBuilder answer(InvocationOnMock invocation) {
311 when(album.getId()).thenReturn(randomUUID().toString());
315 when(albumBuilder.by(any(Sone.class))).thenAnswer(new Answer<AlbumBuilder>() {
317 public AlbumBuilder answer(InvocationOnMock invocation) {
318 when(album.getSone()).thenReturn((Sone) invocation.getArguments()[0]);
322 when(albumBuilder.build()).thenAnswer(new Answer<Album>() {
324 public Album answer(InvocationOnMock invocation) {
325 Album album = SoneParserTest.this.album;
326 albums.put(album.getId(), album);
327 SoneParserTest.this.album = mock(Album.class);
332 when(database.newAlbumBuilder()).thenReturn(albumBuilder);
336 public void setupAlbums() {
337 when(database.getAlbum(anyString())).thenAnswer(new Answer<Album>() {
339 public Album answer(InvocationOnMock invocation)
341 return albums.get(invocation.getArguments()[0]);
347 public void setupImage() {
348 final Image image = SoneParserTest.this.image;
349 Image.Modifier modifier = new Image.Modifier() {
350 private Sone sone = image.getSone();
351 private long creationTime = image.getCreationTime();
352 private String key = image.getKey();
353 private String title = image.getTitle();
354 private String description = image.getDescription();
355 private int width = image.getWidth();
356 private int height = image.getHeight();
359 public Image.Modifier setSone(Sone sone) {
365 public Image.Modifier setCreationTime(long creationTime) {
366 this.creationTime = creationTime;
371 public Image.Modifier setKey(String key) {
377 public Image.Modifier setTitle(String title) {
383 public Image.Modifier setDescription(String description) {
384 this.description = description;
389 public Image.Modifier setWidth(int width) {
395 public Image.Modifier setHeight(int height) {
396 this.height = height;
401 public Image update() throws IllegalStateException {
402 when(image.getSone()).thenReturn(sone);
403 when(image.getCreationTime()).thenReturn(creationTime);
404 when(image.getKey()).thenReturn(key);
405 when(image.getTitle()).thenReturn(title);
406 when(image.getDescription()).thenReturn(description);
407 when(image.getWidth()).thenReturn(width);
408 when(image.getHeight()).thenReturn(height);
412 when(image.getSone()).thenReturn(sone);
413 when(image.modify()).thenReturn(modifier);
417 public void setupImageBuilder() {
418 when(imageBuilder.randomId()).thenAnswer(new Answer<ImageBuilder>() {
420 public ImageBuilder answer(InvocationOnMock invocation) {
421 when(image.getId()).thenReturn(randomUUID().toString());
425 when(imageBuilder.withId(anyString())).thenAnswer(new Answer<ImageBuilder>() {
427 public ImageBuilder answer(InvocationOnMock invocation) {
428 when(image.getId()).thenReturn(
429 (String) invocation.getArguments()[0]);
433 when(imageBuilder.build()).thenAnswer(new Answer<Image>() {
435 public Image answer(InvocationOnMock invocation) {
436 Image image = SoneParserTest.this.image;
437 images.put(image.getId(), image);
438 SoneParserTest.this.image = mock(Image.class);
443 when(database.newImageBuilder()).thenReturn(imageBuilder);
447 public void setupImages() {
448 when(database.getImage(anyString())).thenAnswer(new Answer<Image>() {
450 public Image answer(InvocationOnMock invocation)
452 return images.get(invocation.getArguments()[0]);
457 public void parsingASoneFailsWhenDocumentIsNotXml() throws SoneException {
458 InputStream inputStream = getClass().getResourceAsStream("sone-parser-not-xml.xml");
459 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
463 public void parsingASoneFailsWhenDocumentHasNegativeProtocolVersion() throws SoneException {
464 InputStream inputStream = getClass().getResourceAsStream("sone-parser-negative-protocol-version.xml");
465 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
469 public void parsingASoneFailsWhenProtocolVersionIsTooLarge() throws SoneException {
470 InputStream inputStream = getClass().getResourceAsStream("sone-parser-too-large-protocol-version.xml");
471 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
475 public void parsingASoneFailsWhenThereIsNoTime() throws SoneException {
476 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-time.xml");
477 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
481 public void parsingASoneFailsWhenTimeIsNotNumeric() throws SoneException {
482 InputStream inputStream = getClass().getResourceAsStream("sone-parser-time-not-numeric.xml");
483 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
487 public void parsingASoneFailsWhenProfileIsMissing() throws SoneException {
488 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-profile.xml");
489 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
493 public void parsingASoneFailsWhenProfileFieldIsMissingAFieldName() throws SoneException {
494 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-missing-field-name.xml");
495 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
499 public void parsingASoneFailsWhenProfileFieldNameIsEmpty() throws SoneException {
500 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-empty-field-name.xml");
501 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
505 public void parsingASoneFailsWhenProfileFieldNameIsNotUnique() throws SoneException {
506 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-duplicate-field-name.xml");
507 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
511 public void parsingASoneSucceedsWithoutPayload() throws SoneException {
512 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-payload.xml");
513 assertThat(soneParser.parseSone(sone, inputStream).getTime(), is(
518 public void parsingALocalSoneSucceedsWithoutPayload() throws SoneException {
519 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-payload.xml");
520 Sone localSone = mock(Sone.class);
521 setupSone(localSone, OwnIdentity.class);
522 when(localSone.isLocal()).thenReturn(true);
523 Sone parsedSone = soneParser.parseSone(localSone, inputStream);
524 assertThat(parsedSone.getTime(), is(1407197508000L));
525 assertThat(parsedSone.isLocal(), is(true));
529 public void parsingASoneSucceedsWithoutProtocolVersion() throws SoneException {
530 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-protocol-version.xml");
531 assertThat(soneParser.parseSone(sone, inputStream), not(
536 public void parsingASoneFailsWithMissingClientName() throws SoneException {
537 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-client-name.xml");
538 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
542 public void parsingASoneFailsWithMissingClientVersion() throws SoneException {
543 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-client-version.xml");
544 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
548 public void parsingASoneSucceedsWithClientInfo() throws SoneException {
549 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-client-info.xml");
550 assertThat(soneParser.parseSone(sone, inputStream).getClient(), is(new Client("some-client", "some-version")));
554 public void parsingASoneSucceedsWithProfile() throws SoneException,
555 MalformedURLException {
556 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-profile.xml");
557 final Profile profile = soneParser.parseSone(sone, inputStream).getProfile();
558 assertThat(profile.getFirstName(), is("first"));
559 assertThat(profile.getMiddleName(), is("middle"));
560 assertThat(profile.getLastName(), is("last"));
561 assertThat(profile.getBirthDay(), is(18));
562 assertThat(profile.getBirthMonth(), is(12));
563 assertThat(profile.getBirthYear(), is(1976));
567 public void parsingASoneSucceedsWithoutProfileFields() throws SoneException, MalformedURLException {
568 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-fields.xml");
569 assertThat(soneParser.parseSone(sone, inputStream), notNullValue());
573 public void parsingASoneFailsWithoutPostId() throws SoneException, MalformedURLException {
574 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-id.xml");
575 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
579 public void parsingASoneFailsWithoutPostTime() throws SoneException, MalformedURLException {
580 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-time.xml");
581 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
585 public void parsingASoneFailsWithoutPostText() throws SoneException, MalformedURLException {
586 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-text.xml");
587 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
591 public void parsingASoneFailsWithInvalidPostTime() throws SoneException, MalformedURLException {
592 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-post-time.xml");
593 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
597 public void parsingASoneSucceedsWithValidPostTime() throws SoneException, MalformedURLException {
598 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-valid-post-time.xml");
599 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
600 assertThat(posts, is(createdPosts));
601 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
602 assertThat(posts.get(0).getId(), is("post-id"));
603 assertThat(posts.get(0).getTime(), is(1407197508000L));
604 assertThat(posts.get(0).getRecipientId(), is(Optional.<String>absent()));
605 assertThat(posts.get(0).getText(), is("text"));
609 public void parsingASoneSucceedsWithRecipient() throws SoneException, MalformedURLException {
610 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-recipient.xml");
611 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
612 assertThat(posts, is(createdPosts));
613 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
614 assertThat(posts.get(0).getId(), is("post-id"));
615 assertThat(posts.get(0).getTime(), is(1407197508000L));
616 assertThat(posts.get(0).getRecipientId(), is(of(
617 "1234567890123456789012345678901234567890123")));
618 assertThat(posts.get(0).getText(), is("text"));
622 public void parsingASoneSucceedsWithInvalidRecipient() throws SoneException, MalformedURLException {
623 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-recipient.xml");
624 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
625 assertThat(posts, is(createdPosts));
626 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
627 assertThat(posts.get(0).getId(), is("post-id"));
628 assertThat(posts.get(0).getTime(), is(1407197508000L));
629 assertThat(posts.get(0).getRecipientId(), is(Optional.<String>absent()));
630 assertThat(posts.get(0).getText(), is("text"));
634 public void parsingASoneFailsWithoutPostReplyId() throws SoneException, MalformedURLException {
635 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-id.xml");
636 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
640 public void parsingASoneFailsWithoutPostReplyPostId() throws SoneException, MalformedURLException {
641 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-post-id.xml");
642 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
646 public void parsingASoneFailsWithoutPostReplyTime() throws SoneException, MalformedURLException {
647 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-time.xml");
648 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
652 public void parsingASoneFailsWithoutPostReplyText() throws SoneException, MalformedURLException {
653 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-text.xml");
654 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
658 public void parsingASoneFailsWithInvalidPostReplyTime() throws SoneException, MalformedURLException {
659 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-post-reply-time.xml");
660 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
664 public void parsingASoneSucceedsWithValidPostReplyTime() throws SoneException, MalformedURLException {
665 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-valid-post-reply-time.xml");
666 final Set<PostReply> postReplies = soneParser.parseSone(sone, inputStream).getReplies();
667 assertThat(postReplies, is(createdPostReplies));
668 PostReply postReply = createdPostReplies.iterator().next();
669 assertThat(postReply.getId(), is("reply-id"));
670 assertThat(postReply.getPostId(), is("post-id"));
671 assertThat(postReply.getPost().get().getId(), is("post-id"));
672 assertThat(postReply.getSone().getId(), is("identity"));
673 assertThat(postReply.getTime(), is(1407197508000L));
674 assertThat(postReply.getText(), is("reply-text"));
678 public void parsingASoneSucceedsWithoutLikedPostIds() throws SoneException, MalformedURLException {
679 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-liked-post-ids.xml");
680 assertThat(soneParser.parseSone(sone, inputStream), not(
685 public void parsingASoneSucceedsWithLikedPostIds() throws SoneException, MalformedURLException {
686 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-liked-post-ids.xml");
687 assertThat(soneParser.parseSone(sone, inputStream).getLikedPostIds(), is(
688 (Set<String>) ImmutableSet.of("liked-post-id")));
692 public void parsingASoneSucceedsWithoutLikedPostReplyIds() throws SoneException, MalformedURLException {
693 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-liked-post-reply-ids.xml");
694 assertThat(soneParser.parseSone(sone, inputStream), not(
699 public void parsingASoneSucceedsWithLikedPostReplyIds() throws SoneException, MalformedURLException {
700 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-liked-post-reply-ids.xml");
701 assertThat(soneParser.parseSone(sone, inputStream).getLikedReplyIds(), is(
702 (Set<String>) ImmutableSet.of("liked-post-reply-id")));
706 public void parsingASoneSucceedsWithoutAlbums() throws SoneException, MalformedURLException {
707 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-albums.xml");
708 assertThat(soneParser.parseSone(sone, inputStream), not(
713 public void parsingASoneFailsWithoutAlbumId() throws SoneException, MalformedURLException {
714 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-album-id.xml");
715 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
719 public void parsingASoneFailsWithoutAlbumTitle() throws SoneException, MalformedURLException {
720 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-album-title.xml");
721 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
725 public void parsingASoneSucceedsWithNestedAlbums() throws SoneException, MalformedURLException {
726 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-multiple-albums.xml");
727 final Sone parsedSone = soneParser.parseSone(sone, inputStream);
728 assertThat(parsedSone, not(nullValue()));
729 assertThat(parsedSone.getRootAlbum().getAlbums(), hasSize(1));
730 Album album = parsedSone.getRootAlbum().getAlbums().get(0);
731 assertThat(album.getId(), is("album-id-1"));
732 assertThat(album.getTitle(), is("album-title"));
733 assertThat(album.getDescription(), is("album-description"));
734 assertThat(album.getAlbums(), hasSize(1));
735 Album nestedAlbum = album.getAlbums().get(0);
736 assertThat(nestedAlbum.getId(), is("album-id-2"));
737 assertThat(nestedAlbum.getTitle(), is("album-title-2"));
738 assertThat(nestedAlbum.getDescription(), is("album-description-2"));
739 assertThat(nestedAlbum.getAlbums(), hasSize(0));
743 public void parsingASoneFailsWithInvalidParentAlbumId() throws SoneException, MalformedURLException {
744 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-parent-album-id.xml");
745 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
749 public void parsingASoneSucceedsWithoutImages() throws SoneException, MalformedURLException {
750 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-images.xml");
751 assertThat(soneParser.parseSone(sone, inputStream), not(
756 public void parsingASoneFailsWithoutImageId() throws SoneException, MalformedURLException {
757 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-id.xml");
758 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
762 public void parsingASoneFailsWithoutImageTime() throws SoneException, MalformedURLException {
763 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-time.xml");
764 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
768 public void parsingASoneFailsWithoutImageKey() throws SoneException, MalformedURLException {
769 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-key.xml");
770 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
774 public void parsingASoneFailsWithoutImageTitle() throws SoneException, MalformedURLException {
775 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-title.xml");
776 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
780 public void parsingASoneFailsWithoutImageWidth() throws SoneException, MalformedURLException {
781 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-width.xml");
782 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
786 public void parsingASoneFailsWithoutImageHeight() throws SoneException, MalformedURLException {
787 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-height.xml");
788 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
792 public void parsingASoneFailsWithInvalidImageWidth() throws SoneException, MalformedURLException {
793 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-image-width.xml");
794 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
798 public void parsingASoneFailsWithInvalidImageHeight() throws SoneException, MalformedURLException {
799 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-image-height.xml");
800 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
804 public void parsingASoneSucceedsWithImage() throws SoneException, MalformedURLException {
805 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-image.xml");
806 final Sone sone = soneParser.parseSone(this.sone, inputStream);
807 assertThat(sone, not(nullValue()));
808 assertThat(sone.getRootAlbum().getAlbums(), hasSize(1));
809 assertThat(sone.getRootAlbum().getAlbums().get(0).getImages(), hasSize(1));
810 Image image = sone.getRootAlbum().getAlbums().get(0).getImages().get(0);
811 assertThat(image.getId(), is("image-id"));
812 assertThat(image.getCreationTime(), is(1407197508000L));
813 assertThat(image.getKey(), is("KSK@GPLv3.txt"));
814 assertThat(image.getTitle(), is("image-title"));
815 assertThat(image.getDescription(), is("image-description"));
816 assertThat(image.getWidth(), is(1920));
817 assertThat(image.getHeight(), is(1080));
818 assertThat(sone.getProfile().getAvatar(), is("image-id"));