1 package net.pterodactylus.sone.core;
3 import static com.google.common.base.Optional.of;
4 import static net.pterodactylus.sone.test.Matchers.isAlbum;
5 import static net.pterodactylus.sone.test.Matchers.isImage;
6 import static net.pterodactylus.sone.test.Matchers.isPost;
7 import static net.pterodactylus.sone.test.Matchers.isPostReply;
8 import static org.hamcrest.MatcherAssert.assertThat;
9 import static org.hamcrest.Matchers.contains;
10 import static org.hamcrest.Matchers.containsInAnyOrder;
11 import static org.hamcrest.Matchers.emptyIterable;
12 import static org.hamcrest.Matchers.hasSize;
13 import static org.hamcrest.Matchers.is;
14 import static org.hamcrest.Matchers.notNullValue;
15 import static org.hamcrest.Matchers.nullValue;
16 import static org.mockito.ArgumentMatchers.anyString;
17 import static org.mockito.ArgumentMatchers.eq;
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.when;
21 import java.util.Collection;
22 import java.util.List;
26 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidAlbumFound;
27 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidImageFound;
28 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidParentAlbumFound;
29 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostFound;
30 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostReplyFound;
31 import net.pterodactylus.sone.data.Album;
32 import net.pterodactylus.sone.data.Post;
33 import net.pterodactylus.sone.data.PostReply;
34 import net.pterodactylus.sone.data.Profile;
35 import net.pterodactylus.sone.data.Profile.Field;
36 import net.pterodactylus.sone.data.Sone;
37 import net.pterodactylus.sone.database.AlbumBuilder;
38 import net.pterodactylus.sone.database.AlbumBuilderFactory;
39 import net.pterodactylus.sone.database.ImageBuilder;
40 import net.pterodactylus.sone.database.ImageBuilderFactory;
41 import net.pterodactylus.sone.database.PostBuilder;
42 import net.pterodactylus.sone.database.PostBuilderFactory;
43 import net.pterodactylus.sone.database.PostReplyBuilder;
44 import net.pterodactylus.sone.database.PostReplyBuilderFactory;
45 import net.pterodactylus.sone.test.TestAlbumBuilder;
46 import net.pterodactylus.sone.test.TestImageBuilder;
47 import net.pterodactylus.sone.test.TestPostBuilder;
48 import net.pterodactylus.sone.test.TestPostReplyBuilder;
49 import net.pterodactylus.sone.test.TestValue;
50 import net.pterodactylus.util.config.Configuration;
52 import com.google.common.base.Optional;
53 import org.hamcrest.Matchers;
54 import org.junit.Test;
55 import org.mockito.invocation.InvocationOnMock;
56 import org.mockito.stubbing.Answer;
59 * Unit test for {@link ConfigurationSoneParser}.
61 public class ConfigurationSoneParserTest {
63 private final Configuration configuration = mock(Configuration.class);
64 private final Sone sone = mock(Sone.class);
65 private final ConfigurationSoneParser configurationSoneParser;
67 public ConfigurationSoneParserTest() {
68 when(sone.getId()).thenReturn("1");
69 configurationSoneParser =
70 new ConfigurationSoneParser(configuration, sone);
74 public void emptyProfileIsLoadedCorrectly() {
76 Profile profile = configurationSoneParser.parseProfile();
77 assertThat(profile, notNullValue());
78 assertThat(profile.getFirstName(), nullValue());
79 assertThat(profile.getMiddleName(), nullValue());
80 assertThat(profile.getLastName(), nullValue());
81 assertThat(profile.getBirthDay(), nullValue());
82 assertThat(profile.getBirthMonth(), nullValue());
83 assertThat(profile.getBirthYear(), nullValue());
84 assertThat(profile.getFields(), emptyIterable());
87 private void setupEmptyProfile() {
88 when(configuration.getStringValue(anyString())).thenReturn(
89 TestValue.<String>from(null));
90 when(configuration.getIntValue(anyString())).thenReturn(
91 TestValue.<Integer>from(null));
95 public void filledProfileWithFieldsIsParsedCorrectly() {
97 Profile profile = configurationSoneParser.parseProfile();
98 assertThat(profile, notNullValue());
99 assertThat(profile.getFirstName(), is("First"));
100 assertThat(profile.getMiddleName(), is("M."));
101 assertThat(profile.getLastName(), is("Last"));
102 assertThat(profile.getBirthDay(), is(18));
103 assertThat(profile.getBirthMonth(), is(12));
104 assertThat(profile.getBirthYear(), is(1976));
105 final List<Field> fields = profile.getFields();
106 assertThat(fields, hasSize(2));
107 assertThat(fields.get(0).getName(), is("Field1"));
108 assertThat(fields.get(0).getValue(), is("Value1"));
109 assertThat(fields.get(1).getName(), is("Field2"));
110 assertThat(fields.get(1).getValue(), is("Value2"));
113 private void setupFilledProfile() {
114 setupString("Sone/1/Profile/FirstName", "First");
115 setupString("Sone/1/Profile/MiddleName", "M.");
116 setupString("Sone/1/Profile/LastName", "Last");
117 setupInteger("Sone/1/Profile/BirthDay", 18);
118 setupInteger("Sone/1/Profile/BirthMonth", 12);
119 setupInteger("Sone/1/Profile/BirthYear", 1976);
120 setupString("Sone/1/Profile/Fields/0/Name", "Field1");
121 setupString("Sone/1/Profile/Fields/0/Value", "Value1");
122 setupString("Sone/1/Profile/Fields/1/Name", "Field2");
123 setupString("Sone/1/Profile/Fields/1/Value", "Value2");
124 setupString("Sone/1/Profile/Fields/2/Name", null);
127 private void setupString(String nodeName, String value) {
128 when(configuration.getStringValue(eq(nodeName))).thenReturn(
129 TestValue.from(value));
132 private void setupInteger(String nodeName, Integer value) {
133 when(configuration.getIntValue(eq(nodeName))).thenReturn(
134 TestValue.from(value));
138 public void postsAreParsedCorrectly() {
139 setupCompletePosts();
140 PostBuilderFactory postBuilderFactory = createPostBuilderFactory();
141 Collection<Post> posts =
142 configurationSoneParser.parsePosts(postBuilderFactory);
144 Matchers.<Post>containsInAnyOrder(
145 isPost("P0", 1000L, "T0", Optional.<String>absent()),
146 isPost("P1", 1001L, "T1",
147 of("1234567890123456789012345678901234567890123"))));
150 private PostBuilderFactory createPostBuilderFactory() {
151 PostBuilderFactory postBuilderFactory =
152 mock(PostBuilderFactory.class);
153 when(postBuilderFactory.newPostBuilder()).thenAnswer(
154 new Answer<PostBuilder>() {
156 public PostBuilder answer(InvocationOnMock invocation)
158 return new TestPostBuilder();
161 return postBuilderFactory;
164 private void setupCompletePosts() {
165 setupPost("0", "P0", 1000L, "T0", null);
166 setupPost("1", "P1", 1001L, "T1",
167 "1234567890123456789012345678901234567890123");
168 setupPost("2", null, 0L, null, null);
171 private void setupPost(String postNumber, String postId, long time,
172 String text, String recipientId) {
173 setupString("Sone/1/Posts/" + postNumber + "/ID", postId);
174 setupLong("Sone/1/Posts/" + postNumber + "/Time", time);
175 setupString("Sone/1/Posts/" + postNumber + "/Text", text);
176 setupString("Sone/1/Posts/" + postNumber + "/Recipient", recipientId);
179 private void setupLong(String nodeName, Long value) {
180 when(configuration.getLongValue(eq(nodeName))).thenReturn(
181 TestValue.from(value));
184 @Test(expected = InvalidPostFound.class)
185 public void postWithoutTimeIsRecognized() {
186 setupPostWithoutTime();
187 configurationSoneParser.parsePosts(createPostBuilderFactory());
190 private void setupPostWithoutTime() {
191 setupPost("0", "P0", 0L, "T0", null);
194 @Test(expected = InvalidPostFound.class)
195 public void postWithoutTextIsRecognized() {
196 setupPostWithoutText();
197 configurationSoneParser.parsePosts(createPostBuilderFactory());
200 private void setupPostWithoutText() {
201 setupPost("0", "P0", 1000L, null, null);
205 public void postWithInvalidRecipientIdIsRecognized() {
206 setupPostWithInvalidRecipientId();
207 Collection<Post> posts = configurationSoneParser.parsePosts(
208 createPostBuilderFactory());
209 assertThat(posts, contains(
210 isPost("P0", 1000L, "T0", Optional.<String>absent())));
213 private void setupPostWithInvalidRecipientId() {
214 setupPost("0", "P0", 1000L, "T0", "123");
215 setupPost("1", null, 0L, null, null);
219 public void postRepliesAreParsedCorrectly() {
221 PostReplyBuilderFactory postReplyBuilderFactory =
222 new PostReplyBuilderFactory() {
224 public PostReplyBuilder newPostReplyBuilder() {
225 return new TestPostReplyBuilder();
228 Collection<PostReply> postReplies =
229 configurationSoneParser.parsePostReplies(
230 postReplyBuilderFactory);
231 assertThat(postReplies, hasSize(2));
232 assertThat(postReplies,
233 containsInAnyOrder(isPostReply("R0", "P0", 1000L, "T0"),
234 isPostReply("R1", "P1", 1001L, "T1")));
237 private void setupPostReplies() {
238 setupPostReply("0", "R0", "P0", 1000L, "T0");
239 setupPostReply("1", "R1", "P1", 1001L, "T1");
240 setupPostReply("2", null, null, 0L, null);
243 private void setupPostReply(String postReplyNumber, String postReplyId,
244 String postId, long time, String text) {
245 setupString("Sone/1/Replies/" + postReplyNumber + "/ID", postReplyId);
246 setupString("Sone/1/Replies/" + postReplyNumber + "/Post/ID", postId);
247 setupLong("Sone/1/Replies/" + postReplyNumber + "/Time", time);
248 setupString("Sone/1/Replies/" + postReplyNumber + "/Text", text);
251 @Test(expected = InvalidPostReplyFound.class)
252 public void missingPostIdIsRecognized() {
253 setupPostReplyWithMissingPostId();
254 configurationSoneParser.parsePostReplies(null);
257 private void setupPostReplyWithMissingPostId() {
258 setupPostReply("0", "R0", null, 1000L, "T0");
261 @Test(expected = InvalidPostReplyFound.class)
262 public void missingPostReplyTimeIsRecognized() {
263 setupPostReplyWithMissingPostReplyTime();
264 configurationSoneParser.parsePostReplies(null);
267 private void setupPostReplyWithMissingPostReplyTime() {
268 setupPostReply("0", "R0", "P0", 0L, "T0");
271 @Test(expected = InvalidPostReplyFound.class)
272 public void missingPostReplyTextIsRecognized() {
273 setupPostReplyWithMissingPostReplyText();
274 configurationSoneParser.parsePostReplies(null);
277 private void setupPostReplyWithMissingPostReplyText() {
278 setupPostReply("0", "R0", "P0", 1000L, null);
282 public void likedPostIdsParsedCorrectly() {
284 Set<String> likedPostIds =
285 configurationSoneParser.parseLikedPostIds();
286 assertThat(likedPostIds, containsInAnyOrder("P1", "P2", "P3"));
289 private void setupLikedPostIds() {
290 setupString("Sone/1/Likes/Post/0/ID", "P1");
291 setupString("Sone/1/Likes/Post/1/ID", "P2");
292 setupString("Sone/1/Likes/Post/2/ID", "P3");
293 setupString("Sone/1/Likes/Post/3/ID", null);
297 public void likedPostReplyIdsAreParsedCorrectly() {
298 setupLikedPostReplyIds();
299 Set<String> likedPostReplyIds =
300 configurationSoneParser.parseLikedPostReplyIds();
301 assertThat(likedPostReplyIds, containsInAnyOrder("R1", "R2", "R3"));
304 private void setupLikedPostReplyIds() {
305 setupString("Sone/1/Likes/Reply/0/ID", "R1");
306 setupString("Sone/1/Likes/Reply/1/ID", "R2");
307 setupString("Sone/1/Likes/Reply/2/ID", "R3");
308 setupString("Sone/1/Likes/Reply/3/ID", null);
312 public void friendsAreParsedCorrectly() {
314 Set<String> friends = configurationSoneParser.parseFriends();
315 assertThat(friends, containsInAnyOrder("F1", "F2", "F3"));
318 private void setupFriends() {
319 setupString("Sone/1/Friends/0/ID", "F1");
320 setupString("Sone/1/Friends/1/ID", "F2");
321 setupString("Sone/1/Friends/2/ID", "F3");
322 setupString("Sone/1/Friends/3/ID", null);
326 public void topLevelAlbumsAreParsedCorrectly() {
327 setupTopLevelAlbums();
328 AlbumBuilderFactory albumBuilderFactory = createAlbumBuilderFactory();
329 List<Album> topLevelAlbums =
330 configurationSoneParser.parseTopLevelAlbums(
331 albumBuilderFactory);
332 assertThat(topLevelAlbums, hasSize(2));
333 Album firstAlbum = topLevelAlbums.get(0);
334 assertThat(firstAlbum, isAlbum("A1", null, "T1", "D1"));
335 assertThat(firstAlbum.getAlbums(), emptyIterable());
336 assertThat(firstAlbum.getImages(), emptyIterable());
337 Album secondAlbum = topLevelAlbums.get(1);
338 assertThat(secondAlbum, isAlbum("A2", null, "T2", "D2"));
339 assertThat(secondAlbum.getAlbums(), hasSize(1));
340 assertThat(secondAlbum.getImages(), emptyIterable());
341 Album thirdAlbum = secondAlbum.getAlbums().get(0);
342 assertThat(thirdAlbum, isAlbum("A3", "A2", "T3", "D3"));
343 assertThat(thirdAlbum.getAlbums(), emptyIterable());
344 assertThat(thirdAlbum.getImages(), emptyIterable());
347 private void setupTopLevelAlbums() {
348 setupAlbum(0, "A1", null, "T1", "D1", "I1");
349 setupAlbum(1, "A2", null, "T2", "D2", null);
350 setupAlbum(2, "A3", "A2", "T3", "D3", "I3");
351 setupAlbum(3, null, null, null, null, null);
354 private void setupAlbum(int albumNumber, String albumId,
355 String parentAlbumId,
356 String title, String description, String imageId) {
357 final String albumPrefix = "Sone/1/Albums/" + albumNumber;
358 setupString(albumPrefix + "/ID", albumId);
359 setupString(albumPrefix + "/Title", title);
360 setupString(albumPrefix + "/Description", description);
361 setupString(albumPrefix + "/Parent", parentAlbumId);
362 setupString(albumPrefix + "/AlbumImage", imageId);
365 private AlbumBuilderFactory createAlbumBuilderFactory() {
366 AlbumBuilderFactory albumBuilderFactory =
367 mock(AlbumBuilderFactory.class);
368 when(albumBuilderFactory.newAlbumBuilder()).thenAnswer(
369 new Answer<AlbumBuilder>() {
371 public AlbumBuilder answer(InvocationOnMock invocation) {
372 return new TestAlbumBuilder();
375 return albumBuilderFactory;
378 @Test(expected = InvalidAlbumFound.class)
379 public void albumWithInvalidTitleIsRecognized() {
380 setupAlbum(0, "A1", null, null, "D1", "I1");
381 configurationSoneParser.parseTopLevelAlbums(
382 createAlbumBuilderFactory());
385 @Test(expected = InvalidAlbumFound.class)
386 public void albumWithInvalidDescriptionIsRecognized() {
387 setupAlbum(0, "A1", null, "T1", null, "I1");
388 configurationSoneParser.parseTopLevelAlbums(
389 createAlbumBuilderFactory());
392 @Test(expected = InvalidParentAlbumFound.class)
393 public void albumWithInvalidParentIsRecognized() {
394 setupAlbum(0, "A1", "A0", "T1", "D1", "I1");
395 configurationSoneParser.parseTopLevelAlbums(
396 createAlbumBuilderFactory());
400 public void imagesAreParsedCorrectly() {
401 setupTopLevelAlbums();
402 configurationSoneParser.parseTopLevelAlbums(
403 createAlbumBuilderFactory());
405 configurationSoneParser.parseImages(createImageBuilderFactory());
406 Map<String, Album> albums = configurationSoneParser.getAlbums();
407 assertThat(albums.get("A1").getImages(),
408 contains(isImage("I1", 1000L, "K1", "T1", "D1", 16, 9)));
409 assertThat(albums.get("A2").getImages(), contains(
410 isImage("I2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2)));
411 assertThat(albums.get("A3").getImages(), contains(
412 isImage("I3", 3000L, "K3", "T3", "D3", 16 * 3, 9 * 3)));
415 private void setupImages() {
416 setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, 9);
417 setupImage(1, "I2", "A2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2);
418 setupImage(2, "I3", "A3", 3000L, "K3", "T3", "D3", 16 * 3, 9 * 3);
419 setupImage(3, null, null, 0L, null, null, null, 0, 0);
422 private void setupImage(int imageNumber, String id,
423 String parentAlbumId, Long creationTime, String key, String title,
424 String description, Integer width, Integer height) {
425 final String imagePrefix = "Sone/1/Images/" + imageNumber;
426 setupString(imagePrefix + "/ID", id);
427 setupString(imagePrefix + "/Album", parentAlbumId);
428 setupLong(imagePrefix + "/CreationTime", creationTime);
429 setupString(imagePrefix + "/Key", key);
430 setupString(imagePrefix + "/Title", title);
431 setupString(imagePrefix + "/Description", description);
432 setupInteger(imagePrefix + "/Width", width);
433 setupInteger(imagePrefix + "/Height", height);
436 private ImageBuilderFactory createImageBuilderFactory() {
437 ImageBuilderFactory imageBuilderFactory =
438 mock(ImageBuilderFactory.class);
439 when(imageBuilderFactory.newImageBuilder()).thenAnswer(
440 new Answer<ImageBuilder>() {
442 public ImageBuilder answer(InvocationOnMock invocation)
444 return new TestImageBuilder();
447 return imageBuilderFactory;
450 @Test(expected = InvalidImageFound.class)
451 public void missingAlbumIdIsRecognized() {
452 setupTopLevelAlbums();
453 configurationSoneParser.parseTopLevelAlbums(
454 createAlbumBuilderFactory());
455 setupImage(0, "I1", null, 1000L, "K1", "T1", "D1", 16, 9);
456 configurationSoneParser.parseImages(createImageBuilderFactory());
459 @Test(expected = InvalidParentAlbumFound.class)
460 public void invalidAlbumIdIsRecognized() {
461 setupTopLevelAlbums();
462 configurationSoneParser.parseTopLevelAlbums(
463 createAlbumBuilderFactory());
464 setupImage(0, "I1", "A4", 1000L, "K1", "T1", "D1", 16, 9);
465 configurationSoneParser.parseImages(createImageBuilderFactory());
468 @Test(expected = InvalidImageFound.class)
469 public void missingCreationTimeIsRecognized() {
470 setupTopLevelAlbums();
471 configurationSoneParser.parseTopLevelAlbums(
472 createAlbumBuilderFactory());
473 setupImage(0, "I1", "A1", null, "K1", "T1", "D1", 16, 9);
474 configurationSoneParser.parseImages(createImageBuilderFactory());
477 @Test(expected = InvalidImageFound.class)
478 public void missingKeyIsRecognized() {
479 setupTopLevelAlbums();
480 configurationSoneParser.parseTopLevelAlbums(
481 createAlbumBuilderFactory());
482 setupImage(0, "I1", "A1", 1000L, null, "T1", "D1", 16, 9);
483 configurationSoneParser.parseImages(createImageBuilderFactory());
486 @Test(expected = InvalidImageFound.class)
487 public void missingTitleIsRecognized() {
488 setupTopLevelAlbums();
489 configurationSoneParser.parseTopLevelAlbums(
490 createAlbumBuilderFactory());
491 setupImage(0, "I1", "A1", 1000L, "K1", null, "D1", 16, 9);
492 configurationSoneParser.parseImages(createImageBuilderFactory());
495 @Test(expected = InvalidImageFound.class)
496 public void missingDescriptionIsRecognized() {
497 setupTopLevelAlbums();
498 configurationSoneParser.parseTopLevelAlbums(
499 createAlbumBuilderFactory());
500 setupImage(0, "I1", "A1", 1000L, "K1", "T1", null, 16, 9);
501 configurationSoneParser.parseImages(createImageBuilderFactory());
504 @Test(expected = InvalidImageFound.class)
505 public void missingWidthIsRecognized() {
506 setupTopLevelAlbums();
507 configurationSoneParser.parseTopLevelAlbums(
508 createAlbumBuilderFactory());
509 setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", null, 9);
510 configurationSoneParser.parseImages(createImageBuilderFactory());
513 @Test(expected = InvalidImageFound.class)
514 public void missingHeightIsRecognized() {
515 setupTopLevelAlbums();
516 configurationSoneParser.parseTopLevelAlbums(
517 createAlbumBuilderFactory());
518 setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, null);
519 configurationSoneParser.parseImages(createImageBuilderFactory());