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.Matchers.any;
15 import static org.mockito.Matchers.anyLong;
16 import static org.mockito.Matchers.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.IdBuilder;
34 import net.pterodactylus.sone.data.Image;
35 import net.pterodactylus.sone.data.Post;
36 import net.pterodactylus.sone.data.PostReply;
37 import net.pterodactylus.sone.data.Profile;
38 import net.pterodactylus.sone.data.Sone;
39 import net.pterodactylus.sone.database.AlbumBuilder;
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 Core core = mock(Core.class);
69 private final SoneParser soneParser = new SoneParser(core);
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(core.soneBuilder()).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(core.postBuilder()).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(core.postReplyBuilder()).thenReturn(postReplyBuilder);
245 public void setupAlbum() {
246 final Album album = SoneParserTest.this.album;
247 when(album.getAlbumImage()).thenReturn(mock(Image.class));
248 doAnswer(new Answer<Void>() {
250 public Void answer(InvocationOnMock invocation) {
251 nestedAlbums.put(album, (Album) invocation.getArguments()[0]);
254 }).when(album).addAlbum(any(Album.class));
255 doAnswer(new Answer<Void>() {
257 public Void answer(InvocationOnMock invocation) {
258 albumImages.put(album, (Image) invocation.getArguments()[0]);
261 }).when(album).addImage(any(Image.class));
262 when(album.getAlbums()).thenAnswer(new Answer<List<Album>>() {
264 public List<Album> answer(InvocationOnMock invocation) {
265 return nestedAlbums.get(album);
268 when(album.getImages()).thenAnswer(new Answer<List<Image>>() {
270 public List<Image> answer(InvocationOnMock invocation) {
271 return albumImages.get(album);
274 final Modifier albumModifier = new Modifier() {
275 private String title = album.getTitle();
276 private String description = album.getDescription();
277 private String imageId = album.getAlbumImage().getId();
280 public Modifier setTitle(String title) {
286 public Modifier setDescription(String description) {
287 this.description = description;
292 public Modifier setAlbumImage(String imageId) {
293 this.imageId = imageId;
298 public Album update() throws IllegalStateException {
299 when(album.getTitle()).thenReturn(title);
300 when(album.getDescription()).thenReturn(description);
301 Image image = mock(Image.class);
302 when(image.getId()).thenReturn(imageId);
303 when(album.getAlbumImage()).thenReturn(image);
307 when(album.modify()).thenReturn(albumModifier);
311 public void setupAlbumBuilder() {
312 when(albumBuilder.withId(anyString())).thenAnswer(new Answer<AlbumBuilder>() {
314 public AlbumBuilder answer(InvocationOnMock invocation) {
315 when(album.getId()).thenReturn((String) invocation.getArguments()[0]);
319 when(albumBuilder.randomId()).thenAnswer(new Answer<AlbumBuilder>() {
321 public AlbumBuilder answer(InvocationOnMock invocation) {
322 when(album.getId()).thenReturn(randomUUID().toString());
326 when(albumBuilder.by(any(Sone.class))).thenAnswer(new Answer<AlbumBuilder>() {
328 public AlbumBuilder answer(InvocationOnMock invocation) {
329 when(album.getSone()).thenReturn((Sone) invocation.getArguments()[0]);
333 when(albumBuilder.build()).thenAnswer(new Answer<Album>() {
335 public Album answer(InvocationOnMock invocation) {
336 Album album = SoneParserTest.this.album;
337 albums.put(album.getId(), album);
338 SoneParserTest.this.album = mock(Album.class);
343 when(core.albumBuilder()).thenReturn(albumBuilder);
347 public void setupAlbums() {
348 when(core.getAlbum(anyString())).thenAnswer(new Answer<Optional<Album>>() {
350 public Optional<Album> answer(InvocationOnMock invocation)
352 return Optional.fromNullable(albums.get(invocation.getArguments()[0]));
358 public void setupImage() {
359 final Image image = SoneParserTest.this.image;
360 Image.Modifier modifier = new Image.Modifier() {
361 private Sone sone = image.getSone();
362 private long creationTime = image.getCreationTime();
363 private String key = image.getKey();
364 private String title = image.getTitle();
365 private String description = image.getDescription();
366 private int width = image.getWidth();
367 private int height = image.getHeight();
370 public Image.Modifier setSone(Sone sone) {
376 public Image.Modifier setCreationTime(long creationTime) {
377 this.creationTime = creationTime;
382 public Image.Modifier setKey(String key) {
388 public Image.Modifier setTitle(String title) {
394 public Image.Modifier setDescription(String description) {
395 this.description = description;
400 public Image.Modifier setWidth(int width) {
406 public Image.Modifier setHeight(int height) {
407 this.height = height;
412 public Image update() throws IllegalStateException {
413 when(image.getSone()).thenReturn(sone);
414 when(image.getCreationTime()).thenReturn(creationTime);
415 when(image.getKey()).thenReturn(key);
416 when(image.getTitle()).thenReturn(title);
417 when(image.getDescription()).thenReturn(description);
418 when(image.getWidth()).thenReturn(width);
419 when(image.getHeight()).thenReturn(height);
423 when(image.getSone()).thenReturn(sone);
424 when(image.modify()).thenReturn(modifier);
428 public void setupImageBuilder() {
429 when(imageBuilder.randomId()).thenAnswer(new Answer<ImageBuilder>() {
431 public ImageBuilder answer(InvocationOnMock invocation) {
432 when(image.getId()).thenReturn(randomUUID().toString());
436 when(imageBuilder.withId(anyString())).thenAnswer(new Answer<ImageBuilder>() {
438 public ImageBuilder answer(InvocationOnMock invocation) {
439 when(image.getId()).thenReturn(new IdBuilder().buildId("identity", (String) invocation.getArguments()[0]));
440 when(image.getInternalId()).thenReturn((String) invocation.getArguments()[0]);
444 when(imageBuilder.build()).thenAnswer(new Answer<Image>() {
446 public Image answer(InvocationOnMock invocation) {
447 Image image = SoneParserTest.this.image;
448 images.put(image.getId(), image);
449 SoneParserTest.this.image = mock(Image.class);
454 when(core.imageBuilder()).thenReturn(imageBuilder);
458 public void setupImages() {
459 when(core.getImage(anyString())).thenAnswer(new Answer<Image>() {
461 public Image answer(InvocationOnMock invocation)
463 return images.get(invocation.getArguments()[0]);
468 public void parsingASoneFailsWhenDocumentIsNotXml() throws SoneException {
469 InputStream inputStream = getClass().getResourceAsStream("sone-parser-not-xml.xml");
470 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
474 public void parsingASoneFailsWhenDocumentHasNegativeProtocolVersion() throws SoneException {
475 InputStream inputStream = getClass().getResourceAsStream("sone-parser-negative-protocol-version.xml");
476 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
480 public void parsingASoneFailsWhenProtocolVersionIsTooLarge() throws SoneException {
481 InputStream inputStream = getClass().getResourceAsStream("sone-parser-too-large-protocol-version.xml");
482 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
486 public void parsingASoneFailsWhenThereIsNoTime() throws SoneException {
487 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-time.xml");
488 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
492 public void parsingASoneFailsWhenTimeIsNotNumeric() throws SoneException {
493 InputStream inputStream = getClass().getResourceAsStream("sone-parser-time-not-numeric.xml");
494 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
498 public void parsingASoneFailsWhenProfileIsMissing() throws SoneException {
499 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-profile.xml");
500 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
504 public void parsingASoneFailsWhenProfileFieldIsMissingAFieldName() throws SoneException {
505 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-missing-field-name.xml");
506 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
510 public void parsingASoneFailsWhenProfileFieldNameIsEmpty() throws SoneException {
511 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-empty-field-name.xml");
512 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
516 public void parsingASoneFailsWhenProfileFieldNameIsNotUnique() throws SoneException {
517 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-duplicate-field-name.xml");
518 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
522 public void parsingASoneSucceedsWithoutPayload() throws SoneException {
523 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-payload.xml");
524 assertThat(soneParser.parseSone(sone, inputStream).getTime(), is(
529 public void parsingALocalSoneSucceedsWithoutPayload() throws SoneException {
530 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-payload.xml");
531 Sone localSone = mock(Sone.class);
532 setupSone(localSone, OwnIdentity.class);
533 when(localSone.isLocal()).thenReturn(true);
534 Sone parsedSone = soneParser.parseSone(localSone, inputStream);
535 assertThat(parsedSone.getTime(), is(1407197508000L));
536 assertThat(parsedSone.isLocal(), is(true));
540 public void parsingASoneSucceedsWithoutProtocolVersion() throws SoneException {
541 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-protocol-version.xml");
542 assertThat(soneParser.parseSone(sone, inputStream), not(
547 public void parsingASoneFailsWithMissingClientName() throws SoneException {
548 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-client-name.xml");
549 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
553 public void parsingASoneFailsWithMissingClientVersion() throws SoneException {
554 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-client-version.xml");
555 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
559 public void parsingASoneSucceedsWithClientInfo() throws SoneException {
560 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-client-info.xml");
561 assertThat(soneParser.parseSone(sone, inputStream).getClient(), is(new Client("some-client", "some-version")));
565 public void parsingASoneSucceedsWithProfile() throws SoneException,
566 MalformedURLException {
567 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-profile.xml");
568 final Profile profile = soneParser.parseSone(sone, inputStream).getProfile();
569 assertThat(profile.getFirstName(), is("first"));
570 assertThat(profile.getMiddleName(), is("middle"));
571 assertThat(profile.getLastName(), is("last"));
572 assertThat(profile.getBirthDay(), is(18));
573 assertThat(profile.getBirthMonth(), is(12));
574 assertThat(profile.getBirthYear(), is(1976));
578 public void parsingASoneSucceedsWithoutProfileFields() throws SoneException, MalformedURLException {
579 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-fields.xml");
580 assertThat(soneParser.parseSone(sone, inputStream), notNullValue());
584 public void parsingASoneFailsWithoutPostId() throws SoneException, MalformedURLException {
585 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-id.xml");
586 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
590 public void parsingASoneFailsWithoutPostTime() throws SoneException, MalformedURLException {
591 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-time.xml");
592 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
596 public void parsingASoneFailsWithoutPostText() throws SoneException, MalformedURLException {
597 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-text.xml");
598 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
602 public void parsingASoneFailsWithInvalidPostTime() throws SoneException, MalformedURLException {
603 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-post-time.xml");
604 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
608 public void parsingASoneSucceedsWithValidPostTime() throws SoneException, MalformedURLException {
609 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-valid-post-time.xml");
610 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
611 assertThat(posts, is(createdPosts));
612 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
613 assertThat(posts.get(0).getId(), is("post-id"));
614 assertThat(posts.get(0).getTime(), is(1407197508000L));
615 assertThat(posts.get(0).getRecipientId(), is(Optional.<String>absent()));
616 assertThat(posts.get(0).getText(), is("text"));
620 public void parsingASoneSucceedsWithRecipient() throws SoneException, MalformedURLException {
621 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-recipient.xml");
622 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
623 assertThat(posts, is(createdPosts));
624 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
625 assertThat(posts.get(0).getId(), is("post-id"));
626 assertThat(posts.get(0).getTime(), is(1407197508000L));
627 assertThat(posts.get(0).getRecipientId(), is(of(
628 "1234567890123456789012345678901234567890123")));
629 assertThat(posts.get(0).getText(), is("text"));
633 public void parsingASoneSucceedsWithInvalidRecipient() throws SoneException, MalformedURLException {
634 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-recipient.xml");
635 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
636 assertThat(posts, is(createdPosts));
637 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
638 assertThat(posts.get(0).getId(), is("post-id"));
639 assertThat(posts.get(0).getTime(), is(1407197508000L));
640 assertThat(posts.get(0).getRecipientId(), is(Optional.<String>absent()));
641 assertThat(posts.get(0).getText(), is("text"));
645 public void parsingASoneFailsWithoutPostReplyId() throws SoneException, MalformedURLException {
646 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-id.xml");
647 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
651 public void parsingASoneFailsWithoutPostReplyPostId() throws SoneException, MalformedURLException {
652 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-post-id.xml");
653 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
657 public void parsingASoneFailsWithoutPostReplyTime() throws SoneException, MalformedURLException {
658 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-time.xml");
659 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
663 public void parsingASoneFailsWithoutPostReplyText() throws SoneException, MalformedURLException {
664 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-text.xml");
665 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
669 public void parsingASoneFailsWithInvalidPostReplyTime() throws SoneException, MalformedURLException {
670 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-post-reply-time.xml");
671 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
675 public void parsingASoneSucceedsWithValidPostReplyTime() throws SoneException, MalformedURLException {
676 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-valid-post-reply-time.xml");
677 final Set<PostReply> postReplies = soneParser.parseSone(sone, inputStream).getReplies();
678 assertThat(postReplies, is(createdPostReplies));
679 PostReply postReply = createdPostReplies.iterator().next();
680 assertThat(postReply.getId(), is("reply-id"));
681 assertThat(postReply.getPostId(), is("post-id"));
682 assertThat(postReply.getPost().get().getId(), is("post-id"));
683 assertThat(postReply.getSone().getId(), is("identity"));
684 assertThat(postReply.getTime(), is(1407197508000L));
685 assertThat(postReply.getText(), is("reply-text"));
689 public void parsingASoneSucceedsWithoutLikedPostIds() throws SoneException, MalformedURLException {
690 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-liked-post-ids.xml");
691 assertThat(soneParser.parseSone(sone, inputStream), not(
696 public void parsingASoneSucceedsWithLikedPostIds() throws SoneException, MalformedURLException {
697 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-liked-post-ids.xml");
698 assertThat(soneParser.parseSone(sone, inputStream).getLikedPostIds(), is(
699 (Set<String>) ImmutableSet.of("liked-post-id")));
703 public void parsingASoneSucceedsWithoutLikedPostReplyIds() throws SoneException, MalformedURLException {
704 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-liked-post-reply-ids.xml");
705 assertThat(soneParser.parseSone(sone, inputStream), not(
710 public void parsingASoneSucceedsWithLikedPostReplyIds() throws SoneException, MalformedURLException {
711 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-liked-post-reply-ids.xml");
712 assertThat(soneParser.parseSone(sone, inputStream).getLikedReplyIds(), is(
713 (Set<String>) ImmutableSet.of("liked-post-reply-id")));
717 public void parsingASoneSucceedsWithoutAlbums() throws SoneException, MalformedURLException {
718 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-albums.xml");
719 assertThat(soneParser.parseSone(sone, inputStream), not(
724 public void parsingASoneFailsWithoutAlbumId() throws SoneException, MalformedURLException {
725 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-album-id.xml");
726 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
730 public void parsingASoneFailsWithoutAlbumTitle() throws SoneException, MalformedURLException {
731 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-album-title.xml");
732 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
736 public void parsingASoneSucceedsWithNestedAlbums() throws SoneException, MalformedURLException {
737 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-multiple-albums.xml");
738 final Sone parsedSone = soneParser.parseSone(sone, inputStream);
739 assertThat(parsedSone, not(nullValue()));
740 assertThat(parsedSone.getRootAlbum().getAlbums(), hasSize(1));
741 Album album = parsedSone.getRootAlbum().getAlbums().get(0);
742 assertThat(album.getId(), is("album-id-1"));
743 assertThat(album.getTitle(), is("album-title"));
744 assertThat(album.getDescription(), is("album-description"));
745 assertThat(album.getAlbums(), hasSize(1));
746 Album nestedAlbum = album.getAlbums().get(0);
747 assertThat(nestedAlbum.getId(), is("album-id-2"));
748 assertThat(nestedAlbum.getTitle(), is("album-title-2"));
749 assertThat(nestedAlbum.getDescription(), is("album-description-2"));
750 assertThat(nestedAlbum.getAlbums(), hasSize(0));
754 public void parsingASoneFailsWithInvalidParentAlbumId() throws SoneException, MalformedURLException {
755 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-parent-album-id.xml");
756 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
760 public void parsingASoneSucceedsWithoutImages() throws SoneException, MalformedURLException {
761 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-images.xml");
762 assertThat(soneParser.parseSone(sone, inputStream), not(
767 public void parsingASoneFailsWithoutImageId() throws SoneException, MalformedURLException {
768 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-id.xml");
769 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
773 public void parsingASoneFailsWithoutImageTime() throws SoneException, MalformedURLException {
774 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-time.xml");
775 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
779 public void parsingASoneFailsWithoutImageKey() throws SoneException, MalformedURLException {
780 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-key.xml");
781 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
785 public void parsingASoneFailsWithoutImageTitle() throws SoneException, MalformedURLException {
786 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-title.xml");
787 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
791 public void parsingASoneFailsWithoutImageWidth() throws SoneException, MalformedURLException {
792 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-width.xml");
793 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
797 public void parsingASoneFailsWithoutImageHeight() throws SoneException, MalformedURLException {
798 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-height.xml");
799 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
803 public void parsingASoneFailsWithInvalidImageWidth() throws SoneException, MalformedURLException {
804 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-image-width.xml");
805 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
809 public void parsingASoneFailsWithInvalidImageHeight() throws SoneException, MalformedURLException {
810 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-image-height.xml");
811 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
815 public void parsingASoneSucceedsWithImage() throws SoneException, MalformedURLException {
816 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-image.xml");
817 final Sone sone = soneParser.parseSone(this.sone, inputStream);
818 assertThat(sone, not(nullValue()));
819 assertThat(sone.getRootAlbum().getAlbums(), hasSize(1));
820 assertThat(sone.getRootAlbum().getAlbums().get(0).getImages(), hasSize(1));
821 Image image = sone.getRootAlbum().getAlbums().get(0).getImages().get(0);
822 assertThat(image.getId(), is(new IdBuilder().buildId("identity", "image-id")));
823 assertThat(image.getInternalId(), is("image-id"));
824 assertThat(image.getCreationTime(), is(1407197508000L));
825 assertThat(image.getKey(), is("KSK@GPLv3.txt"));
826 assertThat(image.getTitle(), is("image-title"));
827 assertThat(image.getDescription(), is("image-description"));
828 assertThat(image.getWidth(), is(1920));
829 assertThat(image.getHeight(), is(1080));
830 assertThat(sone.getProfile().getAvatar(), is("image-id"));