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.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.ImageBuilder;
40 import net.pterodactylus.sone.database.PostBuilder;
41 import net.pterodactylus.sone.database.PostReplyBuilder;
42 import net.pterodactylus.sone.database.SoneBuilder;
43 import net.pterodactylus.sone.database.memory.MemorySoneBuilder;
44 import net.pterodactylus.sone.freenet.wot.Identity;
45 import net.pterodactylus.sone.freenet.wot.OwnIdentity;
47 import freenet.crypt.DummyRandomSource;
48 import freenet.keys.FreenetURI;
49 import freenet.keys.InsertableClientSSK;
51 import com.google.common.base.Optional;
52 import com.google.common.collect.ArrayListMultimap;
53 import com.google.common.collect.ImmutableSet;
54 import com.google.common.collect.ListMultimap;
55 import org.junit.Before;
56 import org.junit.Test;
57 import org.mockito.invocation.InvocationOnMock;
58 import org.mockito.stubbing.Answer;
61 * Unit test for {@link SoneParser}.
63 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
65 public class SoneParserTest {
67 private final Core core = mock(Core.class);
68 private final SoneParser soneParser = new SoneParser(core);
69 private final Sone sone = mock(Sone.class);
70 private FreenetURI requestUri = mock(FreenetURI.class);
71 private final PostBuilder postBuilder = mock(PostBuilder.class);
72 private final List<Post> createdPosts = new ArrayList<Post>();
73 private Post post = mock(Post.class);
74 private final PostReplyBuilder postReplyBuilder = mock(PostReplyBuilder.class);
75 private final Set<PostReply> createdPostReplies = new HashSet<PostReply>();
76 private PostReply postReply = mock(PostReply.class);
77 private final AlbumBuilder albumBuilder = mock(AlbumBuilder.class);
78 private final ListMultimap<Album, Album>
79 nestedAlbums = ArrayListMultimap.create();
80 private final ListMultimap<Album, Image> albumImages = ArrayListMultimap.create();
81 private Album album = mock(Album.class);
82 private final Map<String, Album> albums = new HashMap<String, Album>();
83 private final ImageBuilder imageBuilder = mock(ImageBuilder.class);
84 private Image image = mock(Image.class);
85 private final Map<String, Image> images = new HashMap<String, Image>();
88 public void setupSone() {
89 setupSone(this.sone, Identity.class);
92 private void setupSone(Sone sone, Class<? extends Identity> identityClass) {
93 Identity identity = mock(identityClass);
94 InsertableClientSSK clientSSK =
95 createRandom(new DummyRandomSource(), "WoT");
96 when(identity.getRequestUri()).thenReturn(clientSSK.getURI().toString());
97 when(identity.getId()).thenReturn("identity");
98 when(sone.getId()).thenReturn("identity");
99 when(sone.getIdentity()).thenReturn(identity);
100 requestUri = clientSSK.getURI().setKeyType("USK").setDocName("Sone");
101 when(sone.getRequestUri()).thenAnswer(new Answer<FreenetURI>() {
103 public FreenetURI answer(InvocationOnMock invocation)
109 .thenReturn(currentTimeMillis() - DAYS.toMillis(1));
113 public void setupSoneBuilder() {
114 when(core.soneBuilder()).thenAnswer(new Answer<SoneBuilder>() {
116 public SoneBuilder answer(InvocationOnMock invocation) {
117 return new MemorySoneBuilder(null);
123 public void setupPost() {
124 when(post.getRecipientId()).thenReturn(Optional.<String>absent());
128 public void setupPostBuilder() {
129 when(postBuilder.withId(anyString())).thenAnswer(new Answer<PostBuilder>() {
131 public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
132 when(post.getId()).thenReturn((String) invocation.getArguments()[0]);
136 when(postBuilder.from(anyString())).thenAnswer(new Answer<PostBuilder>() {
138 public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
139 final Sone sone = mock(Sone.class);
140 when(sone.getId()).thenReturn((String) invocation.getArguments()[0]);
141 when(post.getSone()).thenReturn(sone);
145 when(postBuilder.withTime(anyLong())).thenAnswer(new Answer<PostBuilder>() {
147 public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
148 when(post.getTime()).thenReturn((Long) invocation.getArguments()[0]);
152 when(postBuilder.withText(anyString())).thenAnswer(new Answer<PostBuilder>() {
154 public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
155 when(post.getText()).thenReturn((String) invocation.getArguments()[0]);
159 when(postBuilder.to(anyString())).thenAnswer(new Answer<PostBuilder>() {
161 public PostBuilder answer(InvocationOnMock invocation) throws Throwable {
162 when(post.getRecipientId()).thenReturn(of((String) invocation.getArguments()[0]));
166 when(postBuilder.build()).thenAnswer(new Answer<Post>() {
168 public Post answer(InvocationOnMock invocation) throws Throwable {
169 Post post = SoneParserTest.this.post;
170 SoneParserTest.this.post = mock(Post.class);
172 createdPosts.add(post);
176 when(core.postBuilder()).thenReturn(postBuilder);
180 public void setupPostReplyBuilder() {
181 when(postReplyBuilder.withId(anyString())).thenAnswer(new Answer<PostReplyBuilder>() {
183 public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable {
184 when(postReply.getId()).thenReturn((String) invocation.getArguments()[0]);
185 return postReplyBuilder;
188 when(postReplyBuilder.from(anyString())).thenAnswer(
189 new Answer<PostReplyBuilder>() {
191 public PostReplyBuilder answer(
192 InvocationOnMock invocation) throws Throwable {
193 Sone sone = when(mock(Sone.class).getId()).thenReturn(
194 (String) invocation.getArguments()[0])
196 when(postReply.getSone()).thenReturn(sone);
197 return postReplyBuilder;
200 when(postReplyBuilder.to(anyString())).thenAnswer(
201 new Answer<PostReplyBuilder>() {
203 public PostReplyBuilder answer(
204 InvocationOnMock invocation) throws Throwable {
205 when(postReply.getPostId()).thenReturn(
206 (String) invocation.getArguments()[0]);
207 Post post = when(mock(Post.class).getId()).thenReturn(
208 (String) invocation.getArguments()[0])
210 when(postReply.getPost()).thenReturn(of(post));
211 return postReplyBuilder;
214 when(postReplyBuilder.withTime(anyLong())).thenAnswer(
215 new Answer<PostReplyBuilder>() {
217 public PostReplyBuilder answer(
218 InvocationOnMock invocation) throws Throwable {
219 when(postReply.getTime()).thenReturn(
220 (Long) invocation.getArguments()[0]);
221 return postReplyBuilder;
224 when(postReplyBuilder.withText(anyString())).thenAnswer(new Answer<PostReplyBuilder>() {
226 public PostReplyBuilder answer(InvocationOnMock invocation) throws Throwable {
227 when(postReply.getText()).thenReturn((String) invocation.getArguments()[0]);
228 return postReplyBuilder;
231 when(postReplyBuilder.build()).thenAnswer(new Answer<PostReply>() {
233 public PostReply answer(InvocationOnMock invocation) throws Throwable {
234 PostReply postReply = SoneParserTest.this.postReply;
235 createdPostReplies.add(postReply);
236 SoneParserTest.this.postReply = mock(PostReply.class);
240 when(core.postReplyBuilder()).thenReturn(postReplyBuilder);
244 public void setupAlbum() {
245 final Album album = SoneParserTest.this.album;
246 when(album.getAlbumImage()).thenReturn(mock(Image.class));
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();
276 private String imageId = album.getAlbumImage().getId();
279 public Modifier setTitle(String title) {
285 public Modifier setDescription(String description) {
286 this.description = description;
291 public Modifier setAlbumImage(String imageId) {
292 this.imageId = imageId;
297 public Album update() throws IllegalStateException {
298 when(album.getTitle()).thenReturn(title);
299 when(album.getDescription()).thenReturn(description);
300 Image image = mock(Image.class);
301 when(image.getId()).thenReturn(imageId);
302 when(album.getAlbumImage()).thenReturn(image);
306 when(album.modify()).thenReturn(albumModifier);
310 public void setupAlbumBuilder() {
311 when(albumBuilder.withId(anyString())).thenAnswer(new Answer<AlbumBuilder>() {
313 public AlbumBuilder answer(InvocationOnMock invocation) {
314 when(album.getId()).thenReturn((String) invocation.getArguments()[0]);
318 when(albumBuilder.randomId()).thenAnswer(new Answer<AlbumBuilder>() {
320 public AlbumBuilder answer(InvocationOnMock invocation) {
321 when(album.getId()).thenReturn(randomUUID().toString());
325 when(albumBuilder.by(any(Sone.class))).thenAnswer(new Answer<AlbumBuilder>() {
327 public AlbumBuilder answer(InvocationOnMock invocation) {
328 when(album.getSone()).thenReturn((Sone) invocation.getArguments()[0]);
332 when(albumBuilder.build()).thenAnswer(new Answer<Album>() {
334 public Album answer(InvocationOnMock invocation) {
335 Album album = SoneParserTest.this.album;
336 albums.put(album.getId(), album);
337 SoneParserTest.this.album = mock(Album.class);
342 when(core.albumBuilder()).thenReturn(albumBuilder);
346 public void setupAlbums() {
347 when(core.getAlbum(anyString())).thenAnswer(new Answer<Album>() {
349 public Album answer(InvocationOnMock invocation)
351 return albums.get(invocation.getArguments()[0]);
357 public void setupImage() {
358 final Image image = SoneParserTest.this.image;
359 Image.Modifier modifier = new Image.Modifier() {
360 private Sone sone = image.getSone();
361 private long creationTime = image.getCreationTime();
362 private String key = image.getKey();
363 private String title = image.getTitle();
364 private String description = image.getDescription();
365 private int width = image.getWidth();
366 private int height = image.getHeight();
369 public Image.Modifier setSone(Sone sone) {
375 public Image.Modifier setCreationTime(long creationTime) {
376 this.creationTime = creationTime;
381 public Image.Modifier setKey(String key) {
387 public Image.Modifier setTitle(String title) {
393 public Image.Modifier setDescription(String description) {
394 this.description = description;
399 public Image.Modifier setWidth(int width) {
405 public Image.Modifier setHeight(int height) {
406 this.height = height;
411 public Image update() throws IllegalStateException {
412 when(image.getSone()).thenReturn(sone);
413 when(image.getCreationTime()).thenReturn(creationTime);
414 when(image.getKey()).thenReturn(key);
415 when(image.getTitle()).thenReturn(title);
416 when(image.getDescription()).thenReturn(description);
417 when(image.getWidth()).thenReturn(width);
418 when(image.getHeight()).thenReturn(height);
422 when(image.getSone()).thenReturn(sone);
423 when(image.modify()).thenReturn(modifier);
427 public void setupImageBuilder() {
428 when(imageBuilder.randomId()).thenAnswer(new Answer<ImageBuilder>() {
430 public ImageBuilder answer(InvocationOnMock invocation) {
431 when(image.getId()).thenReturn(randomUUID().toString());
435 when(imageBuilder.withId(anyString())).thenAnswer(new Answer<ImageBuilder>() {
437 public ImageBuilder answer(InvocationOnMock invocation) {
438 when(image.getId()).thenReturn(
439 (String) invocation.getArguments()[0]);
443 when(imageBuilder.build()).thenAnswer(new Answer<Image>() {
445 public Image answer(InvocationOnMock invocation) {
446 Image image = SoneParserTest.this.image;
447 images.put(image.getId(), image);
448 SoneParserTest.this.image = mock(Image.class);
453 when(core.imageBuilder()).thenReturn(imageBuilder);
457 public void setupImages() {
458 when(core.getImage(anyString())).thenAnswer(new Answer<Image>() {
460 public Image answer(InvocationOnMock invocation)
462 return images.get(invocation.getArguments()[0]);
467 public void parsingASoneFailsWhenDocumentIsNotXml() throws SoneException {
468 InputStream inputStream = getClass().getResourceAsStream("sone-parser-not-xml.xml");
469 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
473 public void parsingASoneFailsWhenDocumentHasNegativeProtocolVersion() throws SoneException {
474 InputStream inputStream = getClass().getResourceAsStream("sone-parser-negative-protocol-version.xml");
475 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
479 public void parsingASoneFailsWhenProtocolVersionIsTooLarge() throws SoneException {
480 InputStream inputStream = getClass().getResourceAsStream("sone-parser-too-large-protocol-version.xml");
481 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
485 public void parsingASoneFailsWhenThereIsNoTime() throws SoneException {
486 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-time.xml");
487 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
491 public void parsingASoneFailsWhenTimeIsNotNumeric() throws SoneException {
492 InputStream inputStream = getClass().getResourceAsStream("sone-parser-time-not-numeric.xml");
493 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
497 public void parsingASoneFailsWhenProfileIsMissing() throws SoneException {
498 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-profile.xml");
499 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
503 public void parsingASoneFailsWhenProfileFieldIsMissingAFieldName() throws SoneException {
504 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-missing-field-name.xml");
505 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
509 public void parsingASoneFailsWhenProfileFieldNameIsEmpty() throws SoneException {
510 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-empty-field-name.xml");
511 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
515 public void parsingASoneFailsWhenProfileFieldNameIsNotUnique() throws SoneException {
516 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-duplicate-field-name.xml");
517 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
521 public void parsingASoneSucceedsWithoutPayload() throws SoneException {
522 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-payload.xml");
523 assertThat(soneParser.parseSone(sone, inputStream).getTime(), is(
528 public void parsingALocalSoneSucceedsWithoutPayload() throws SoneException {
529 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-payload.xml");
530 Sone localSone = mock(Sone.class);
531 setupSone(localSone, OwnIdentity.class);
532 when(localSone.isLocal()).thenReturn(true);
533 Sone parsedSone = soneParser.parseSone(localSone, inputStream);
534 assertThat(parsedSone.getTime(), is(1407197508000L));
535 assertThat(parsedSone.isLocal(), is(true));
539 public void parsingASoneSucceedsWithoutProtocolVersion() throws SoneException {
540 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-protocol-version.xml");
541 assertThat(soneParser.parseSone(sone, inputStream), not(
546 public void parsingASoneFailsWithMissingClientName() throws SoneException {
547 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-client-name.xml");
548 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
552 public void parsingASoneFailsWithMissingClientVersion() throws SoneException {
553 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-client-version.xml");
554 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
558 public void parsingASoneSucceedsWithClientInfo() throws SoneException {
559 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-client-info.xml");
560 assertThat(soneParser.parseSone(sone, inputStream).getClient(), is(new Client("some-client", "some-version")));
564 public void parsingASoneSucceedsWithProfile() throws SoneException,
565 MalformedURLException {
566 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-profile.xml");
567 final Profile profile = soneParser.parseSone(sone, inputStream).getProfile();
568 assertThat(profile.getFirstName(), is("first"));
569 assertThat(profile.getMiddleName(), is("middle"));
570 assertThat(profile.getLastName(), is("last"));
571 assertThat(profile.getBirthDay(), is(18));
572 assertThat(profile.getBirthMonth(), is(12));
573 assertThat(profile.getBirthYear(), is(1976));
577 public void parsingASoneSucceedsWithoutProfileFields() throws SoneException, MalformedURLException {
578 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-fields.xml");
579 assertThat(soneParser.parseSone(sone, inputStream), notNullValue());
583 public void parsingASoneFailsWithoutPostId() throws SoneException, MalformedURLException {
584 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-id.xml");
585 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
589 public void parsingASoneFailsWithoutPostTime() throws SoneException, MalformedURLException {
590 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-time.xml");
591 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
595 public void parsingASoneFailsWithoutPostText() throws SoneException, MalformedURLException {
596 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-text.xml");
597 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
601 public void parsingASoneFailsWithInvalidPostTime() throws SoneException, MalformedURLException {
602 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-post-time.xml");
603 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
607 public void parsingASoneSucceedsWithValidPostTime() throws SoneException, MalformedURLException {
608 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-valid-post-time.xml");
609 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
610 assertThat(posts, is(createdPosts));
611 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
612 assertThat(posts.get(0).getId(), is("post-id"));
613 assertThat(posts.get(0).getTime(), is(1407197508000L));
614 assertThat(posts.get(0).getRecipientId(), is(Optional.<String>absent()));
615 assertThat(posts.get(0).getText(), is("text"));
619 public void parsingASoneSucceedsWithRecipient() throws SoneException, MalformedURLException {
620 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-recipient.xml");
621 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
622 assertThat(posts, is(createdPosts));
623 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
624 assertThat(posts.get(0).getId(), is("post-id"));
625 assertThat(posts.get(0).getTime(), is(1407197508000L));
626 assertThat(posts.get(0).getRecipientId(), is(of(
627 "1234567890123456789012345678901234567890123")));
628 assertThat(posts.get(0).getText(), is("text"));
632 public void parsingASoneSucceedsWithInvalidRecipient() throws SoneException, MalformedURLException {
633 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-recipient.xml");
634 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
635 assertThat(posts, is(createdPosts));
636 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
637 assertThat(posts.get(0).getId(), is("post-id"));
638 assertThat(posts.get(0).getTime(), is(1407197508000L));
639 assertThat(posts.get(0).getRecipientId(), is(Optional.<String>absent()));
640 assertThat(posts.get(0).getText(), is("text"));
644 public void parsingASoneFailsWithoutPostReplyId() throws SoneException, MalformedURLException {
645 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-id.xml");
646 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
650 public void parsingASoneFailsWithoutPostReplyPostId() throws SoneException, MalformedURLException {
651 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-post-id.xml");
652 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
656 public void parsingASoneFailsWithoutPostReplyTime() throws SoneException, MalformedURLException {
657 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-time.xml");
658 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
662 public void parsingASoneFailsWithoutPostReplyText() throws SoneException, MalformedURLException {
663 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-text.xml");
664 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
668 public void parsingASoneFailsWithInvalidPostReplyTime() throws SoneException, MalformedURLException {
669 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-post-reply-time.xml");
670 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
674 public void parsingASoneSucceedsWithValidPostReplyTime() throws SoneException, MalformedURLException {
675 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-valid-post-reply-time.xml");
676 final Set<PostReply> postReplies = soneParser.parseSone(sone, inputStream).getReplies();
677 assertThat(postReplies, is(createdPostReplies));
678 PostReply postReply = createdPostReplies.iterator().next();
679 assertThat(postReply.getId(), is("reply-id"));
680 assertThat(postReply.getPostId(), is("post-id"));
681 assertThat(postReply.getPost().get().getId(), is("post-id"));
682 assertThat(postReply.getSone().getId(), is("identity"));
683 assertThat(postReply.getTime(), is(1407197508000L));
684 assertThat(postReply.getText(), is("reply-text"));
688 public void parsingASoneSucceedsWithoutLikedPostIds() throws SoneException, MalformedURLException {
689 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-liked-post-ids.xml");
690 assertThat(soneParser.parseSone(sone, inputStream), not(
695 public void parsingASoneSucceedsWithLikedPostIds() throws SoneException, MalformedURLException {
696 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-liked-post-ids.xml");
697 assertThat(soneParser.parseSone(sone, inputStream).getLikedPostIds(), is(
698 (Set<String>) ImmutableSet.of("liked-post-id")));
702 public void parsingASoneSucceedsWithoutLikedPostReplyIds() throws SoneException, MalformedURLException {
703 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-liked-post-reply-ids.xml");
704 assertThat(soneParser.parseSone(sone, inputStream), not(
709 public void parsingASoneSucceedsWithLikedPostReplyIds() throws SoneException, MalformedURLException {
710 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-liked-post-reply-ids.xml");
711 assertThat(soneParser.parseSone(sone, inputStream).getLikedReplyIds(), is(
712 (Set<String>) ImmutableSet.of("liked-post-reply-id")));
716 public void parsingASoneSucceedsWithoutAlbums() throws SoneException, MalformedURLException {
717 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-albums.xml");
718 assertThat(soneParser.parseSone(sone, inputStream), not(
723 public void parsingASoneFailsWithoutAlbumId() throws SoneException, MalformedURLException {
724 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-album-id.xml");
725 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
729 public void parsingASoneFailsWithoutAlbumTitle() throws SoneException, MalformedURLException {
730 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-album-title.xml");
731 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
735 public void parsingASoneSucceedsWithNestedAlbums() throws SoneException, MalformedURLException {
736 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-multiple-albums.xml");
737 final Sone parsedSone = soneParser.parseSone(sone, inputStream);
738 assertThat(parsedSone, not(nullValue()));
739 assertThat(parsedSone.getRootAlbum().getAlbums(), hasSize(1));
740 Album album = parsedSone.getRootAlbum().getAlbums().get(0);
741 assertThat(album.getId(), is("album-id-1"));
742 assertThat(album.getTitle(), is("album-title"));
743 assertThat(album.getDescription(), is("album-description"));
744 assertThat(album.getAlbums(), hasSize(1));
745 Album nestedAlbum = album.getAlbums().get(0);
746 assertThat(nestedAlbum.getId(), is("album-id-2"));
747 assertThat(nestedAlbum.getTitle(), is("album-title-2"));
748 assertThat(nestedAlbum.getDescription(), is("album-description-2"));
749 assertThat(nestedAlbum.getAlbums(), hasSize(0));
753 public void parsingASoneFailsWithInvalidParentAlbumId() throws SoneException, MalformedURLException {
754 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-parent-album-id.xml");
755 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
759 public void parsingASoneSucceedsWithoutImages() throws SoneException, MalformedURLException {
760 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-images.xml");
761 assertThat(soneParser.parseSone(sone, inputStream), not(
766 public void parsingASoneFailsWithoutImageId() throws SoneException, MalformedURLException {
767 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-id.xml");
768 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
772 public void parsingASoneFailsWithoutImageTime() throws SoneException, MalformedURLException {
773 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-time.xml");
774 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
778 public void parsingASoneFailsWithoutImageKey() throws SoneException, MalformedURLException {
779 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-key.xml");
780 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
784 public void parsingASoneFailsWithoutImageTitle() throws SoneException, MalformedURLException {
785 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-title.xml");
786 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
790 public void parsingASoneFailsWithoutImageWidth() throws SoneException, MalformedURLException {
791 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-width.xml");
792 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
796 public void parsingASoneFailsWithoutImageHeight() throws SoneException, MalformedURLException {
797 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-height.xml");
798 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
802 public void parsingASoneFailsWithInvalidImageWidth() throws SoneException, MalformedURLException {
803 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-image-width.xml");
804 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
808 public void parsingASoneFailsWithInvalidImageHeight() throws SoneException, MalformedURLException {
809 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-image-height.xml");
810 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
814 public void parsingASoneSucceedsWithImage() throws SoneException, MalformedURLException {
815 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-image.xml");
816 final Sone sone = soneParser.parseSone(this.sone, inputStream);
817 assertThat(sone, not(nullValue()));
818 assertThat(sone.getRootAlbum().getAlbums(), hasSize(1));
819 assertThat(sone.getRootAlbum().getAlbums().get(0).getImages(), hasSize(1));
820 Image image = sone.getRootAlbum().getAlbums().get(0).getImages().get(0);
821 assertThat(image.getId(), is("image-id"));
822 assertThat(image.getCreationTime(), is(1407197508000L));
823 assertThat(image.getKey(), is("KSK@GPLv3.txt"));
824 assertThat(image.getTitle(), is("image-title"));
825 assertThat(image.getDescription(), is("image-description"));
826 assertThat(image.getWidth(), is(1920));
827 assertThat(image.getHeight(), is(1080));
828 assertThat(sone.getProfile().getAvatar(), is("image-id"));