1 package net.pterodactylus.sone.core;
3 import static com.google.common.base.Optional.fromNullable;
4 import static com.google.common.base.Optional.of;
5 import static java.lang.System.currentTimeMillis;
6 import static java.util.UUID.randomUUID;
7 import static net.pterodactylus.sone.Matchers.isAlbum;
8 import static net.pterodactylus.sone.Matchers.isImage;
9 import static net.pterodactylus.sone.Matchers.isPost;
10 import static net.pterodactylus.sone.Matchers.isPostReply;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.hamcrest.Matchers.contains;
13 import static org.hamcrest.Matchers.containsInAnyOrder;
14 import static org.hamcrest.Matchers.emptyIterable;
15 import static org.hamcrest.Matchers.hasSize;
16 import static org.hamcrest.Matchers.is;
17 import static org.hamcrest.Matchers.notNullValue;
18 import static org.hamcrest.Matchers.nullValue;
19 import static org.mockito.Matchers.any;
20 import static org.mockito.Matchers.anyString;
21 import static org.mockito.Matchers.eq;
22 import static org.mockito.Mockito.doAnswer;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.when;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.List;
31 import java.util.concurrent.atomic.AtomicReference;
33 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidAlbumFound;
34 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidImageFound;
35 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidParentAlbumFound;
36 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostFound;
37 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostReplyFound;
38 import net.pterodactylus.sone.data.Album;
39 import net.pterodactylus.sone.data.Album.Modifier;
40 import net.pterodactylus.sone.data.Image;
41 import net.pterodactylus.sone.data.Post;
42 import net.pterodactylus.sone.data.PostReply;
43 import net.pterodactylus.sone.data.Profile;
44 import net.pterodactylus.sone.data.Profile.Field;
45 import net.pterodactylus.sone.data.Sone;
46 import net.pterodactylus.sone.database.AlbumBuilder;
47 import net.pterodactylus.sone.database.AlbumBuilderFactory;
48 import net.pterodactylus.sone.database.ImageBuilder;
49 import net.pterodactylus.sone.database.ImageBuilderFactory;
50 import net.pterodactylus.sone.database.PostBuilder;
51 import net.pterodactylus.sone.database.PostBuilderFactory;
52 import net.pterodactylus.sone.database.PostReplyBuilder;
53 import net.pterodactylus.sone.database.PostReplyBuilderFactory;
54 import net.pterodactylus.util.config.Configuration;
55 import net.pterodactylus.util.config.ConfigurationException;
56 import net.pterodactylus.util.config.Value;
58 import com.google.common.base.Optional;
59 import org.hamcrest.Matchers;
60 import org.junit.Test;
61 import org.mockito.invocation.InvocationOnMock;
62 import org.mockito.stubbing.Answer;
65 * Unit test for {@link ConfigurationSoneParser}.
67 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
69 public class ConfigurationSoneParserTest {
71 private final Configuration configuration = mock(Configuration.class);
72 private final Sone sone = mock(Sone.class);
73 private final ConfigurationSoneParser configurationSoneParser;
75 public ConfigurationSoneParserTest() {
76 when(sone.getId()).thenReturn("1");
77 configurationSoneParser =
78 new ConfigurationSoneParser(configuration, sone);
82 public void emptyProfileIsLoadedCorrectly() {
84 Profile profile = configurationSoneParser.parseProfile();
85 assertThat(profile, notNullValue());
86 assertThat(profile.getFirstName(), nullValue());
87 assertThat(profile.getMiddleName(), nullValue());
88 assertThat(profile.getLastName(), nullValue());
89 assertThat(profile.getBirthDay(), nullValue());
90 assertThat(profile.getBirthMonth(), nullValue());
91 assertThat(profile.getBirthYear(), nullValue());
92 assertThat(profile.getFields(), emptyIterable());
95 private void setupEmptyProfile() {
96 when(configuration.getStringValue(anyString())).thenReturn(
97 new TestValue<String>(null));
98 when(configuration.getIntValue(anyString())).thenReturn(
99 new TestValue<Integer>(null));
103 public void filledProfileWithFieldsIsParsedCorrectly() {
104 setupFilledProfile();
105 Profile profile = configurationSoneParser.parseProfile();
106 assertThat(profile, notNullValue());
107 assertThat(profile.getFirstName(), is("First"));
108 assertThat(profile.getMiddleName(), is("M."));
109 assertThat(profile.getLastName(), is("Last"));
110 assertThat(profile.getBirthDay(), is(18));
111 assertThat(profile.getBirthMonth(), is(12));
112 assertThat(profile.getBirthYear(), is(1976));
113 final List<Field> fields = profile.getFields();
114 assertThat(fields, hasSize(2));
115 assertThat(fields.get(0).getName(), is("Field1"));
116 assertThat(fields.get(0).getValue(), is("Value1"));
117 assertThat(fields.get(1).getName(), is("Field2"));
118 assertThat(fields.get(1).getValue(), is("Value2"));
121 private void setupFilledProfile() {
122 setupString("Sone/1/Profile/FirstName", "First");
123 setupString("Sone/1/Profile/MiddleName", "M.");
124 setupString("Sone/1/Profile/LastName", "Last");
125 setupInteger("Sone/1/Profile/BirthDay", 18);
126 setupInteger("Sone/1/Profile/BirthMonth", 12);
127 setupInteger("Sone/1/Profile/BirthYear", 1976);
128 setupString("Sone/1/Profile/Fields/0/Name", "Field1");
129 setupString("Sone/1/Profile/Fields/0/Value", "Value1");
130 setupString("Sone/1/Profile/Fields/1/Name", "Field2");
131 setupString("Sone/1/Profile/Fields/1/Value", "Value2");
132 setupString("Sone/1/Profile/Fields/2/Name", null);
135 private void setupString(String nodeName, String value) {
136 when(configuration.getStringValue(eq(nodeName))).thenReturn(
137 new TestValue<String>(value));
140 private void setupInteger(String nodeName, Integer value) {
141 when(configuration.getIntValue(eq(nodeName))).thenReturn(
142 new TestValue<Integer>(value));
146 public void postsAreParsedCorrectly() {
147 setupCompletePosts();
148 PostBuilderFactory postBuilderFactory = createPostBuilderFactory();
149 Collection<Post> posts =
150 configurationSoneParser.parsePosts(postBuilderFactory);
152 Matchers.<Post>containsInAnyOrder(
153 isPost("P0", 1000L, "T0", Optional.<String>absent()),
154 isPost("P1", 1001L, "T1",
155 of("1234567890123456789012345678901234567890123"))));
158 private PostBuilderFactory createPostBuilderFactory() {
159 PostBuilderFactory postBuilderFactory =
160 mock(PostBuilderFactory.class);
161 when(postBuilderFactory.newPostBuilder()).thenAnswer(
162 new Answer<PostBuilder>() {
164 public PostBuilder answer(InvocationOnMock invocation)
166 return new TestPostBuilder();
169 return postBuilderFactory;
172 private void setupCompletePosts() {
173 setupPost("0", "P0", 1000L, "T0", null);
174 setupPost("1", "P1", 1001L, "T1",
175 "1234567890123456789012345678901234567890123");
176 setupPost("2", null, 0L, null, null);
179 private void setupPost(String postNumber, String postId, long time,
180 String text, String recipientId) {
181 setupString("Sone/1/Posts/" + postNumber + "/ID", postId);
182 setupLong("Sone/1/Posts/" + postNumber + "/Time", time);
183 setupString("Sone/1/Posts/" + postNumber + "/Text", text);
184 setupString("Sone/1/Posts/" + postNumber + "/Recipient", recipientId);
187 private void setupLong(String nodeName, Long value) {
188 when(configuration.getLongValue(eq(nodeName))).thenReturn(
189 new TestValue<Long>(value));
192 @Test(expected = InvalidPostFound.class)
193 public void postWithoutTimeIsRecognized() {
194 setupPostWithoutTime();
195 configurationSoneParser.parsePosts(createPostBuilderFactory());
198 private void setupPostWithoutTime() {
199 setupPost("0", "P0", 0L, "T0", null);
202 @Test(expected = InvalidPostFound.class)
203 public void postWithoutTextIsRecognized() {
204 setupPostWithoutText();
205 configurationSoneParser.parsePosts(createPostBuilderFactory());
208 private void setupPostWithoutText() {
209 setupPost("0", "P0", 1000L, null, null);
213 public void postWithInvalidRecipientIdIsRecognized() {
214 setupPostWithInvalidRecipientId();
215 Collection<Post> posts = configurationSoneParser.parsePosts(
216 createPostBuilderFactory());
217 assertThat(posts, contains(
218 isPost("P0", 1000L, "T0", Optional.<String>absent())));
221 private void setupPostWithInvalidRecipientId() {
222 setupPost("0", "P0", 1000L, "T0", "123");
223 setupPost("1", null, 0L, null, null);
227 public void postRepliesAreParsedCorrectly() {
229 PostReplyBuilderFactory postReplyBuilderFactory =
230 new PostReplyBuilderFactory() {
232 public PostReplyBuilder newPostReplyBuilder() {
233 return new TestPostReplyBuilder();
236 Collection<PostReply> postReplies =
237 configurationSoneParser.parsePostReplies(
238 postReplyBuilderFactory);
239 assertThat(postReplies, hasSize(2));
240 assertThat(postReplies,
241 containsInAnyOrder(isPostReply("R0", "P0", 1000L, "T0"),
242 isPostReply("R1", "P1", 1001L, "T1")));
245 private void setupPostReplies() {
246 setupPostReply("0", "R0", "P0", 1000L, "T0");
247 setupPostReply("1", "R1", "P1", 1001L, "T1");
248 setupPostReply("2", null, null, 0L, null);
251 private void setupPostReply(String postReplyNumber, String postReplyId,
252 String postId, long time, String text) {
253 setupString("Sone/1/Replies/" + postReplyNumber + "/ID", postReplyId);
254 setupString("Sone/1/Replies/" + postReplyNumber + "/Post/ID", postId);
255 setupLong("Sone/1/Replies/" + postReplyNumber + "/Time", time);
256 setupString("Sone/1/Replies/" + postReplyNumber + "/Text", text);
259 @Test(expected = InvalidPostReplyFound.class)
260 public void missingPostIdIsRecognized() {
261 setupPostReplyWithMissingPostId();
262 configurationSoneParser.parsePostReplies(null);
265 private void setupPostReplyWithMissingPostId() {
266 setupPostReply("0", "R0", null, 1000L, "T0");
269 @Test(expected = InvalidPostReplyFound.class)
270 public void missingPostReplyTimeIsRecognized() {
271 setupPostReplyWithMissingPostReplyTime();
272 configurationSoneParser.parsePostReplies(null);
275 private void setupPostReplyWithMissingPostReplyTime() {
276 setupPostReply("0", "R0", "P0", 0L, "T0");
279 @Test(expected = InvalidPostReplyFound.class)
280 public void missingPostReplyTextIsRecognized() {
281 setupPostReplyWithMissingPostReplyText();
282 configurationSoneParser.parsePostReplies(null);
285 private void setupPostReplyWithMissingPostReplyText() {
286 setupPostReply("0", "R0", "P0", 1000L, null);
290 public void likedPostIdsParsedCorrectly() {
292 Set<String> likedPostIds =
293 configurationSoneParser.parseLikedPostIds();
294 assertThat(likedPostIds, containsInAnyOrder("P1", "P2", "P3"));
297 private void setupLikedPostIds() {
298 setupString("Sone/1/Likes/Post/0/ID", "P1");
299 setupString("Sone/1/Likes/Post/1/ID", "P2");
300 setupString("Sone/1/Likes/Post/2/ID", "P3");
301 setupString("Sone/1/Likes/Post/3/ID", null);
305 public void likedPostReplyIdsAreParsedCorrectly() {
306 setupLikedPostReplyIds();
307 Set<String> likedPostReplyIds =
308 configurationSoneParser.parseLikedPostReplyIds();
309 assertThat(likedPostReplyIds, containsInAnyOrder("R1", "R2", "R3"));
312 private void setupLikedPostReplyIds() {
313 setupString("Sone/1/Likes/Reply/0/ID", "R1");
314 setupString("Sone/1/Likes/Reply/1/ID", "R2");
315 setupString("Sone/1/Likes/Reply/2/ID", "R3");
316 setupString("Sone/1/Likes/Reply/3/ID", null);
320 public void friendsAreParsedCorrectly() {
322 Set<String> friends = configurationSoneParser.parseFriends();
323 assertThat(friends, containsInAnyOrder("F1", "F2", "F3"));
326 private void setupFriends() {
327 setupString("Sone/1/Friends/0/ID", "F1");
328 setupString("Sone/1/Friends/1/ID", "F2");
329 setupString("Sone/1/Friends/2/ID", "F3");
330 setupString("Sone/1/Friends/3/ID", null);
334 public void topLevelAlbumsAreParsedCorrectly() {
335 setupTopLevelAlbums();
336 AlbumBuilderFactory albumBuilderFactory = createAlbumBuilderFactory();
337 List<Album> topLevelAlbums =
338 configurationSoneParser.parseTopLevelAlbums(
339 albumBuilderFactory);
340 assertThat(topLevelAlbums, hasSize(2));
341 Album firstAlbum = topLevelAlbums.get(0);
342 assertThat(firstAlbum, isAlbum("A1", null, "T1", "D1", "I1"));
343 assertThat(firstAlbum.getAlbums(), emptyIterable());
344 assertThat(firstAlbum.getImages(), emptyIterable());
345 Album secondAlbum = topLevelAlbums.get(1);
346 assertThat(secondAlbum, isAlbum("A2", null, "T2", "D2", null));
347 assertThat(secondAlbum.getAlbums(), hasSize(1));
348 assertThat(secondAlbum.getImages(), emptyIterable());
349 Album thirdAlbum = secondAlbum.getAlbums().get(0);
350 assertThat(thirdAlbum, isAlbum("A3", "A2", "T3", "D3", "I3"));
351 assertThat(thirdAlbum.getAlbums(), emptyIterable());
352 assertThat(thirdAlbum.getImages(), emptyIterable());
355 private void setupTopLevelAlbums() {
356 setupAlbum(0, "A1", null, "T1", "D1", "I1");
357 setupAlbum(1, "A2", null, "T2", "D2", null);
358 setupAlbum(2, "A3", "A2", "T3", "D3", "I3");
359 setupAlbum(3, null, null, null, null, null);
362 private void setupAlbum(int albumNumber, String albumId,
363 String parentAlbumId,
364 String title, String description, String imageId) {
365 final String albumPrefix = "Sone/1/Albums/" + albumNumber;
366 setupString(albumPrefix + "/ID", albumId);
367 setupString(albumPrefix + "/Title", title);
368 setupString(albumPrefix + "/Description", description);
369 setupString(albumPrefix + "/Parent", parentAlbumId);
370 setupString(albumPrefix + "/AlbumImage", imageId);
373 private AlbumBuilderFactory createAlbumBuilderFactory() {
374 AlbumBuilderFactory albumBuilderFactory =
375 mock(AlbumBuilderFactory.class);
376 when(albumBuilderFactory.newAlbumBuilder()).thenAnswer(
377 new Answer<AlbumBuilder>() {
379 public AlbumBuilder answer(InvocationOnMock invocation) {
380 return new TestAlbumBuilder();
383 return albumBuilderFactory;
386 @Test(expected = InvalidAlbumFound.class)
387 public void albumWithInvalidTitleIsRecognized() {
388 setupAlbum(0, "A1", null, null, "D1", "I1");
389 configurationSoneParser.parseTopLevelAlbums(
390 createAlbumBuilderFactory());
393 @Test(expected = InvalidAlbumFound.class)
394 public void albumWithInvalidDescriptionIsRecognized() {
395 setupAlbum(0, "A1", null, "T1", null, "I1");
396 configurationSoneParser.parseTopLevelAlbums(
397 createAlbumBuilderFactory());
400 @Test(expected = InvalidParentAlbumFound.class)
401 public void albumWithInvalidParentIsRecognized() {
402 setupAlbum(0, "A1", "A0", "T1", "D1", "I1");
403 configurationSoneParser.parseTopLevelAlbums(
404 createAlbumBuilderFactory());
408 public void imagesAreParsedCorrectly() {
409 setupTopLevelAlbums();
410 configurationSoneParser.parseTopLevelAlbums(
411 createAlbumBuilderFactory());
413 configurationSoneParser.parseImages(createImageBuilderFactory());
414 Map<String, Album> albums = configurationSoneParser.getAlbums();
415 assertThat(albums.get("A1").getImages(),
416 contains(isImage("I1", 1000L, "K1", "T1", "D1", 16, 9)));
417 assertThat(albums.get("A2").getImages(), contains(
418 isImage("I2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2)));
419 assertThat(albums.get("A3").getImages(), contains(
420 isImage("I3", 3000L, "K3", "T3", "D3", 16 * 3, 9 * 3)));
423 private void setupImages() {
424 setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, 9);
425 setupImage(1, "I2", "A2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2);
426 setupImage(2, "I3", "A3", 3000L, "K3", "T3", "D3", 16 * 3, 9 * 3);
427 setupImage(3, null, null, 0L, null, null, null, 0, 0);
430 private void setupImage(int imageNumber, String id,
431 String parentAlbumId, Long creationTime, String key, String title,
432 String description, Integer width, Integer height) {
433 final String imagePrefix = "Sone/1/Images/" + imageNumber;
434 setupString(imagePrefix + "/ID", id);
435 setupString(imagePrefix + "/Album", parentAlbumId);
436 setupLong(imagePrefix + "/CreationTime", creationTime);
437 setupString(imagePrefix + "/Key", key);
438 setupString(imagePrefix + "/Title", title);
439 setupString(imagePrefix + "/Description", description);
440 setupInteger(imagePrefix + "/Width", width);
441 setupInteger(imagePrefix + "/Height", height);
444 private ImageBuilderFactory createImageBuilderFactory() {
445 ImageBuilderFactory imageBuilderFactory =
446 mock(ImageBuilderFactory.class);
447 when(imageBuilderFactory.newImageBuilder()).thenAnswer(
448 new Answer<ImageBuilder>() {
450 public ImageBuilder answer(InvocationOnMock invocation)
452 return new TestImageBuilder();
455 return imageBuilderFactory;
458 @Test(expected = InvalidImageFound.class)
459 public void missingAlbumIdIsRecognized() {
460 setupTopLevelAlbums();
461 configurationSoneParser.parseTopLevelAlbums(
462 createAlbumBuilderFactory());
463 setupImage(0, "I1", null, 1000L, "K1", "T1", "D1", 16, 9);
464 configurationSoneParser.parseImages(createImageBuilderFactory());
467 @Test(expected = InvalidParentAlbumFound.class)
468 public void invalidAlbumIdIsRecognized() {
469 setupTopLevelAlbums();
470 configurationSoneParser.parseTopLevelAlbums(
471 createAlbumBuilderFactory());
472 setupImage(0, "I1", "A4", 1000L, "K1", "T1", "D1", 16, 9);
473 configurationSoneParser.parseImages(createImageBuilderFactory());
476 @Test(expected = InvalidImageFound.class)
477 public void missingCreationTimeIsRecognized() {
478 setupTopLevelAlbums();
479 configurationSoneParser.parseTopLevelAlbums(
480 createAlbumBuilderFactory());
481 setupImage(0, "I1", "A1", null, "K1", "T1", "D1", 16, 9);
482 configurationSoneParser.parseImages(createImageBuilderFactory());
485 @Test(expected = InvalidImageFound.class)
486 public void missingKeyIsRecognized() {
487 setupTopLevelAlbums();
488 configurationSoneParser.parseTopLevelAlbums(
489 createAlbumBuilderFactory());
490 setupImage(0, "I1", "A1", 1000L, null, "T1", "D1", 16, 9);
491 configurationSoneParser.parseImages(createImageBuilderFactory());
494 @Test(expected = InvalidImageFound.class)
495 public void missingTitleIsRecognized() {
496 setupTopLevelAlbums();
497 configurationSoneParser.parseTopLevelAlbums(
498 createAlbumBuilderFactory());
499 setupImage(0, "I1", "A1", 1000L, "K1", null, "D1", 16, 9);
500 configurationSoneParser.parseImages(createImageBuilderFactory());
503 @Test(expected = InvalidImageFound.class)
504 public void missingDescriptionIsRecognized() {
505 setupTopLevelAlbums();
506 configurationSoneParser.parseTopLevelAlbums(
507 createAlbumBuilderFactory());
508 setupImage(0, "I1", "A1", 1000L, "K1", "T1", null, 16, 9);
509 configurationSoneParser.parseImages(createImageBuilderFactory());
512 @Test(expected = InvalidImageFound.class)
513 public void missingWidthIsRecognized() {
514 setupTopLevelAlbums();
515 configurationSoneParser.parseTopLevelAlbums(
516 createAlbumBuilderFactory());
517 setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", null, 9);
518 configurationSoneParser.parseImages(createImageBuilderFactory());
521 @Test(expected = InvalidImageFound.class)
522 public void missingHeightIsRecognized() {
523 setupTopLevelAlbums();
524 configurationSoneParser.parseTopLevelAlbums(
525 createAlbumBuilderFactory());
526 setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, null);
527 configurationSoneParser.parseImages(createImageBuilderFactory());
530 private static class TestValue<T> implements Value<T> {
532 private final AtomicReference<T> value = new AtomicReference<T>();
534 public TestValue(T originalValue) {
535 value.set(originalValue);
539 public T getValue() throws ConfigurationException {
544 public T getValue(T defaultValue) {
545 final T realValue = value.get();
546 return (realValue != null) ? realValue : defaultValue;
550 public void setValue(T newValue) throws ConfigurationException {
556 private static class TestPostBuilder implements PostBuilder {
558 private final Post post = mock(Post.class);
559 private String recipientId = null;
562 public PostBuilder copyPost(Post post) throws NullPointerException {
567 public PostBuilder from(String senderId) {
568 final Sone sone = mock(Sone.class);
569 when(sone.getId()).thenReturn(senderId);
570 when(post.getSone()).thenReturn(sone);
575 public PostBuilder randomId() {
576 when(post.getId()).thenReturn(randomUUID().toString());
581 public PostBuilder withId(String id) {
582 when(post.getId()).thenReturn(id);
587 public PostBuilder currentTime() {
588 when(post.getTime()).thenReturn(currentTimeMillis());
593 public PostBuilder withTime(long time) {
594 when(post.getTime()).thenReturn(time);
599 public PostBuilder withText(String text) {
600 when(post.getText()).thenReturn(text);
605 public PostBuilder to(String recipientId) {
606 this.recipientId = recipientId;
611 public Post build() throws IllegalStateException {
612 when(post.getRecipientId()).thenReturn(fromNullable(recipientId));
618 private static class TestPostReplyBuilder implements PostReplyBuilder {
620 private final PostReply postReply = mock(PostReply.class);
623 public PostReplyBuilder to(String postId) {
624 when(postReply.getPostId()).thenReturn(postId);
629 public PostReply build() throws IllegalStateException {
634 public PostReplyBuilder randomId() {
635 when(postReply.getId()).thenReturn(randomUUID().toString());
640 public PostReplyBuilder withId(String id) {
641 when(postReply.getId()).thenReturn(id);
646 public PostReplyBuilder from(String senderId) {
647 Sone sone = mock(Sone.class);
648 when(sone.getId()).thenReturn(senderId);
649 when(postReply.getSone()).thenReturn(sone);
654 public PostReplyBuilder currentTime() {
655 when(postReply.getTime()).thenReturn(currentTimeMillis());
660 public PostReplyBuilder withTime(long time) {
661 when(postReply.getTime()).thenReturn(time);
666 public PostReplyBuilder withText(String text) {
667 when(postReply.getText()).thenReturn(text);
673 private static class TestAlbumBuilder implements AlbumBuilder {
675 private final Album album = mock(Album.class);
676 private final List<Album> albums = new ArrayList<Album>();
677 private final List<Image> images = new ArrayList<Image>();
678 private Album parentAlbum;
679 private String title;
680 private String description;
681 private String imageId;
683 public TestAlbumBuilder() {
684 when(album.getTitle()).thenAnswer(new Answer<String>() {
686 public String answer(InvocationOnMock invocation) {
690 when(album.getDescription()).thenAnswer(new Answer<String>() {
692 public String answer(InvocationOnMock invocation) {
696 when(album.getAlbumImage()).thenAnswer(new Answer<Image>() {
698 public Image answer(InvocationOnMock invocation) {
699 if (imageId == null) {
702 Image image = mock(Image.class);
703 when(image.getId()).thenReturn(imageId);
707 when(album.getAlbums()).thenReturn(albums);
708 when(album.getImages()).thenReturn(images);
709 doAnswer(new Answer<Void>() {
711 public Void answer(InvocationOnMock invocation) {
712 albums.add((Album) invocation.getArguments()[0]);
713 ((Album) invocation.getArguments()[0]).setParent(album);
716 }).when(album).addAlbum(any(Album.class));
717 doAnswer(new Answer<Void>() {
719 public Void answer(InvocationOnMock invocation) {
720 images.add((Image) invocation.getArguments()[0]);
723 }).when(album).addImage(any(Image.class));
724 doAnswer(new Answer<Void>() {
726 public Void answer(InvocationOnMock invocation) {
727 parentAlbum = (Album) invocation.getArguments()[0];
730 }).when(album).setParent(any(Album.class));
731 when(album.getParent()).thenAnswer(new Answer<Album>() {
733 public Album answer(InvocationOnMock invocation) {
737 when(album.modify()).thenReturn(new Modifier() {
739 public Modifier setTitle(String title) {
740 TestAlbumBuilder.this.title = title;
745 public Modifier setDescription(String description) {
746 TestAlbumBuilder.this.description = description;
751 public Modifier setAlbumImage(String imageId) {
752 TestAlbumBuilder.this.imageId = imageId;
757 public Album update() throws IllegalStateException {
764 public AlbumBuilder randomId() {
765 when(album.getId()).thenReturn(randomUUID().toString());
770 public AlbumBuilder withId(String id) {
771 when(album.getId()).thenReturn(id);
776 public AlbumBuilder by(Sone sone) {
777 when(album.getSone()).thenReturn(sone);
782 public Album build() throws IllegalStateException {
788 private static class TestImageBuilder implements ImageBuilder {
790 private final Image image;
792 private TestImageBuilder() {
793 image = mock(Image.class);
794 Image.Modifier imageModifier = new Image.Modifier() {
795 private Sone sone = image.getSone();
796 private long creationTime = image.getCreationTime();
797 private String key = image.getKey();
798 private String title = image.getTitle();
799 private String description = image.getDescription();
800 private int width = image.getWidth();
801 private int height = image.getHeight();
804 public Image.Modifier setSone(Sone sone) {
810 public Image.Modifier setCreationTime(long creationTime) {
811 this.creationTime = creationTime;
816 public Image.Modifier setKey(String key) {
822 public Image.Modifier setTitle(String title) {
828 public Image.Modifier setDescription(String description) {
829 this.description = description;
834 public Image.Modifier setWidth(int width) {
840 public Image.Modifier setHeight(int height) {
841 this.height = height;
846 public Image update() throws IllegalStateException {
847 when(image.getSone()).thenReturn(sone);
848 when(image.getCreationTime()).thenReturn(creationTime);
849 when(image.getKey()).thenReturn(key);
850 when(image.getTitle()).thenReturn(title);
851 when(image.getDescription()).thenReturn(description);
852 when(image.getWidth()).thenReturn(width);
853 when(image.getHeight()).thenReturn(height);
857 when(image.modify()).thenReturn(imageModifier);
861 public ImageBuilder randomId() {
862 when(image.getId()).thenReturn(randomUUID().toString());
867 public ImageBuilder withId(String id) {
868 when(image.getId()).thenReturn(id);
873 public Image build() throws IllegalStateException {