🎨 Replace ConfigurationSoneParserTest with Kotlin version
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 29 Jun 2019 10:48:34 +0000 (12:48 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 29 Jun 2019 10:48:34 +0000 (12:48 +0200)
src/test/java/net/pterodactylus/sone/core/ConfigurationSoneParserTest.java [deleted file]
src/test/kotlin/net/pterodactylus/sone/core/ConfigurationSoneParserTest.kt [new file with mode: 0644]
src/test/kotlin/net/pterodactylus/sone/test/TestUtils.kt

diff --git a/src/test/java/net/pterodactylus/sone/core/ConfigurationSoneParserTest.java b/src/test/java/net/pterodactylus/sone/core/ConfigurationSoneParserTest.java
deleted file mode 100644 (file)
index 4edc1b7..0000000
+++ /dev/null
@@ -1,522 +0,0 @@
-package net.pterodactylus.sone.core;
-
-import static com.google.common.base.Optional.of;
-import static net.pterodactylus.sone.test.Matchers.isAlbum;
-import static net.pterodactylus.sone.test.Matchers.isImage;
-import static net.pterodactylus.sone.test.Matchers.isPost;
-import static net.pterodactylus.sone.test.Matchers.isPostReply;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.Matchers.emptyIterable;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.Matchers.nullValue;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidAlbumFound;
-import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidImageFound;
-import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidParentAlbumFound;
-import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostFound;
-import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostReplyFound;
-import net.pterodactylus.sone.data.Album;
-import net.pterodactylus.sone.data.Post;
-import net.pterodactylus.sone.data.PostReply;
-import net.pterodactylus.sone.data.Profile;
-import net.pterodactylus.sone.data.Profile.Field;
-import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.database.AlbumBuilder;
-import net.pterodactylus.sone.database.AlbumBuilderFactory;
-import net.pterodactylus.sone.database.ImageBuilder;
-import net.pterodactylus.sone.database.ImageBuilderFactory;
-import net.pterodactylus.sone.database.PostBuilder;
-import net.pterodactylus.sone.database.PostBuilderFactory;
-import net.pterodactylus.sone.database.PostReplyBuilder;
-import net.pterodactylus.sone.database.PostReplyBuilderFactory;
-import net.pterodactylus.sone.test.TestAlbumBuilder;
-import net.pterodactylus.sone.test.TestImageBuilder;
-import net.pterodactylus.sone.test.TestPostBuilder;
-import net.pterodactylus.sone.test.TestPostReplyBuilder;
-import net.pterodactylus.sone.test.TestValue;
-import net.pterodactylus.util.config.Configuration;
-
-import com.google.common.base.Optional;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-/**
- * Unit test for {@link ConfigurationSoneParser}.
- */
-public class ConfigurationSoneParserTest {
-
-       private final Configuration configuration = mock(Configuration.class);
-       private final Sone sone = mock(Sone.class);
-       private final ConfigurationSoneParser configurationSoneParser;
-
-       public ConfigurationSoneParserTest() {
-               when(sone.getId()).thenReturn("1");
-               configurationSoneParser =
-                               new ConfigurationSoneParser(configuration, sone);
-       }
-
-       @Test
-       public void emptyProfileIsLoadedCorrectly() {
-               setupEmptyProfile();
-               Profile profile = configurationSoneParser.parseProfile();
-               assertThat(profile, notNullValue());
-               assertThat(profile.getFirstName(), nullValue());
-               assertThat(profile.getMiddleName(), nullValue());
-               assertThat(profile.getLastName(), nullValue());
-               assertThat(profile.getBirthDay(), nullValue());
-               assertThat(profile.getBirthMonth(), nullValue());
-               assertThat(profile.getBirthYear(), nullValue());
-               assertThat(profile.getFields(), emptyIterable());
-       }
-
-       private void setupEmptyProfile() {
-               when(configuration.getStringValue(anyString())).thenReturn(
-                               TestValue.<String>from(null));
-               when(configuration.getIntValue(anyString())).thenReturn(
-                               TestValue.<Integer>from(null));
-       }
-
-       @Test
-       public void filledProfileWithFieldsIsParsedCorrectly() {
-               setupFilledProfile();
-               Profile profile = configurationSoneParser.parseProfile();
-               assertThat(profile, notNullValue());
-               assertThat(profile.getFirstName(), is("First"));
-               assertThat(profile.getMiddleName(), is("M."));
-               assertThat(profile.getLastName(), is("Last"));
-               assertThat(profile.getBirthDay(), is(18));
-               assertThat(profile.getBirthMonth(), is(12));
-               assertThat(profile.getBirthYear(), is(1976));
-               final List<Field> fields = profile.getFields();
-               assertThat(fields, hasSize(2));
-               assertThat(fields.get(0).getName(), is("Field1"));
-               assertThat(fields.get(0).getValue(), is("Value1"));
-               assertThat(fields.get(1).getName(), is("Field2"));
-               assertThat(fields.get(1).getValue(), is("Value2"));
-       }
-
-       private void setupFilledProfile() {
-               setupString("Sone/1/Profile/FirstName", "First");
-               setupString("Sone/1/Profile/MiddleName", "M.");
-               setupString("Sone/1/Profile/LastName", "Last");
-               setupInteger("Sone/1/Profile/BirthDay", 18);
-               setupInteger("Sone/1/Profile/BirthMonth", 12);
-               setupInteger("Sone/1/Profile/BirthYear", 1976);
-               setupString("Sone/1/Profile/Fields/0/Name", "Field1");
-               setupString("Sone/1/Profile/Fields/0/Value", "Value1");
-               setupString("Sone/1/Profile/Fields/1/Name", "Field2");
-               setupString("Sone/1/Profile/Fields/1/Value", "Value2");
-               setupString("Sone/1/Profile/Fields/2/Name", null);
-       }
-
-       private void setupString(String nodeName, String value) {
-               when(configuration.getStringValue(eq(nodeName))).thenReturn(
-                               TestValue.from(value));
-       }
-
-       private void setupInteger(String nodeName, Integer value) {
-               when(configuration.getIntValue(eq(nodeName))).thenReturn(
-                               TestValue.from(value));
-       }
-
-       @Test
-       public void postsAreParsedCorrectly() {
-               setupCompletePosts();
-               PostBuilderFactory postBuilderFactory = createPostBuilderFactory();
-               Collection<Post> posts =
-                               configurationSoneParser.parsePosts(postBuilderFactory);
-               assertThat(posts,
-                               Matchers.<Post>containsInAnyOrder(
-                                               isPost("P0", 1000L, "T0", Optional.<String>absent()),
-                                               isPost("P1", 1001L, "T1",
-                                                               of("1234567890123456789012345678901234567890123"))));
-       }
-
-       private PostBuilderFactory createPostBuilderFactory() {
-               PostBuilderFactory postBuilderFactory =
-                               mock(PostBuilderFactory.class);
-               when(postBuilderFactory.newPostBuilder()).thenAnswer(
-                               new Answer<PostBuilder>() {
-                                       @Override
-                                       public PostBuilder answer(InvocationOnMock invocation)
-                                       throws Throwable {
-                                               return new TestPostBuilder();
-                                       }
-                               });
-               return postBuilderFactory;
-       }
-
-       private void setupCompletePosts() {
-               setupPost("0", "P0", 1000L, "T0", null);
-               setupPost("1", "P1", 1001L, "T1",
-                               "1234567890123456789012345678901234567890123");
-               setupPost("2", null, 0L, null, null);
-       }
-
-       private void setupPost(String postNumber, String postId, long time,
-                       String text, String recipientId) {
-               setupString("Sone/1/Posts/" + postNumber + "/ID", postId);
-               setupLong("Sone/1/Posts/" + postNumber + "/Time", time);
-               setupString("Sone/1/Posts/" + postNumber + "/Text", text);
-               setupString("Sone/1/Posts/" + postNumber + "/Recipient", recipientId);
-       }
-
-       private void setupLong(String nodeName, Long value) {
-               when(configuration.getLongValue(eq(nodeName))).thenReturn(
-                               TestValue.from(value));
-       }
-
-       @Test(expected = InvalidPostFound.class)
-       public void postWithoutTimeIsRecognized() {
-               setupPostWithoutTime();
-               configurationSoneParser.parsePosts(createPostBuilderFactory());
-       }
-
-       private void setupPostWithoutTime() {
-               setupPost("0", "P0", 0L, "T0", null);
-       }
-
-       @Test(expected = InvalidPostFound.class)
-       public void postWithoutTextIsRecognized() {
-               setupPostWithoutText();
-               configurationSoneParser.parsePosts(createPostBuilderFactory());
-       }
-
-       private void setupPostWithoutText() {
-               setupPost("0", "P0", 1000L, null, null);
-       }
-
-       @Test
-       public void postWithInvalidRecipientIdIsRecognized() {
-               setupPostWithInvalidRecipientId();
-               Collection<Post> posts = configurationSoneParser.parsePosts(
-                               createPostBuilderFactory());
-               assertThat(posts, contains(
-                               isPost("P0", 1000L, "T0", Optional.<String>absent())));
-       }
-
-       private void setupPostWithInvalidRecipientId() {
-               setupPost("0", "P0", 1000L, "T0", "123");
-               setupPost("1", null, 0L, null, null);
-       }
-
-       @Test
-       public void postRepliesAreParsedCorrectly() {
-               setupPostReplies();
-               PostReplyBuilderFactory postReplyBuilderFactory =
-                               new PostReplyBuilderFactory() {
-                                       @Override
-                                       public PostReplyBuilder newPostReplyBuilder() {
-                                               return new TestPostReplyBuilder();
-                                       }
-                               };
-               Collection<PostReply> postReplies =
-                               configurationSoneParser.parsePostReplies(
-                                               postReplyBuilderFactory);
-               assertThat(postReplies, hasSize(2));
-               assertThat(postReplies,
-                               containsInAnyOrder(isPostReply("R0", "P0", 1000L, "T0"),
-                                               isPostReply("R1", "P1", 1001L, "T1")));
-       }
-
-       private void setupPostReplies() {
-               setupPostReply("0", "R0", "P0", 1000L, "T0");
-               setupPostReply("1", "R1", "P1", 1001L, "T1");
-               setupPostReply("2", null, null, 0L, null);
-       }
-
-       private void setupPostReply(String postReplyNumber, String postReplyId,
-                       String postId, long time, String text) {
-               setupString("Sone/1/Replies/" + postReplyNumber + "/ID", postReplyId);
-               setupString("Sone/1/Replies/" + postReplyNumber + "/Post/ID", postId);
-               setupLong("Sone/1/Replies/" + postReplyNumber + "/Time", time);
-               setupString("Sone/1/Replies/" + postReplyNumber + "/Text", text);
-       }
-
-       @Test(expected = InvalidPostReplyFound.class)
-       public void missingPostIdIsRecognized() {
-               setupPostReplyWithMissingPostId();
-               configurationSoneParser.parsePostReplies(null);
-       }
-
-       private void setupPostReplyWithMissingPostId() {
-               setupPostReply("0", "R0", null, 1000L, "T0");
-       }
-
-       @Test(expected = InvalidPostReplyFound.class)
-       public void missingPostReplyTimeIsRecognized() {
-               setupPostReplyWithMissingPostReplyTime();
-               configurationSoneParser.parsePostReplies(null);
-       }
-
-       private void setupPostReplyWithMissingPostReplyTime() {
-               setupPostReply("0", "R0", "P0", 0L, "T0");
-       }
-
-       @Test(expected = InvalidPostReplyFound.class)
-       public void missingPostReplyTextIsRecognized() {
-               setupPostReplyWithMissingPostReplyText();
-               configurationSoneParser.parsePostReplies(null);
-       }
-
-       private void setupPostReplyWithMissingPostReplyText() {
-               setupPostReply("0", "R0", "P0", 1000L, null);
-       }
-
-       @Test
-       public void likedPostIdsParsedCorrectly() {
-               setupLikedPostIds();
-               Set<String> likedPostIds =
-                               configurationSoneParser.parseLikedPostIds();
-               assertThat(likedPostIds, containsInAnyOrder("P1", "P2", "P3"));
-       }
-
-       private void setupLikedPostIds() {
-               setupString("Sone/1/Likes/Post/0/ID", "P1");
-               setupString("Sone/1/Likes/Post/1/ID", "P2");
-               setupString("Sone/1/Likes/Post/2/ID", "P3");
-               setupString("Sone/1/Likes/Post/3/ID", null);
-       }
-
-       @Test
-       public void likedPostReplyIdsAreParsedCorrectly() {
-               setupLikedPostReplyIds();
-               Set<String> likedPostReplyIds =
-                               configurationSoneParser.parseLikedPostReplyIds();
-               assertThat(likedPostReplyIds, containsInAnyOrder("R1", "R2", "R3"));
-       }
-
-       private void setupLikedPostReplyIds() {
-               setupString("Sone/1/Likes/Reply/0/ID", "R1");
-               setupString("Sone/1/Likes/Reply/1/ID", "R2");
-               setupString("Sone/1/Likes/Reply/2/ID", "R3");
-               setupString("Sone/1/Likes/Reply/3/ID", null);
-       }
-
-       @Test
-       public void friendsAreParsedCorrectly() {
-               setupFriends();
-               Set<String> friends = configurationSoneParser.parseFriends();
-               assertThat(friends, containsInAnyOrder("F1", "F2", "F3"));
-       }
-
-       private void setupFriends() {
-               setupString("Sone/1/Friends/0/ID", "F1");
-               setupString("Sone/1/Friends/1/ID", "F2");
-               setupString("Sone/1/Friends/2/ID", "F3");
-               setupString("Sone/1/Friends/3/ID", null);
-       }
-
-       @Test
-       public void topLevelAlbumsAreParsedCorrectly() {
-               setupTopLevelAlbums();
-               AlbumBuilderFactory albumBuilderFactory = createAlbumBuilderFactory();
-               List<Album> topLevelAlbums =
-                               configurationSoneParser.parseTopLevelAlbums(
-                                               albumBuilderFactory);
-               assertThat(topLevelAlbums, hasSize(2));
-               Album firstAlbum = topLevelAlbums.get(0);
-               assertThat(firstAlbum, isAlbum("A1", null, "T1", "D1"));
-               assertThat(firstAlbum.getAlbums(), emptyIterable());
-               assertThat(firstAlbum.getImages(), emptyIterable());
-               Album secondAlbum = topLevelAlbums.get(1);
-               assertThat(secondAlbum, isAlbum("A2", null, "T2", "D2"));
-               assertThat(secondAlbum.getAlbums(), hasSize(1));
-               assertThat(secondAlbum.getImages(), emptyIterable());
-               Album thirdAlbum = secondAlbum.getAlbums().get(0);
-               assertThat(thirdAlbum, isAlbum("A3", "A2", "T3", "D3"));
-               assertThat(thirdAlbum.getAlbums(), emptyIterable());
-               assertThat(thirdAlbum.getImages(), emptyIterable());
-       }
-
-       private void setupTopLevelAlbums() {
-               setupAlbum(0, "A1", null, "T1", "D1", "I1");
-               setupAlbum(1, "A2", null, "T2", "D2", null);
-               setupAlbum(2, "A3", "A2", "T3", "D3", "I3");
-               setupAlbum(3, null, null, null, null, null);
-       }
-
-       private void setupAlbum(int albumNumber, String albumId,
-                       String parentAlbumId,
-                       String title, String description, String imageId) {
-               final String albumPrefix = "Sone/1/Albums/" + albumNumber;
-               setupString(albumPrefix + "/ID", albumId);
-               setupString(albumPrefix + "/Title", title);
-               setupString(albumPrefix + "/Description", description);
-               setupString(albumPrefix + "/Parent", parentAlbumId);
-               setupString(albumPrefix + "/AlbumImage", imageId);
-       }
-
-       private AlbumBuilderFactory createAlbumBuilderFactory() {
-               AlbumBuilderFactory albumBuilderFactory =
-                               mock(AlbumBuilderFactory.class);
-               when(albumBuilderFactory.newAlbumBuilder()).thenAnswer(
-                               new Answer<AlbumBuilder>() {
-                                       @Override
-                                       public AlbumBuilder answer(InvocationOnMock invocation) {
-                                               return new TestAlbumBuilder();
-                                       }
-                               });
-               return albumBuilderFactory;
-       }
-
-       @Test(expected = InvalidAlbumFound.class)
-       public void albumWithInvalidTitleIsRecognized() {
-               setupAlbum(0, "A1", null, null, "D1", "I1");
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-       }
-
-       @Test(expected = InvalidAlbumFound.class)
-       public void albumWithInvalidDescriptionIsRecognized() {
-               setupAlbum(0, "A1", null, "T1", null, "I1");
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-       }
-
-       @Test(expected = InvalidParentAlbumFound.class)
-       public void albumWithInvalidParentIsRecognized() {
-               setupAlbum(0, "A1", "A0", "T1", "D1", "I1");
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-       }
-
-       @Test
-       public void imagesAreParsedCorrectly() {
-               setupTopLevelAlbums();
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-               setupImages();
-               configurationSoneParser.parseImages(createImageBuilderFactory());
-               Map<String, Album> albums = configurationSoneParser.getAlbums();
-               assertThat(albums.get("A1").getImages(),
-                               contains(isImage("I1", 1000L, "K1", "T1", "D1", 16, 9)));
-               assertThat(albums.get("A2").getImages(), contains(
-                               isImage("I2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2)));
-               assertThat(albums.get("A3").getImages(), contains(
-                               isImage("I3", 3000L, "K3", "T3", "D3", 16 * 3, 9 * 3)));
-       }
-
-       private void setupImages() {
-               setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, 9);
-               setupImage(1, "I2", "A2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2);
-               setupImage(2, "I3", "A3", 3000L, "K3", "T3", "D3", 16 * 3, 9 * 3);
-               setupImage(3, null, null, 0L, null, null, null, 0, 0);
-       }
-
-       private void setupImage(int imageNumber, String id,
-                       String parentAlbumId, Long creationTime, String key, String title,
-                       String description, Integer width, Integer height) {
-               final String imagePrefix = "Sone/1/Images/" + imageNumber;
-               setupString(imagePrefix + "/ID", id);
-               setupString(imagePrefix + "/Album", parentAlbumId);
-               setupLong(imagePrefix + "/CreationTime", creationTime);
-               setupString(imagePrefix + "/Key", key);
-               setupString(imagePrefix + "/Title", title);
-               setupString(imagePrefix + "/Description", description);
-               setupInteger(imagePrefix + "/Width", width);
-               setupInteger(imagePrefix + "/Height", height);
-       }
-
-       private ImageBuilderFactory createImageBuilderFactory() {
-               ImageBuilderFactory imageBuilderFactory =
-                               mock(ImageBuilderFactory.class);
-               when(imageBuilderFactory.newImageBuilder()).thenAnswer(
-                               new Answer<ImageBuilder>() {
-                                       @Override
-                                       public ImageBuilder answer(InvocationOnMock invocation)
-                                       throws Throwable {
-                                               return new TestImageBuilder();
-                                       }
-                               });
-               return imageBuilderFactory;
-       }
-
-       @Test(expected = InvalidImageFound.class)
-       public void missingAlbumIdIsRecognized() {
-               setupTopLevelAlbums();
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-               setupImage(0, "I1", null, 1000L, "K1", "T1", "D1", 16, 9);
-               configurationSoneParser.parseImages(createImageBuilderFactory());
-       }
-
-       @Test(expected = InvalidParentAlbumFound.class)
-       public void invalidAlbumIdIsRecognized() {
-               setupTopLevelAlbums();
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-               setupImage(0, "I1", "A4", 1000L, "K1", "T1", "D1", 16, 9);
-               configurationSoneParser.parseImages(createImageBuilderFactory());
-       }
-
-       @Test(expected = InvalidImageFound.class)
-       public void missingCreationTimeIsRecognized() {
-               setupTopLevelAlbums();
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-               setupImage(0, "I1", "A1", null, "K1", "T1", "D1", 16, 9);
-               configurationSoneParser.parseImages(createImageBuilderFactory());
-       }
-
-       @Test(expected = InvalidImageFound.class)
-       public void missingKeyIsRecognized() {
-               setupTopLevelAlbums();
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-               setupImage(0, "I1", "A1", 1000L, null, "T1", "D1", 16, 9);
-               configurationSoneParser.parseImages(createImageBuilderFactory());
-       }
-
-       @Test(expected = InvalidImageFound.class)
-       public void missingTitleIsRecognized() {
-               setupTopLevelAlbums();
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-               setupImage(0, "I1", "A1", 1000L, "K1", null, "D1", 16, 9);
-               configurationSoneParser.parseImages(createImageBuilderFactory());
-       }
-
-       @Test(expected = InvalidImageFound.class)
-       public void missingDescriptionIsRecognized() {
-               setupTopLevelAlbums();
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-               setupImage(0, "I1", "A1", 1000L, "K1", "T1", null, 16, 9);
-               configurationSoneParser.parseImages(createImageBuilderFactory());
-       }
-
-       @Test(expected = InvalidImageFound.class)
-       public void missingWidthIsRecognized() {
-               setupTopLevelAlbums();
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-               setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", null, 9);
-               configurationSoneParser.parseImages(createImageBuilderFactory());
-       }
-
-       @Test(expected = InvalidImageFound.class)
-       public void missingHeightIsRecognized() {
-               setupTopLevelAlbums();
-               configurationSoneParser.parseTopLevelAlbums(
-                               createAlbumBuilderFactory());
-               setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, null);
-               configurationSoneParser.parseImages(createImageBuilderFactory());
-       }
-
-}
diff --git a/src/test/kotlin/net/pterodactylus/sone/core/ConfigurationSoneParserTest.kt b/src/test/kotlin/net/pterodactylus/sone/core/ConfigurationSoneParserTest.kt
new file mode 100644 (file)
index 0000000..6f93cd4
--- /dev/null
@@ -0,0 +1,436 @@
+package net.pterodactylus.sone.core
+
+import com.google.common.base.Optional.*
+import net.pterodactylus.sone.core.ConfigurationSoneParser.*
+import net.pterodactylus.sone.data.*
+import net.pterodactylus.sone.database.*
+import net.pterodactylus.sone.test.*
+import net.pterodactylus.sone.test.Matchers.*
+import net.pterodactylus.util.config.*
+import org.hamcrest.MatcherAssert.*
+import org.hamcrest.Matchers.*
+import org.junit.*
+import org.junit.rules.*
+import org.mockito.ArgumentMatchers.*
+import org.mockito.ArgumentMatchers.eq
+
+/**
+ * Unit test for [ConfigurationSoneParser].
+ */
+class ConfigurationSoneParserTest {
+
+       @Rule
+       @JvmField
+       val expectedException = ExpectedException.none()!!
+
+       private val configuration = mock<Configuration>()
+       private val sone = mock<Sone>().apply {
+               whenever(this.id).thenReturn("1")
+       }
+       private val configurationSoneParser = ConfigurationSoneParser(configuration, sone)
+
+       @Test
+       fun emptyProfileIsLoadedCorrectly() {
+               setupEmptyProfile()
+               val profile = configurationSoneParser.parseProfile()
+               assertThat(profile, notNullValue())
+               assertThat(profile.firstName, nullValue())
+               assertThat(profile.middleName, nullValue())
+               assertThat(profile.lastName, nullValue())
+               assertThat(profile.birthDay, nullValue())
+               assertThat(profile.birthMonth, nullValue())
+               assertThat(profile.birthYear, nullValue())
+               assertThat(profile.fields, emptyIterable())
+       }
+
+       private fun setupEmptyProfile() {
+               whenever(configuration.getStringValue(anyString())).thenReturn(TestValue.from(null))
+               whenever(configuration.getIntValue(anyString())).thenReturn(TestValue.from(null))
+       }
+
+       @Test
+       fun filledProfileWithFieldsIsParsedCorrectly() {
+               setupFilledProfile()
+               val profile = configurationSoneParser.parseProfile()
+               assertThat(profile, notNullValue())
+               assertThat(profile.firstName, equalTo("First"))
+               assertThat(profile.middleName, equalTo("M."))
+               assertThat(profile.lastName, equalTo("Last"))
+               assertThat(profile.birthDay, equalTo(18))
+               assertThat(profile.birthMonth, equalTo(12))
+               assertThat(profile.birthYear, equalTo(1976))
+               val fields = profile.fields
+               assertThat(fields, hasSize<Any>(2))
+               assertThat(fields[0].name, equalTo("Field1"))
+               assertThat(fields[0].value, equalTo("Value1"))
+               assertThat(fields[1].name, equalTo("Field2"))
+               assertThat(fields[1].value, equalTo("Value2"))
+       }
+
+       private fun setupFilledProfile() {
+               setupString("Sone/1/Profile/FirstName", "First")
+               setupString("Sone/1/Profile/MiddleName", "M.")
+               setupString("Sone/1/Profile/LastName", "Last")
+               setupInteger("Sone/1/Profile/BirthDay", 18)
+               setupInteger("Sone/1/Profile/BirthMonth", 12)
+               setupInteger("Sone/1/Profile/BirthYear", 1976)
+               setupString("Sone/1/Profile/Fields/0/Name", "Field1")
+               setupString("Sone/1/Profile/Fields/0/Value", "Value1")
+               setupString("Sone/1/Profile/Fields/1/Name", "Field2")
+               setupString("Sone/1/Profile/Fields/1/Value", "Value2")
+               setupString("Sone/1/Profile/Fields/2/Name")
+       }
+
+       private fun setupString(nodeName: String, value: String? = null) {
+               whenever(configuration.getStringValue(eq(nodeName))).thenReturn(TestValue.from(value))
+       }
+
+       private fun setupInteger(nodeName: String, value: Int?) {
+               whenever(configuration.getIntValue(eq(nodeName))).thenReturn(TestValue.from(value))
+       }
+
+       @Test
+       fun postsAreParsedCorrectly() {
+               setupCompletePosts()
+               val postBuilderFactory = createPostBuilderFactory()
+               val posts = configurationSoneParser.parsePosts(postBuilderFactory)
+               assertThat(posts, containsInAnyOrder(
+                               isPost("P0", 1000L, "T0", absent()),
+                               isPost("P1", 1001L, "T1", of("1234567890123456789012345678901234567890123"))
+               ))
+       }
+
+       private fun createPostBuilderFactory(): PostBuilderFactory {
+               val postBuilderFactory = mock<PostBuilderFactory>()
+               whenever(postBuilderFactory.newPostBuilder()).thenAnswer { TestPostBuilder() }
+               return postBuilderFactory
+       }
+
+       private fun setupCompletePosts() {
+               setupPost("0", "P0", 1000L, "T0")
+               setupPost("1", "P1", 1001L, "T1", "1234567890123456789012345678901234567890123")
+               setupPost("2")
+       }
+
+       private fun setupPost(postNumber: String, postId: String? = null, time: Long = 0, text: String? = null, recipientId: String? = null) {
+               setupString("Sone/1/Posts/$postNumber/ID", postId)
+               setupLong("Sone/1/Posts/$postNumber/Time", time)
+               setupString("Sone/1/Posts/$postNumber/Text", text)
+               setupString("Sone/1/Posts/$postNumber/Recipient", recipientId)
+       }
+
+       private fun setupLong(nodeName: String, value: Long?) {
+               whenever(configuration.getLongValue(eq(nodeName))).thenReturn(TestValue.from(value))
+       }
+
+       @Test
+       fun postWithoutTimeIsRecognized() {
+               setupPostWithoutTime()
+               expectedException.expect<InvalidPostFound>()
+               configurationSoneParser.parsePosts(createPostBuilderFactory())
+       }
+
+       private fun setupPostWithoutTime() {
+               setupPost("0", "P0", 0L, "T0")
+       }
+
+       @Test
+       fun postWithoutTextIsRecognized() {
+               setupPostWithoutText()
+               expectedException.expect<InvalidPostFound>()
+               configurationSoneParser.parsePosts(createPostBuilderFactory())
+       }
+
+       private fun setupPostWithoutText() {
+               setupPost("0", "P0", 1000L)
+       }
+
+       @Test
+       fun postWithInvalidRecipientIdIsRecognized() {
+               setupPostWithInvalidRecipientId()
+               val posts = configurationSoneParser.parsePosts(createPostBuilderFactory())
+               assertThat(posts, contains(isPost("P0", 1000L, "T0", absent())))
+       }
+
+       private fun setupPostWithInvalidRecipientId() {
+               setupPost("0", "P0", 1000L, "T0", "123")
+               setupPost("1")
+       }
+
+       @Test
+       fun postRepliesAreParsedCorrectly() {
+               setupPostReplies()
+               val postReplyBuilderFactory = object : PostReplyBuilderFactory {
+                       override fun newPostReplyBuilder(): PostReplyBuilder {
+                               return TestPostReplyBuilder()
+                       }
+               }
+               val postReplies = configurationSoneParser.parsePostReplies(postReplyBuilderFactory)
+               assertThat(postReplies, hasSize(2))
+               assertThat(postReplies, containsInAnyOrder(
+                               isPostReply("R0", "P0", 1000L, "T0"),
+                               isPostReply("R1", "P1", 1001L, "T1")
+               ))
+       }
+
+       private fun setupPostReplies() {
+               setupPostReply("0", "R0", "P0", 1000L, "T0")
+               setupPostReply("1", "R1", "P1", 1001L, "T1")
+               setupPostReply("2")
+       }
+
+       private fun setupPostReply(postReplyNumber: String, postReplyId: String? = null, postId: String? = null, time: Long = 0, text: String? = null) {
+               setupString("Sone/1/Replies/$postReplyNumber/ID", postReplyId)
+               setupString("Sone/1/Replies/$postReplyNumber/Post/ID", postId)
+               setupLong("Sone/1/Replies/$postReplyNumber/Time", time)
+               setupString("Sone/1/Replies/$postReplyNumber/Text", text)
+       }
+
+       @Test
+       fun missingPostIdIsRecognized() {
+               setupPostReplyWithMissingPostId()
+               expectedException.expect<InvalidPostReplyFound>()
+               configurationSoneParser.parsePostReplies(null)
+       }
+
+       private fun setupPostReplyWithMissingPostId() {
+               setupPostReply("0", "R0", null, 1000L, "T0")
+       }
+
+       @Test
+       fun missingPostReplyTimeIsRecognized() {
+               setupPostReplyWithMissingPostReplyTime()
+               expectedException.expect<InvalidPostReplyFound>()
+               configurationSoneParser.parsePostReplies(null)
+       }
+
+       private fun setupPostReplyWithMissingPostReplyTime() {
+               setupPostReply("0", "R0", "P0", 0L, "T0")
+       }
+
+       @Test
+       fun missingPostReplyTextIsRecognized() {
+               setupPostReplyWithMissingPostReplyText()
+               expectedException.expect<InvalidPostReplyFound>()
+               configurationSoneParser.parsePostReplies(null)
+       }
+
+       private fun setupPostReplyWithMissingPostReplyText() {
+               setupPostReply("0", "R0", "P0", 1000L)
+       }
+
+       @Test
+       fun likedPostIdsParsedCorrectly() {
+               setupLikedPostIds()
+               val likedPostIds = configurationSoneParser.parseLikedPostIds()
+               assertThat(likedPostIds, containsInAnyOrder("P1", "P2", "P3"))
+       }
+
+       private fun setupLikedPostIds() {
+               setupString("Sone/1/Likes/Post/0/ID", "P1")
+               setupString("Sone/1/Likes/Post/1/ID", "P2")
+               setupString("Sone/1/Likes/Post/2/ID", "P3")
+               setupString("Sone/1/Likes/Post/3/ID")
+       }
+
+       @Test
+       fun likedPostReplyIdsAreParsedCorrectly() {
+               setupLikedPostReplyIds()
+               val likedPostReplyIds = configurationSoneParser.parseLikedPostReplyIds()
+               assertThat(likedPostReplyIds, containsInAnyOrder("R1", "R2", "R3"))
+       }
+
+       private fun setupLikedPostReplyIds() {
+               setupString("Sone/1/Likes/Reply/0/ID", "R1")
+               setupString("Sone/1/Likes/Reply/1/ID", "R2")
+               setupString("Sone/1/Likes/Reply/2/ID", "R3")
+               setupString("Sone/1/Likes/Reply/3/ID")
+       }
+
+       @Test
+       fun friendsAreParsedCorrectly() {
+               setupFriends()
+               val friends = configurationSoneParser.parseFriends()
+               assertThat(friends, containsInAnyOrder("F1", "F2", "F3"))
+       }
+
+       private fun setupFriends() {
+               setupString("Sone/1/Friends/0/ID", "F1")
+               setupString("Sone/1/Friends/1/ID", "F2")
+               setupString("Sone/1/Friends/2/ID", "F3")
+               setupString("Sone/1/Friends/3/ID")
+       }
+
+       @Test
+       fun topLevelAlbumsAreParsedCorrectly() {
+               setupTopLevelAlbums()
+               val albumBuilderFactory = createAlbumBuilderFactory()
+               val topLevelAlbums = configurationSoneParser.parseTopLevelAlbums(albumBuilderFactory)
+               assertThat(topLevelAlbums, hasSize<Any>(2))
+               val firstAlbum = topLevelAlbums[0]
+               assertThat(firstAlbum, isAlbum("A1", null, "T1", "D1"))
+               assertThat(firstAlbum.albums, emptyIterable<Any>())
+               assertThat<List<Image>>(firstAlbum.images, emptyIterable<Any>())
+               val secondAlbum = topLevelAlbums[1]
+               assertThat(secondAlbum, isAlbum("A2", null, "T2", "D2"))
+               assertThat(secondAlbum.albums, hasSize<Any>(1))
+               assertThat<List<Image>>(secondAlbum.images, emptyIterable<Any>())
+               val thirdAlbum = secondAlbum.albums[0]
+               assertThat(thirdAlbum, isAlbum("A3", "A2", "T3", "D3"))
+               assertThat(thirdAlbum.albums, emptyIterable<Any>())
+               assertThat<List<Image>>(thirdAlbum.images, emptyIterable<Any>())
+       }
+
+       private fun setupTopLevelAlbums() {
+               setupAlbum(0, "A1", null, "T1", "D1", "I1")
+               setupAlbum(1, "A2", null, "T2", "D2")
+               setupAlbum(2, "A3", "A2", "T3", "D3", "I3")
+               setupAlbum(3)
+       }
+
+       private fun setupAlbum(albumNumber: Int, albumId: String? = null, parentAlbumId: String? = null, title: String? = null, description: String? = null, imageId: String? =null) {
+               val albumPrefix = "Sone/1/Albums/$albumNumber"
+               setupString("$albumPrefix/ID", albumId)
+               setupString("$albumPrefix/Title", title)
+               setupString("$albumPrefix/Description", description)
+               setupString("$albumPrefix/Parent", parentAlbumId)
+               setupString("$albumPrefix/AlbumImage", imageId)
+       }
+
+       private fun createAlbumBuilderFactory(): AlbumBuilderFactory {
+               val albumBuilderFactory = mock<AlbumBuilderFactory>()
+               whenever(albumBuilderFactory.newAlbumBuilder()).thenAnswer { TestAlbumBuilder() }
+               return albumBuilderFactory
+       }
+
+       @Test
+       fun albumWithInvalidTitleIsRecognized() {
+               setupAlbum(0, "A1", null, null, "D1", "I1")
+               expectedException.expect<InvalidAlbumFound>()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+       }
+
+       @Test
+       fun albumWithInvalidDescriptionIsRecognized() {
+               setupAlbum(0, "A1", null, "T1", null, "I1")
+               expectedException.expect<InvalidAlbumFound>()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+       }
+
+       @Test
+       fun albumWithInvalidParentIsRecognized() {
+               setupAlbum(0, "A1", "A0", "T1", "D1", "I1")
+               expectedException.expect<InvalidParentAlbumFound>()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+       }
+
+       @Test
+       fun imagesAreParsedCorrectly() {
+               setupTopLevelAlbums()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+               setupImages()
+               configurationSoneParser.parseImages(createImageBuilderFactory())
+               val albums = configurationSoneParser.albums
+               assertThat<List<Image>>(albums["A1"]!!.images, contains<Image>(isImage("I1", 1000L, "K1", "T1", "D1", 16, 9)))
+               assertThat<List<Image>>(albums["A2"]!!.images, contains<Image>(isImage("I2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2)))
+               assertThat<List<Image>>(albums["A3"]!!.images, contains<Image>(isImage("I3", 3000L, "K3", "T3", "D3", 16 * 3, 9 * 3)))
+       }
+
+       private fun setupImages() {
+               setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, 9)
+               setupImage(1, "I2", "A2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2)
+               setupImage(2, "I3", "A3", 3000L, "K3", "T3", "D3", 16 * 3, 9 * 3)
+               setupImage(3, null, null, 0L, null, null, null, 0, 0)
+       }
+
+       private fun setupImage(imageNumber: Int, id: String?, parentAlbumId: String?, creationTime: Long?, key: String?, title: String?, description: String?, width: Int?, height: Int?) {
+               val imagePrefix = "Sone/1/Images/$imageNumber"
+               setupString("$imagePrefix/ID", id)
+               setupString("$imagePrefix/Album", parentAlbumId)
+               setupLong("$imagePrefix/CreationTime", creationTime)
+               setupString("$imagePrefix/Key", key)
+               setupString("$imagePrefix/Title", title)
+               setupString("$imagePrefix/Description", description)
+               setupInteger("$imagePrefix/Width", width)
+               setupInteger("$imagePrefix/Height", height)
+       }
+
+       private fun createImageBuilderFactory(): ImageBuilderFactory {
+               val imageBuilderFactory = mock<ImageBuilderFactory>()
+               whenever(imageBuilderFactory.newImageBuilder()).thenAnswer { TestImageBuilder() }
+               return imageBuilderFactory
+       }
+
+       @Test
+       fun missingAlbumIdIsRecognized() {
+               setupTopLevelAlbums()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+               setupImage(0, "I1", null, 1000L, "K1", "T1", "D1", 16, 9)
+               expectedException.expect<InvalidImageFound>()
+               configurationSoneParser.parseImages(createImageBuilderFactory())
+       }
+
+       @Test
+       fun invalidAlbumIdIsRecognized() {
+               setupTopLevelAlbums()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+               setupImage(0, "I1", "A4", 1000L, "K1", "T1", "D1", 16, 9)
+               expectedException.expect<InvalidParentAlbumFound>()
+               configurationSoneParser.parseImages(createImageBuilderFactory())
+       }
+
+       @Test
+       fun missingCreationTimeIsRecognized() {
+               setupTopLevelAlbums()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+               setupImage(0, "I1", "A1", null, "K1", "T1", "D1", 16, 9)
+               expectedException.expect<InvalidImageFound>()
+               configurationSoneParser.parseImages(createImageBuilderFactory())
+       }
+
+       @Test
+       fun missingKeyIsRecognized() {
+               setupTopLevelAlbums()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+               setupImage(0, "I1", "A1", 1000L, null, "T1", "D1", 16, 9)
+               expectedException.expect<InvalidImageFound>()
+               configurationSoneParser.parseImages(createImageBuilderFactory())
+       }
+
+       @Test
+       fun missingTitleIsRecognized() {
+               setupTopLevelAlbums()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+               setupImage(0, "I1", "A1", 1000L, "K1", null, "D1", 16, 9)
+               expectedException.expect<InvalidImageFound>()
+               configurationSoneParser.parseImages(createImageBuilderFactory())
+       }
+
+       @Test
+       fun missingDescriptionIsRecognized() {
+               setupTopLevelAlbums()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+               setupImage(0, "I1", "A1", 1000L, "K1", "T1", null, 16, 9)
+               expectedException.expect<InvalidImageFound>()
+               configurationSoneParser.parseImages(createImageBuilderFactory())
+       }
+
+       @Test
+       fun missingWidthIsRecognized() {
+               setupTopLevelAlbums()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+               setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", null, 9)
+               expectedException.expect<InvalidImageFound>()
+               configurationSoneParser.parseImages(createImageBuilderFactory())
+       }
+
+       @Test
+       fun missingHeightIsRecognized() {
+               setupTopLevelAlbums()
+               configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
+               setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, null)
+               expectedException.expect<InvalidImageFound>()
+               configurationSoneParser.parseImages(createImageBuilderFactory())
+       }
+
+}
index 9996925..ef23d62 100644 (file)
@@ -1,5 +1,6 @@
 package net.pterodactylus.sone.test
 
+import org.junit.rules.*
 import java.lang.reflect.*
 
 private val modifiers = Field::class.java.getDeclaredField("modifiers").apply {
@@ -17,3 +18,5 @@ fun setField(instance: Any, name: String, value: Any?) {
                                field.set(instance, value)
                        }
 }
+
+inline fun <reified T : Throwable> ExpectedException.expect() = expect(T::class.java)