Use XML files for all error conditions, expand test for complete Sone.
[Sone.git] / src / test / java / net / pterodactylus / sone / core / SoneParserTest.java
index ee6c82f..2ed984c 100644 (file)
@@ -1,31 +1,35 @@
 package net.pterodactylus.sone.core;
 
-import static com.google.common.base.Optional.absent;
-import static com.google.common.base.Optional.fromNullable;
-import static com.google.common.base.Optional.of;
+import static com.google.common.base.Objects.equal;
 import static java.lang.String.format;
 import static java.util.logging.Level.OFF;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.util.logging.Logger;
 
 import net.pterodactylus.sone.data.Client;
 import net.pterodactylus.sone.data.Image;
+import net.pterodactylus.sone.data.Post;
+import net.pterodactylus.sone.data.PostReply;
+import net.pterodactylus.sone.data.Profile.Field;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.database.Database;
 import net.pterodactylus.sone.database.SoneBuilder.SoneCreated;
 import net.pterodactylus.sone.database.memory.MemoryDatabase;
 
-import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
 import org.junit.Test;
 
 /**
@@ -42,7 +46,6 @@ public class SoneParserTest {
        private final Core core = mock(Core.class);
        private final Database database = new MemoryDatabase(null);
        private final Sone originalSone = database.newSoneBuilder().by("test").using(new Client("TestClient", "1.0")).build(Optional.<SoneCreated>absent());
-       private final SoneXmlBuilder soneXmlBuilder = new SoneXmlBuilder();
        private final SoneParser soneParser = new SoneParser();
 
        public SoneParserTest() {
@@ -59,28 +62,28 @@ public class SoneParserTest {
 
        @Test
        public void verifyThatANegativeProtocolVersionCausesAnError() {
-               Optional<Sone> sone = soneParser.parseSone(database, originalSone, soneXmlBuilder.setProtocolVersion("-1").get());
+               Optional<Sone> sone = soneParser.parseSone(database, originalSone, getXml("negative-protocol-version"));
                assertThat(sone, notNullValue());
                assertThat(sone.isPresent(), is(false));
        }
 
        @Test
        public void verifyThatATooLargeProtocolVersionCausesAnError() {
-               Optional<Sone> sone = soneParser.parseSone(database, originalSone, soneXmlBuilder.setProtocolVersion("1").get());
+               Optional<Sone> sone = soneParser.parseSone(database, originalSone, getXml("too-large-protocol-version"));
                assertThat(sone, notNullValue());
                assertThat(sone.isPresent(), is(false));
        }
 
        @Test
        public void verifyThatAMissingTimeCausesAnError() {
-               Optional<Sone> sone = soneParser.parseSone(database, originalSone, soneXmlBuilder.removeTime().get());
+               Optional<Sone> sone = soneParser.parseSone(database, originalSone, getXml("missing-time"));
                assertThat(sone, notNullValue());
                assertThat(sone.isPresent(), is(false));
        }
 
        @Test
        public void verifyThatAMissingClientCausesTheOriginalClientToBeUsed() {
-               Optional<Sone> sone = soneParser.parseSone(database, originalSone, soneXmlBuilder.removeClientInformation().get());
+               Optional<Sone> sone = soneParser.parseSone(database, originalSone, getXml("missing-client"));
                assertThat(sone, notNullValue());
                assertThat(sone.isPresent(), is(true));
                assertThat(sone.get().getClient(), notNullValue());
@@ -104,108 +107,104 @@ public class SoneParserTest {
                assertThat(sone.get().getProfile().getBirthMonth(), is(10));
                assertThat(sone.get().getProfile().getBirthDay(), is(22));
                assertThat(sone.get().getProfile().getAvatar(), is("96431abe-3add-11e3-8a46-67047503bf6d"));
-       }
+               assertThat(sone.get().getProfile().getFields(), contains(
+                               fieldMatcher("Field1", "Value1"),
+                               fieldMatcher("Field2", "Value2")
+               ));
+               assertThat(sone.get().getPosts(), contains(
+                               postMatcher("d8c9586e-3adb-11e3-bb31-171fc040e645", "0rpD4gL8mszav2trndhIdKIxvKUCNAe2kjA3dLV8CVU", 1382420181000L, "Hello, User!"),
+                               postMatcher("bbb7ebf0-3adb-11e3-8a0b-630cd8f21cf3", null, 1382420140000L, "Hello, World!")
+               ));
+               assertThat(sone.get().getReplies(), containsInAnyOrder(
+                               postReplyMatcher("f09fa448-3adb-11e3-a783-ab54a11aacc4", "bbb7ebf0-3adb-11e3-8a0b-630cd8f21cf3", 1382420224000L, "Talking to myself."),
+                               postReplyMatcher("0a376440-3adc-11e3-8f45-c7cc157436a5", "11ebe86e-3adc-11e3-b7b9-7f2c88018a33", 1382420271000L, "Talking to somebody I can't see.")
+               ));
+               assertThat(sone.get().getLikedPostIds(), containsInAnyOrder(
+                               "bbb7ebf0-3adb-11e3-8a0b-630cd8f21cf3",
+                               "305d85e6-3adc-11e3-be45-8b53dd91f0af"
+               ));
+               assertThat(sone.get().getLikedReplyIds(), containsInAnyOrder(
+                               "f09fa448-3adb-11e3-a783-ab54a11aacc4",
+                               "3ba28960-3adc-11e3-93c7-6713d170f44c"
+               ));
 
-       public InputStream getInputStream(String content) throws UnsupportedEncodingException {
-               return new ByteArrayInputStream(content.getBytes("UTF-8"));
        }
 
-       private InputStream getXml(String name) {
-               return getClass().getResourceAsStream(format("/sone-parser/%s.xml", name));
-       }
+       private Matcher<PostReply> postReplyMatcher(final String id, final String postId, final long time, final String text) {
+               return new TypeSafeMatcher<PostReply>() {
+                       @Override
+                       protected boolean matchesSafely(PostReply postReply) {
+                               return postReply.getId().equals(id) && postReply.getPostId().equals(postId) && (postReply.getTime() == time) && postReply.getText().equals(text);
+                       }
 
-       private static class SoneXmlBuilder {
-
-               private Optional<Long> time = of(1000L);
-               private Optional<String> protocolVersion = of("0");
-               private Optional<String> clientInformation = of("<name>Test-Client</name><version>1.0</version>");
-               private Optional<String> profile = of(Joiner.on("").join(
-                               "<first-name>First</first-name>",
-                               "<middle-name>M.</middle-name>",
-                               "<last-name>Last</last-name>",
-                               "<birth-year>2000</birth-year>",
-                               "<birth-month>9</birth-month>",
-                               "<birth-day>13</birth-day>",
-                               "<avatar>avatar-id</avatar>",
-                               "<fields>",
-                               "<field><field-name>Custom Field</field-name><field-value>Custom Value</field-value></field>",
-                               "</fields>"
-               ));
-               private Optional<String> posts = of("<post><id>post-id</id><time>1</time><recipient>recipient</recipient><text>Hello!</text></post>");
-               private Optional<String> replies = of("<reply><id>reply-id</id><post-id>post-id</post-id><time>2</time><text>Reply!</text></reply>");
-
-               public SoneXmlBuilder removeTime() {
-                       time = absent();
-                       return this;
-               }
-
-               public SoneXmlBuilder setProtocolVersion(String protocolVersion) {
-                       this.protocolVersion = fromNullable(protocolVersion);
-                       return this;
-               }
-
-               public SoneXmlBuilder removeProtocolVersion() {
-                       this.protocolVersion = absent();
-                       return this;
-               }
-
-               public SoneXmlBuilder setClientInformation(String name, String version) {
-                       clientInformation = of("<name>" + name + "</name><version>" + version + "</version>");
-                       return this;
-               }
-
-               public SoneXmlBuilder removeClientInformation() {
-                       clientInformation = absent();
-                       return this;
-               }
-
-               public SoneXmlBuilder removeProfile() {
-                       profile = absent();
-                       return this;
-               }
-
-               public SoneXmlBuilder removePost() {
-                       posts = absent();
-                       return this;
-               }
-
-               public SoneXmlBuilder removeReply() {
-                       replies = absent();
-                       return this;
-               }
-
-               public InputStream get() {
-                       StringBuilder content = new StringBuilder();
-                       content.append("<sone>");
-                       if (time.isPresent()) {
-                               content.append(createXmlElement("time", String.valueOf(time.get())));
+                       @Override
+                       public void describeTo(Description description) {
+                               description.appendText("PostReply(")
+                                               .appendValue(id).appendText(", ")
+                                               .appendValue(postId).appendText(", ")
+                                               .appendValue(time).appendText(", ")
+                                               .appendValue(text).appendText(")");
+                       }
+
+                       @Override
+                       protected void describeMismatchSafely(PostReply postReply, Description mismatchDescription) {
+                               mismatchDescription.appendText("PostReply(")
+                                               .appendValue(postReply.getId()).appendText(", ")
+                                               .appendValue(postReply.getPostId()).appendText(", ")
+                                               .appendValue(postReply.getTime()).appendText(", ")
+                                               .appendValue(postReply.getText()).appendText(")");
                        }
-                       if (protocolVersion.isPresent()) {
-                               content.append(createXmlElement("protocol-version", protocolVersion.get()));
+               };
+       }
+
+       private Matcher<Post> postMatcher(final String id, final String recipient, final long time, final String text) {
+               return new TypeSafeMatcher<Post>() {
+                       @Override
+                       protected boolean matchesSafely(Post post) {
+                               return post.getId().equals(id) && equal(post.getRecipientId().orNull(), recipient) && (post.getTime() == time) && post.getText().equals(text);
                        }
-                       if (clientInformation.isPresent()) {
-                               content.append(createXmlElement("client", clientInformation.get()));
+
+                       @Override
+                       public void describeTo(Description description) {
+                               description.appendText("Post(")
+                                               .appendValue(id).appendText(", ")
+                                               .appendValue(recipient).appendText(", ")
+                                               .appendValue(time).appendText(", ")
+                                               .appendValue(text).appendText(")");
                        }
-                       if (profile.isPresent()) {
-                               content.append(createXmlElement("profile", profile.get()));
+
+                       @Override
+                       protected void describeMismatchSafely(Post post, Description mismatchDescription) {
+                               mismatchDescription.appendText("Post(")
+                                               .appendValue(post.getId()).appendText(", ")
+                                               .appendValue(post.getRecipientId().orNull()).appendText(", ")
+                                               .appendValue(post.getTime()).appendText(", ")
+                                               .appendValue(post.getText()).appendText(")");
                        }
-                       if (posts.isPresent()) {
-                               content.append(createXmlElement("posts", posts.get()));
+               };
+       }
+
+       private Matcher<Field> fieldMatcher(final String name, final String value) {
+               return new TypeSafeMatcher<Field>() {
+                       @Override
+                       protected boolean matchesSafely(Field field) {
+                               return field.getName().equals(name) && field.getValue().equals(value);
                        }
-                       content.append("</sone>");
-                       try {
-                               String xmlString = content.toString();
-                               return new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
-                       } catch (UnsupportedEncodingException e) {
-                               /* ignore. */
+
+                       @Override
+                       public void describeTo(Description description) {
+                               description.appendText("field named ").appendValue(name).appendText(" with value ").appendValue(value);
                        }
-                       return null;
-               }
 
-               private String createXmlElement(String xmlElement, String content) {
-                       return format("<%s>%s</%1$s>", xmlElement, content);
-               }
+                       @Override
+                       protected void describeMismatchSafely(Field field, Description mismatchDescription) {
+                               mismatchDescription.appendText("field named ").appendValue(field.getName()).appendText(" with value ").appendValue(field.getValue());
+                       }
+               };
+       }
 
+       private InputStream getXml(String name) {
+               return getClass().getResourceAsStream(format("/sone-parser/%s.xml", name));
        }
 
 }