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 doAnswer(new Answer<Void>() {
248 public Void answer(InvocationOnMock invocation) {
249 nestedAlbums.put(album, (Album) invocation.getArguments()[0]);
252 }).when(album).addAlbum(any(Album.class));
253 doAnswer(new Answer<Void>() {
255 public Void answer(InvocationOnMock invocation) {
256 albumImages.put(album, (Image) invocation.getArguments()[0]);
259 }).when(album).addImage(any(Image.class));
260 when(album.getAlbums()).thenAnswer(new Answer<List<Album>>() {
262 public List<Album> answer(InvocationOnMock invocation) {
263 return nestedAlbums.get(album);
266 when(album.getImages()).thenAnswer(new Answer<List<Image>>() {
268 public List<Image> answer(InvocationOnMock invocation) {
269 return albumImages.get(album);
272 final Modifier albumModifier = new Modifier() {
273 private String title = album.getTitle();
274 private String description = album.getDescription();
277 public Modifier setTitle(String title) {
283 public Modifier setDescription(String description) {
284 this.description = description;
289 public Album update() throws IllegalStateException {
290 when(album.getTitle()).thenReturn(title);
291 when(album.getDescription()).thenReturn(description);
295 when(album.modify()).thenReturn(albumModifier);
299 public void setupAlbumBuilder() {
300 when(albumBuilder.withId(anyString())).thenAnswer(new Answer<AlbumBuilder>() {
302 public AlbumBuilder answer(InvocationOnMock invocation) {
303 when(album.getId()).thenReturn((String) invocation.getArguments()[0]);
307 when(albumBuilder.randomId()).thenAnswer(new Answer<AlbumBuilder>() {
309 public AlbumBuilder answer(InvocationOnMock invocation) {
310 when(album.getId()).thenReturn(randomUUID().toString());
314 when(albumBuilder.by(any(Sone.class))).thenAnswer(new Answer<AlbumBuilder>() {
316 public AlbumBuilder answer(InvocationOnMock invocation) {
317 when(album.getSone()).thenReturn((Sone) invocation.getArguments()[0]);
321 when(albumBuilder.build()).thenAnswer(new Answer<Album>() {
323 public Album answer(InvocationOnMock invocation) {
324 Album album = SoneParserTest.this.album;
325 albums.put(album.getId(), album);
326 SoneParserTest.this.album = mock(Album.class);
331 when(core.albumBuilder()).thenReturn(albumBuilder);
335 public void setupAlbums() {
336 when(core.getAlbum(anyString())).thenAnswer(new Answer<Album>() {
338 public Album answer(InvocationOnMock invocation)
340 return albums.get(invocation.getArguments()[0]);
346 public void setupImage() {
347 final Image image = SoneParserTest.this.image;
348 Image.Modifier modifier = new Image.Modifier() {
349 private Sone sone = image.getSone();
350 private long creationTime = image.getCreationTime();
351 private String key = image.getKey();
352 private String title = image.getTitle();
353 private String description = image.getDescription();
354 private int width = image.getWidth();
355 private int height = image.getHeight();
358 public Image.Modifier setSone(Sone sone) {
364 public Image.Modifier setCreationTime(long creationTime) {
365 this.creationTime = creationTime;
370 public Image.Modifier setKey(String key) {
376 public Image.Modifier setTitle(String title) {
382 public Image.Modifier setDescription(String description) {
383 this.description = description;
388 public Image.Modifier setWidth(int width) {
394 public Image.Modifier setHeight(int height) {
395 this.height = height;
400 public Image update() throws IllegalStateException {
401 when(image.getSone()).thenReturn(sone);
402 when(image.getCreationTime()).thenReturn(creationTime);
403 when(image.getKey()).thenReturn(key);
404 when(image.getTitle()).thenReturn(title);
405 when(image.getDescription()).thenReturn(description);
406 when(image.getWidth()).thenReturn(width);
407 when(image.getHeight()).thenReturn(height);
411 when(image.getSone()).thenReturn(sone);
412 when(image.modify()).thenReturn(modifier);
416 public void setupImageBuilder() {
417 when(imageBuilder.randomId()).thenAnswer(new Answer<ImageBuilder>() {
419 public ImageBuilder answer(InvocationOnMock invocation) {
420 when(image.getId()).thenReturn(randomUUID().toString());
424 when(imageBuilder.withId(anyString())).thenAnswer(new Answer<ImageBuilder>() {
426 public ImageBuilder answer(InvocationOnMock invocation) {
427 when(image.getId()).thenReturn(
428 (String) invocation.getArguments()[0]);
432 when(imageBuilder.build()).thenAnswer(new Answer<Image>() {
434 public Image answer(InvocationOnMock invocation) {
435 Image image = SoneParserTest.this.image;
436 images.put(image.getId(), image);
437 SoneParserTest.this.image = mock(Image.class);
442 when(core.imageBuilder()).thenReturn(imageBuilder);
446 public void setupImages() {
447 when(core.getImage(anyString())).thenAnswer(new Answer<Image>() {
449 public Image answer(InvocationOnMock invocation)
451 return images.get(invocation.getArguments()[0]);
456 public void parsingASoneFailsWhenDocumentIsNotXml() throws SoneException {
457 InputStream inputStream = getClass().getResourceAsStream("sone-parser-not-xml.xml");
458 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
462 public void parsingASoneFailsWhenDocumentHasNegativeProtocolVersion() throws SoneException {
463 InputStream inputStream = getClass().getResourceAsStream("sone-parser-negative-protocol-version.xml");
464 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
468 public void parsingASoneFailsWhenProtocolVersionIsTooLarge() throws SoneException {
469 InputStream inputStream = getClass().getResourceAsStream("sone-parser-too-large-protocol-version.xml");
470 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
474 public void parsingASoneFailsWhenThereIsNoTime() throws SoneException {
475 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-time.xml");
476 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
480 public void parsingASoneFailsWhenTimeIsNotNumeric() throws SoneException {
481 InputStream inputStream = getClass().getResourceAsStream("sone-parser-time-not-numeric.xml");
482 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
486 public void parsingASoneFailsWhenProfileIsMissing() throws SoneException {
487 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-profile.xml");
488 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
492 public void parsingASoneFailsWhenProfileFieldIsMissingAFieldName() throws SoneException {
493 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-missing-field-name.xml");
494 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
498 public void parsingASoneFailsWhenProfileFieldNameIsEmpty() throws SoneException {
499 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-empty-field-name.xml");
500 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
504 public void parsingASoneFailsWhenProfileFieldNameIsNotUnique() throws SoneException {
505 InputStream inputStream = getClass().getResourceAsStream("sone-parser-profile-duplicate-field-name.xml");
506 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
510 public void parsingASoneSucceedsWithoutPayload() throws SoneException {
511 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-payload.xml");
512 assertThat(soneParser.parseSone(sone, inputStream).getTime(), is(
517 public void parsingALocalSoneSucceedsWithoutPayload() throws SoneException {
518 InputStream inputStream = getClass().getResourceAsStream("sone-parser-no-payload.xml");
519 Sone localSone = mock(Sone.class);
520 setupSone(localSone, OwnIdentity.class);
521 when(localSone.isLocal()).thenReturn(true);
522 Sone parsedSone = soneParser.parseSone(localSone, inputStream);
523 assertThat(parsedSone.getTime(), is(1407197508000L));
524 assertThat(parsedSone.isLocal(), is(true));
528 public void parsingASoneSucceedsWithoutProtocolVersion() throws SoneException {
529 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-protocol-version.xml");
530 assertThat(soneParser.parseSone(sone, inputStream), not(
535 public void parsingASoneFailsWithMissingClientName() throws SoneException {
536 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-client-name.xml");
537 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
541 public void parsingASoneFailsWithMissingClientVersion() throws SoneException {
542 InputStream inputStream = getClass().getResourceAsStream("sone-parser-missing-client-version.xml");
543 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
547 public void parsingASoneSucceedsWithClientInfo() throws SoneException {
548 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-client-info.xml");
549 assertThat(soneParser.parseSone(sone, inputStream).getClient(), is(new Client("some-client", "some-version")));
553 public void parsingASoneSucceedsWithProfile() throws SoneException,
554 MalformedURLException {
555 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-profile.xml");
556 final Profile profile = soneParser.parseSone(sone, inputStream).getProfile();
557 assertThat(profile.getFirstName(), is("first"));
558 assertThat(profile.getMiddleName(), is("middle"));
559 assertThat(profile.getLastName(), is("last"));
560 assertThat(profile.getBirthDay(), is(18));
561 assertThat(profile.getBirthMonth(), is(12));
562 assertThat(profile.getBirthYear(), is(1976));
566 public void parsingASoneSucceedsWithoutProfileFields() throws SoneException, MalformedURLException {
567 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-fields.xml");
568 assertThat(soneParser.parseSone(sone, inputStream), notNullValue());
572 public void parsingASoneFailsWithoutPostId() throws SoneException, MalformedURLException {
573 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-id.xml");
574 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
578 public void parsingASoneFailsWithoutPostTime() throws SoneException, MalformedURLException {
579 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-time.xml");
580 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
584 public void parsingASoneFailsWithoutPostText() throws SoneException, MalformedURLException {
585 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-text.xml");
586 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
590 public void parsingASoneFailsWithInvalidPostTime() throws SoneException, MalformedURLException {
591 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-post-time.xml");
592 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
596 public void parsingASoneSucceedsWithValidPostTime() throws SoneException, MalformedURLException {
597 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-valid-post-time.xml");
598 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
599 assertThat(posts, is(createdPosts));
600 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
601 assertThat(posts.get(0).getId(), is("post-id"));
602 assertThat(posts.get(0).getTime(), is(1407197508000L));
603 assertThat(posts.get(0).getRecipientId(), is(Optional.<String>absent()));
604 assertThat(posts.get(0).getText(), is("text"));
608 public void parsingASoneSucceedsWithRecipient() throws SoneException, MalformedURLException {
609 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-recipient.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(of(
616 "1234567890123456789012345678901234567890123")));
617 assertThat(posts.get(0).getText(), is("text"));
621 public void parsingASoneSucceedsWithInvalidRecipient() throws SoneException, MalformedURLException {
622 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-recipient.xml");
623 final List<Post> posts = soneParser.parseSone(sone, inputStream).getPosts();
624 assertThat(posts, is(createdPosts));
625 assertThat(posts.get(0).getSone().getId(), is(sone.getId()));
626 assertThat(posts.get(0).getId(), is("post-id"));
627 assertThat(posts.get(0).getTime(), is(1407197508000L));
628 assertThat(posts.get(0).getRecipientId(), is(Optional.<String>absent()));
629 assertThat(posts.get(0).getText(), is("text"));
633 public void parsingASoneFailsWithoutPostReplyId() throws SoneException, MalformedURLException {
634 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-id.xml");
635 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
639 public void parsingASoneFailsWithoutPostReplyPostId() throws SoneException, MalformedURLException {
640 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-post-id.xml");
641 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
645 public void parsingASoneFailsWithoutPostReplyTime() throws SoneException, MalformedURLException {
646 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-time.xml");
647 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
651 public void parsingASoneFailsWithoutPostReplyText() throws SoneException, MalformedURLException {
652 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-post-reply-text.xml");
653 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
657 public void parsingASoneFailsWithInvalidPostReplyTime() throws SoneException, MalformedURLException {
658 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-post-reply-time.xml");
659 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
663 public void parsingASoneSucceedsWithValidPostReplyTime() throws SoneException, MalformedURLException {
664 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-valid-post-reply-time.xml");
665 final Set<PostReply> postReplies = soneParser.parseSone(sone, inputStream).getReplies();
666 assertThat(postReplies, is(createdPostReplies));
667 PostReply postReply = createdPostReplies.iterator().next();
668 assertThat(postReply.getId(), is("reply-id"));
669 assertThat(postReply.getPostId(), is("post-id"));
670 assertThat(postReply.getPost().get().getId(), is("post-id"));
671 assertThat(postReply.getSone().getId(), is("identity"));
672 assertThat(postReply.getTime(), is(1407197508000L));
673 assertThat(postReply.getText(), is("reply-text"));
677 public void parsingASoneSucceedsWithoutLikedPostIds() throws SoneException, MalformedURLException {
678 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-liked-post-ids.xml");
679 assertThat(soneParser.parseSone(sone, inputStream), not(
684 public void parsingASoneSucceedsWithLikedPostIds() throws SoneException, MalformedURLException {
685 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-liked-post-ids.xml");
686 assertThat(soneParser.parseSone(sone, inputStream).getLikedPostIds(), is(
687 (Set<String>) ImmutableSet.of("liked-post-id")));
691 public void parsingASoneSucceedsWithoutLikedPostReplyIds() throws SoneException, MalformedURLException {
692 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-liked-post-reply-ids.xml");
693 assertThat(soneParser.parseSone(sone, inputStream), not(
698 public void parsingASoneSucceedsWithLikedPostReplyIds() throws SoneException, MalformedURLException {
699 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-liked-post-reply-ids.xml");
700 assertThat(soneParser.parseSone(sone, inputStream).getLikedReplyIds(), is(
701 (Set<String>) ImmutableSet.of("liked-post-reply-id")));
705 public void parsingASoneSucceedsWithoutAlbums() throws SoneException, MalformedURLException {
706 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-albums.xml");
707 assertThat(soneParser.parseSone(sone, inputStream), not(
712 public void parsingASoneFailsWithoutAlbumId() throws SoneException, MalformedURLException {
713 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-album-id.xml");
714 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
718 public void parsingASoneFailsWithoutAlbumTitle() throws SoneException, MalformedURLException {
719 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-album-title.xml");
720 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
724 public void parsingASoneSucceedsWithNestedAlbums() throws SoneException, MalformedURLException {
725 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-multiple-albums.xml");
726 final Sone parsedSone = soneParser.parseSone(sone, inputStream);
727 assertThat(parsedSone, not(nullValue()));
728 assertThat(parsedSone.getRootAlbum().getAlbums(), hasSize(1));
729 Album album = parsedSone.getRootAlbum().getAlbums().get(0);
730 assertThat(album.getId(), is("album-id-1"));
731 assertThat(album.getTitle(), is("album-title"));
732 assertThat(album.getDescription(), is("album-description"));
733 assertThat(album.getAlbums(), hasSize(1));
734 Album nestedAlbum = album.getAlbums().get(0);
735 assertThat(nestedAlbum.getId(), is("album-id-2"));
736 assertThat(nestedAlbum.getTitle(), is("album-title-2"));
737 assertThat(nestedAlbum.getDescription(), is("album-description-2"));
738 assertThat(nestedAlbum.getAlbums(), hasSize(0));
742 public void parsingASoneFailsWithInvalidParentAlbumId() throws SoneException, MalformedURLException {
743 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-parent-album-id.xml");
744 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
748 public void parsingASoneSucceedsWithoutImages() throws SoneException, MalformedURLException {
749 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-images.xml");
750 assertThat(soneParser.parseSone(sone, inputStream), not(
755 public void parsingASoneFailsWithoutImageId() throws SoneException, MalformedURLException {
756 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-id.xml");
757 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
761 public void parsingASoneFailsWithoutImageTime() throws SoneException, MalformedURLException {
762 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-time.xml");
763 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
767 public void parsingASoneFailsWithoutImageKey() throws SoneException, MalformedURLException {
768 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-key.xml");
769 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
773 public void parsingASoneFailsWithoutImageTitle() throws SoneException, MalformedURLException {
774 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-title.xml");
775 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
779 public void parsingASoneFailsWithoutImageWidth() throws SoneException, MalformedURLException {
780 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-width.xml");
781 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
785 public void parsingASoneFailsWithoutImageHeight() throws SoneException, MalformedURLException {
786 InputStream inputStream = getClass().getResourceAsStream("sone-parser-without-image-height.xml");
787 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
791 public void parsingASoneFailsWithInvalidImageWidth() throws SoneException, MalformedURLException {
792 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-image-width.xml");
793 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
797 public void parsingASoneFailsWithInvalidImageHeight() throws SoneException, MalformedURLException {
798 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-invalid-image-height.xml");
799 assertThat(soneParser.parseSone(sone, inputStream), nullValue());
803 public void parsingASoneSucceedsWithImage() throws SoneException, MalformedURLException {
804 InputStream inputStream = getClass().getResourceAsStream("sone-parser-with-image.xml");
805 final Sone sone = soneParser.parseSone(this.sone, inputStream);
806 assertThat(sone, not(nullValue()));
807 assertThat(sone.getRootAlbum().getAlbums(), hasSize(1));
808 assertThat(sone.getRootAlbum().getAlbums().get(0).getImages(), hasSize(1));
809 Image image = sone.getRootAlbum().getAlbums().get(0).getImages().get(0);
810 assertThat(image.getId(), is("image-id"));
811 assertThat(image.getCreationTime(), is(1407197508000L));
812 assertThat(image.getKey(), is("KSK@GPLv3.txt"));
813 assertThat(image.getTitle(), is("image-title"));
814 assertThat(image.getDescription(), is("image-description"));
815 assertThat(image.getWidth(), is(1920));
816 assertThat(image.getHeight(), is(1080));
817 assertThat(sone.getProfile().getAvatar(), is("image-id"));