From: David ‘Bombe’ Roden Date: Sat, 29 Jun 2019 10:48:34 +0000 (+0200) Subject: 🎨 Replace ConfigurationSoneParserTest with Kotlin version X-Git-Tag: v81^2~202 X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=177ffa8fe7cdc29a363eb4e3909a7cfb921ce54c;p=Sone.git 🎨 Replace ConfigurationSoneParserTest with Kotlin version --- 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 index 4edc1b7..0000000 --- a/src/test/java/net/pterodactylus/sone/core/ConfigurationSoneParserTest.java +++ /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.from(null)); - when(configuration.getIntValue(anyString())).thenReturn( - TestValue.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 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 posts = - configurationSoneParser.parsePosts(postBuilderFactory); - assertThat(posts, - Matchers.containsInAnyOrder( - isPost("P0", 1000L, "T0", Optional.absent()), - isPost("P1", 1001L, "T1", - of("1234567890123456789012345678901234567890123")))); - } - - private PostBuilderFactory createPostBuilderFactory() { - PostBuilderFactory postBuilderFactory = - mock(PostBuilderFactory.class); - when(postBuilderFactory.newPostBuilder()).thenAnswer( - new Answer() { - @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 posts = configurationSoneParser.parsePosts( - createPostBuilderFactory()); - assertThat(posts, contains( - isPost("P0", 1000L, "T0", Optional.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 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 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 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 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 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() { - @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 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() { - @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 index 0000000..6f93cd4 --- /dev/null +++ b/src/test/kotlin/net/pterodactylus/sone/core/ConfigurationSoneParserTest.kt @@ -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() + private val sone = mock().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(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() + 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() + configurationSoneParser.parsePosts(createPostBuilderFactory()) + } + + private fun setupPostWithoutTime() { + setupPost("0", "P0", 0L, "T0") + } + + @Test + fun postWithoutTextIsRecognized() { + setupPostWithoutText() + expectedException.expect() + 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() + configurationSoneParser.parsePostReplies(null) + } + + private fun setupPostReplyWithMissingPostId() { + setupPostReply("0", "R0", null, 1000L, "T0") + } + + @Test + fun missingPostReplyTimeIsRecognized() { + setupPostReplyWithMissingPostReplyTime() + expectedException.expect() + configurationSoneParser.parsePostReplies(null) + } + + private fun setupPostReplyWithMissingPostReplyTime() { + setupPostReply("0", "R0", "P0", 0L, "T0") + } + + @Test + fun missingPostReplyTextIsRecognized() { + setupPostReplyWithMissingPostReplyText() + expectedException.expect() + 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(2)) + val firstAlbum = topLevelAlbums[0] + assertThat(firstAlbum, isAlbum("A1", null, "T1", "D1")) + assertThat(firstAlbum.albums, emptyIterable()) + assertThat>(firstAlbum.images, emptyIterable()) + val secondAlbum = topLevelAlbums[1] + assertThat(secondAlbum, isAlbum("A2", null, "T2", "D2")) + assertThat(secondAlbum.albums, hasSize(1)) + assertThat>(secondAlbum.images, emptyIterable()) + val thirdAlbum = secondAlbum.albums[0] + assertThat(thirdAlbum, isAlbum("A3", "A2", "T3", "D3")) + assertThat(thirdAlbum.albums, emptyIterable()) + assertThat>(thirdAlbum.images, emptyIterable()) + } + + 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() + whenever(albumBuilderFactory.newAlbumBuilder()).thenAnswer { TestAlbumBuilder() } + return albumBuilderFactory + } + + @Test + fun albumWithInvalidTitleIsRecognized() { + setupAlbum(0, "A1", null, null, "D1", "I1") + expectedException.expect() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + } + + @Test + fun albumWithInvalidDescriptionIsRecognized() { + setupAlbum(0, "A1", null, "T1", null, "I1") + expectedException.expect() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + } + + @Test + fun albumWithInvalidParentIsRecognized() { + setupAlbum(0, "A1", "A0", "T1", "D1", "I1") + expectedException.expect() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + } + + @Test + fun imagesAreParsedCorrectly() { + setupTopLevelAlbums() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + setupImages() + configurationSoneParser.parseImages(createImageBuilderFactory()) + val albums = configurationSoneParser.albums + assertThat>(albums["A1"]!!.images, contains(isImage("I1", 1000L, "K1", "T1", "D1", 16, 9))) + assertThat>(albums["A2"]!!.images, contains(isImage("I2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2))) + assertThat>(albums["A3"]!!.images, contains(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() + 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() + configurationSoneParser.parseImages(createImageBuilderFactory()) + } + + @Test + fun invalidAlbumIdIsRecognized() { + setupTopLevelAlbums() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + setupImage(0, "I1", "A4", 1000L, "K1", "T1", "D1", 16, 9) + expectedException.expect() + configurationSoneParser.parseImages(createImageBuilderFactory()) + } + + @Test + fun missingCreationTimeIsRecognized() { + setupTopLevelAlbums() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + setupImage(0, "I1", "A1", null, "K1", "T1", "D1", 16, 9) + expectedException.expect() + configurationSoneParser.parseImages(createImageBuilderFactory()) + } + + @Test + fun missingKeyIsRecognized() { + setupTopLevelAlbums() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + setupImage(0, "I1", "A1", 1000L, null, "T1", "D1", 16, 9) + expectedException.expect() + configurationSoneParser.parseImages(createImageBuilderFactory()) + } + + @Test + fun missingTitleIsRecognized() { + setupTopLevelAlbums() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + setupImage(0, "I1", "A1", 1000L, "K1", null, "D1", 16, 9) + expectedException.expect() + configurationSoneParser.parseImages(createImageBuilderFactory()) + } + + @Test + fun missingDescriptionIsRecognized() { + setupTopLevelAlbums() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + setupImage(0, "I1", "A1", 1000L, "K1", "T1", null, 16, 9) + expectedException.expect() + configurationSoneParser.parseImages(createImageBuilderFactory()) + } + + @Test + fun missingWidthIsRecognized() { + setupTopLevelAlbums() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", null, 9) + expectedException.expect() + configurationSoneParser.parseImages(createImageBuilderFactory()) + } + + @Test + fun missingHeightIsRecognized() { + setupTopLevelAlbums() + configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory()) + setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, null) + expectedException.expect() + configurationSoneParser.parseImages(createImageBuilderFactory()) + } + +} diff --git a/src/test/kotlin/net/pterodactylus/sone/test/TestUtils.kt b/src/test/kotlin/net/pterodactylus/sone/test/TestUtils.kt index 9996925..ef23d62 100644 --- a/src/test/kotlin/net/pterodactylus/sone/test/TestUtils.kt +++ b/src/test/kotlin/net/pterodactylus/sone/test/TestUtils.kt @@ -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 ExpectedException.expect() = expect(T::class.java)