import javax.annotation.Nullable;
import net.pterodactylus.sone.data.Post;
+import net.pterodactylus.sone.data.PostReply;
import net.pterodactylus.sone.data.Profile;
import net.pterodactylus.sone.data.Sone;
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.util.config.Configuration;
/**
return (postRecipientId != null) && (postRecipientId.length() == 43);
}
+ public Collection<PostReply> parsePostReplies(
+ PostReplyBuilderFactory postReplyBuilderFactory) {
+ Set<PostReply> replies = new HashSet<PostReply>();
+ while (true) {
+ String replyPrefix = "/Replies/" + replies.size();
+ String replyId = getString(replyPrefix + "/ID", null);
+ if (replyId == null) {
+ break;
+ }
+ String postId = getString(replyPrefix + "/Post/ID", null);
+ long replyTime = getLong(replyPrefix + "/Time", 0L);
+ String replyText = getString(replyPrefix + "/Text", null);
+ if ((postId == null) || (replyTime == 0) || (replyText == null)) {
+ throw new InvalidPostReplyFound();
+ }
+ PostReplyBuilder postReplyBuilder = postReplyBuilderFactory
+ .newPostReplyBuilder()
+ .withId(replyId)
+ .from(sone.getId())
+ .to(postId)
+ .withTime(replyTime)
+ .withText(replyText);
+ replies.add(postReplyBuilder.build());
+ }
+ return replies;
+ }
+
public static class InvalidPostFound extends RuntimeException { }
+ public static class InvalidPostReplyFound extends RuntimeException { }
+
}
import java.util.logging.Logger;
import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostFound;
+import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostReplyFound;
import net.pterodactylus.sone.core.Options.DefaultOption;
import net.pterodactylus.sone.core.SoneInserter.SetInsertionDelay;
import net.pterodactylus.sone.core.event.ImageInsertFinishedEvent;
}
/* load replies. */
- Set<PostReply> replies = new HashSet<PostReply>();
- while (true) {
- String replyPrefix = sonePrefix + "/Replies/" + replies.size();
- String replyId = configuration.getStringValue(replyPrefix + "/ID").getValue(null);
- if (replyId == null) {
- break;
- }
- String postId = configuration.getStringValue(replyPrefix + "/Post/ID").getValue(null);
- long replyTime = configuration.getLongValue(replyPrefix + "/Time").getValue((long) 0);
- String replyText = configuration.getStringValue(replyPrefix + "/Text").getValue(null);
- if ((postId == null) || (replyTime == 0) || (replyText == null)) {
- logger.log(Level.WARNING, "Invalid reply found, aborting load!");
- return;
- }
- PostReplyBuilder postReplyBuilder = postReplyBuilder().withId(replyId).from(sone.getId()).to(postId).withTime(replyTime).withText(replyText);
- replies.add(postReplyBuilder.build());
+ Collection<PostReply> replies;
+ try {
+ replies = configurationSoneParser.parsePostReplies(database);
+ } catch (InvalidPostReplyFound iprf) {
+ logger.log(Level.WARNING, "Invalid reply found, aborting load!");
+ return;
}
/* load post likes. */
import java.io.InputStream;
import net.pterodactylus.sone.data.Post;
+import net.pterodactylus.sone.data.PostReply;
import com.google.common.base.Optional;
import org.hamcrest.Description;
return new PostMatcher(postId, time, text, recipient);
}
+ public static Matcher<PostReply> isPostReply(String postReplyId,
+ String postId, long time, String text) {
+ return new PostReplyMatcher(postReplyId, postId, time, text);
+ }
+
private static class PostMatcher extends TypeSafeDiagnosingMatcher<Post> {
private final String postId;
}
+ private static class PostReplyMatcher
+ extends TypeSafeDiagnosingMatcher<PostReply> {
+
+ private final String postReplyId;
+ private final String postId;
+ private final long time;
+ private final String text;
+
+ private PostReplyMatcher(String postReplyId, String postId, long time,
+ String text) {
+ this.postReplyId = postReplyId;
+ this.postId = postId;
+ this.time = time;
+ this.text = text;
+ }
+
+ @Override
+ protected boolean matchesSafely(PostReply postReply,
+ Description mismatchDescription) {
+ if (!postReply.getId().equals(postReplyId)) {
+ mismatchDescription.appendText("is post reply ")
+ .appendValue(postReply.getId());
+ return false;
+ }
+ if (!postReply.getPostId().equals(postId)) {
+ mismatchDescription.appendText("is reply to ")
+ .appendValue(postReply.getPostId());
+ return false;
+ }
+ if (postReply.getTime() != time) {
+ mismatchDescription.appendText("is created at @").appendValue(
+ postReply.getTime());
+ return false;
+ }
+ if (!postReply.getText().equals(text)) {
+ mismatchDescription.appendText("says ")
+ .appendValue(postReply.getText());
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("is post reply ").appendValue(postReplyId);
+ description.appendText(", replies to post ").appendValue(postId);
+ description.appendText(", is created at @").appendValue(time);
+ description.appendText(", says ").appendValue(text);
+ }
+
+ }
+
}
import static java.lang.System.currentTimeMillis;
import static java.util.UUID.randomUUID;
import static net.pterodactylus.sone.Matchers.isPost;
+import static net.pterodactylus.sone.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 java.util.concurrent.atomic.AtomicReference;
import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostFound;
+import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostReplyFound;
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.PostBuilder;
import net.pterodactylus.sone.database.PostBuilderFactory;
+import net.pterodactylus.sone.database.PostReplyBuilder;
+import net.pterodactylus.sone.database.PostReplyBuilderFactory;
import net.pterodactylus.util.config.Configuration;
import net.pterodactylus.util.config.ConfigurationException;
import net.pterodactylus.util.config.Value;
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);
+ }
private static class TestValue<T> implements Value<T> {
}
+ private static class TestPostReplyBuilder implements PostReplyBuilder {
+
+ private final PostReply postReply = mock(PostReply.class);
+
+ @Override
+ public PostReplyBuilder to(String postId) {
+ when(postReply.getPostId()).thenReturn(postId);
+ return this;
+ }
+
+ @Override
+ public PostReply build() throws IllegalStateException {
+ return postReply;
+ }
+
+ @Override
+ public PostReplyBuilder randomId() {
+ when(postReply.getId()).thenReturn(randomUUID().toString());
+ return this;
+ }
+
+ @Override
+ public PostReplyBuilder withId(String id) {
+ when(postReply.getId()).thenReturn(id);
+ return this;
+ }
+
+ @Override
+ public PostReplyBuilder from(String senderId) {
+ Sone sone = mock(Sone.class);
+ when(sone.getId()).thenReturn(senderId);
+ when(postReply.getSone()).thenReturn(sone);
+ return this;
+ }
+
+ @Override
+ public PostReplyBuilder currentTime() {
+ when(postReply.getTime()).thenReturn(currentTimeMillis());
+ return this;
+ }
+
+ @Override
+ public PostReplyBuilder withTime(long time) {
+ when(postReply.getTime()).thenReturn(time);
+ return this;
+ }
+
+ @Override
+ public PostReplyBuilder withText(String text) {
+ when(postReply.getText()).thenReturn(text);
+ return this;
+ }
+
+ }
+
}