1 package net.pterodactylus.sone.core;
3 import static com.google.common.base.Optional.fromNullable;
4 import static com.google.common.base.Optional.of;
5 import static java.lang.System.currentTimeMillis;
6 import static java.util.UUID.randomUUID;
7 import static net.pterodactylus.sone.Matchers.isPost;
8 import static net.pterodactylus.sone.Matchers.isPostReply;
9 import static org.hamcrest.MatcherAssert.assertThat;
10 import static org.hamcrest.Matchers.contains;
11 import static org.hamcrest.Matchers.containsInAnyOrder;
12 import static org.hamcrest.Matchers.emptyIterable;
13 import static org.hamcrest.Matchers.hasSize;
14 import static org.hamcrest.Matchers.is;
15 import static org.hamcrest.Matchers.notNullValue;
16 import static org.hamcrest.Matchers.nullValue;
17 import static org.mockito.Matchers.anyString;
18 import static org.mockito.Matchers.eq;
19 import static org.mockito.Mockito.mock;
20 import static org.mockito.Mockito.when;
22 import java.util.Collection;
23 import java.util.List;
25 import java.util.concurrent.atomic.AtomicReference;
27 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostFound;
28 import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidPostReplyFound;
29 import net.pterodactylus.sone.data.Post;
30 import net.pterodactylus.sone.data.PostReply;
31 import net.pterodactylus.sone.data.Profile;
32 import net.pterodactylus.sone.data.Profile.Field;
33 import net.pterodactylus.sone.data.Sone;
34 import net.pterodactylus.sone.database.PostBuilder;
35 import net.pterodactylus.sone.database.PostBuilderFactory;
36 import net.pterodactylus.sone.database.PostReplyBuilder;
37 import net.pterodactylus.sone.database.PostReplyBuilderFactory;
38 import net.pterodactylus.util.config.Configuration;
39 import net.pterodactylus.util.config.ConfigurationException;
40 import net.pterodactylus.util.config.Value;
42 import com.google.common.base.Optional;
43 import org.hamcrest.Matchers;
44 import org.junit.Test;
45 import org.mockito.invocation.InvocationOnMock;
46 import org.mockito.stubbing.Answer;
49 * Unit test for {@link ConfigurationSoneParser}.
51 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
53 public class ConfigurationSoneParserTest {
55 private final Configuration configuration = mock(Configuration.class);
56 private final Sone sone = mock(Sone.class);
57 private final ConfigurationSoneParser configurationSoneParser;
59 public ConfigurationSoneParserTest() {
60 when(sone.getId()).thenReturn("1");
61 configurationSoneParser =
62 new ConfigurationSoneParser(configuration, sone);
66 public void emptyProfileIsLoadedCorrectly() {
68 Profile profile = configurationSoneParser.parseProfile();
69 assertThat(profile, notNullValue());
70 assertThat(profile.getFirstName(), nullValue());
71 assertThat(profile.getMiddleName(), nullValue());
72 assertThat(profile.getLastName(), nullValue());
73 assertThat(profile.getBirthDay(), nullValue());
74 assertThat(profile.getBirthMonth(), nullValue());
75 assertThat(profile.getBirthYear(), nullValue());
76 assertThat(profile.getFields(), emptyIterable());
79 private void setupEmptyProfile() {
80 when(configuration.getStringValue(anyString())).thenReturn(
81 new TestValue<String>(null));
82 when(configuration.getIntValue(anyString())).thenReturn(
83 new TestValue<Integer>(null));
87 public void filledProfileWithFieldsIsParsedCorrectly() {
89 Profile profile = configurationSoneParser.parseProfile();
90 assertThat(profile, notNullValue());
91 assertThat(profile.getFirstName(), is("First"));
92 assertThat(profile.getMiddleName(), is("M."));
93 assertThat(profile.getLastName(), is("Last"));
94 assertThat(profile.getBirthDay(), is(18));
95 assertThat(profile.getBirthMonth(), is(12));
96 assertThat(profile.getBirthYear(), is(1976));
97 final List<Field> fields = profile.getFields();
98 assertThat(fields, hasSize(2));
99 assertThat(fields.get(0).getName(), is("Field1"));
100 assertThat(fields.get(0).getValue(), is("Value1"));
101 assertThat(fields.get(1).getName(), is("Field2"));
102 assertThat(fields.get(1).getValue(), is("Value2"));
105 private void setupFilledProfile() {
106 setupString("Sone/1/Profile/FirstName", "First");
107 setupString("Sone/1/Profile/MiddleName", "M.");
108 setupString("Sone/1/Profile/LastName", "Last");
109 setupInteger("Sone/1/Profile/BirthDay", 18);
110 setupInteger("Sone/1/Profile/BirthMonth", 12);
111 setupInteger("Sone/1/Profile/BirthYear", 1976);
112 setupString("Sone/1/Profile/Fields/0/Name", "Field1");
113 setupString("Sone/1/Profile/Fields/0/Value", "Value1");
114 setupString("Sone/1/Profile/Fields/1/Name", "Field2");
115 setupString("Sone/1/Profile/Fields/1/Value", "Value2");
116 setupString("Sone/1/Profile/Fields/2/Name", null);
119 private void setupString(String nodeName, String value) {
120 when(configuration.getStringValue(eq(nodeName))).thenReturn(
121 new TestValue<String>(value));
124 private void setupInteger(String nodeName, Integer value) {
125 when(configuration.getIntValue(eq(nodeName))).thenReturn(
126 new TestValue<Integer>(value));
130 public void postsAreParsedCorrectly() {
131 setupCompletePosts();
132 PostBuilderFactory postBuilderFactory = createPostBuilderFactory();
133 Collection<Post> posts =
134 configurationSoneParser.parsePosts(postBuilderFactory);
136 Matchers.<Post>containsInAnyOrder(
137 isPost("P0", 1000L, "T0", Optional.<String>absent()),
138 isPost("P1", 1001L, "T1",
139 of("1234567890123456789012345678901234567890123"))));
142 private PostBuilderFactory createPostBuilderFactory() {
143 PostBuilderFactory postBuilderFactory =
144 mock(PostBuilderFactory.class);
145 when(postBuilderFactory.newPostBuilder()).thenAnswer(
146 new Answer<PostBuilder>() {
148 public PostBuilder answer(InvocationOnMock invocation)
150 return new TestPostBuilder();
153 return postBuilderFactory;
156 private void setupCompletePosts() {
157 setupPost("0", "P0", 1000L, "T0", null);
158 setupPost("1", "P1", 1001L, "T1",
159 "1234567890123456789012345678901234567890123");
160 setupPost("2", null, 0L, null, null);
163 private void setupPost(String postNumber, String postId, long time,
164 String text, String recipientId) {
165 setupString("Sone/1/Posts/" + postNumber + "/ID", postId);
166 setupLong("Sone/1/Posts/" + postNumber + "/Time", time);
167 setupString("Sone/1/Posts/" + postNumber + "/Text", text);
168 setupString("Sone/1/Posts/" + postNumber + "/Recipient", recipientId);
171 private void setupLong(String nodeName, Long value) {
172 when(configuration.getLongValue(eq(nodeName))).thenReturn(
173 new TestValue<Long>(value));
176 @Test(expected = InvalidPostFound.class)
177 public void postWithoutTimeIsRecognized() {
178 setupPostWithoutTime();
179 configurationSoneParser.parsePosts(createPostBuilderFactory());
182 private void setupPostWithoutTime() {
183 setupPost("0", "P0", 0L, "T0", null);
186 @Test(expected = InvalidPostFound.class)
187 public void postWithoutTextIsRecognized() {
188 setupPostWithoutText();
189 configurationSoneParser.parsePosts(createPostBuilderFactory());
192 private void setupPostWithoutText() {
193 setupPost("0", "P0", 1000L, null, null);
197 public void postWithInvalidRecipientIdIsRecognized() {
198 setupPostWithInvalidRecipientId();
199 Collection<Post> posts = configurationSoneParser.parsePosts(
200 createPostBuilderFactory());
201 assertThat(posts, contains(
202 isPost("P0", 1000L, "T0", Optional.<String>absent())));
205 private void setupPostWithInvalidRecipientId() {
206 setupPost("0", "P0", 1000L, "T0", "123");
207 setupPost("1", null, 0L, null, null);
211 public void postRepliesAreParsedCorrectly() {
213 PostReplyBuilderFactory postReplyBuilderFactory =
214 new PostReplyBuilderFactory() {
216 public PostReplyBuilder newPostReplyBuilder() {
217 return new TestPostReplyBuilder();
220 Collection<PostReply> postReplies =
221 configurationSoneParser.parsePostReplies(
222 postReplyBuilderFactory);
223 assertThat(postReplies, hasSize(2));
224 assertThat(postReplies,
225 containsInAnyOrder(isPostReply("R0", "P0", 1000L, "T0"),
226 isPostReply("R1", "P1", 1001L, "T1")));
229 private void setupPostReplies() {
230 setupPostReply("0", "R0", "P0", 1000L, "T0");
231 setupPostReply("1", "R1", "P1", 1001L, "T1");
232 setupPostReply("2", null, null, 0L, null);
235 private void setupPostReply(String postReplyNumber, String postReplyId,
236 String postId, long time, String text) {
237 setupString("Sone/1/Replies/" + postReplyNumber + "/ID", postReplyId);
238 setupString("Sone/1/Replies/" + postReplyNumber + "/Post/ID", postId);
239 setupLong("Sone/1/Replies/" + postReplyNumber + "/Time", time);
240 setupString("Sone/1/Replies/" + postReplyNumber + "/Text", text);
243 @Test(expected = InvalidPostReplyFound.class)
244 public void missingPostIdIsRecognized() {
245 setupPostReplyWithMissingPostId();
246 configurationSoneParser.parsePostReplies(null);
249 private void setupPostReplyWithMissingPostId() {
250 setupPostReply("0", "R0", null, 1000L, "T0");
253 @Test(expected = InvalidPostReplyFound.class)
254 public void missingPostReplyTimeIsRecognized() {
255 setupPostReplyWithMissingPostReplyTime();
256 configurationSoneParser.parsePostReplies(null);
259 private void setupPostReplyWithMissingPostReplyTime() {
260 setupPostReply("0", "R0", "P0", 0L, "T0");
263 @Test(expected = InvalidPostReplyFound.class)
264 public void missingPostReplyTextIsRecognized() {
265 setupPostReplyWithMissingPostReplyText();
266 configurationSoneParser.parsePostReplies(null);
269 private void setupPostReplyWithMissingPostReplyText() {
270 setupPostReply("0", "R0", "P0", 1000L, null);
274 public void likedPostIdsParsedCorrectly() {
276 Set<String> likedPostIds =
277 configurationSoneParser.parseLikedPostIds();
278 assertThat(likedPostIds, containsInAnyOrder("P1", "P2", "P3"));
281 private void setupLikedPostIds() {
282 setupString("Sone/1/Likes/Post/0/ID", "P1");
283 setupString("Sone/1/Likes/Post/1/ID", "P2");
284 setupString("Sone/1/Likes/Post/2/ID", "P3");
285 setupString("Sone/1/Likes/Post/3/ID", null);
288 private static class TestValue<T> implements Value<T> {
290 private final AtomicReference<T> value = new AtomicReference<T>();
292 public TestValue(T originalValue) {
293 value.set(originalValue);
297 public T getValue() throws ConfigurationException {
302 public T getValue(T defaultValue) {
303 final T realValue = value.get();
304 return (realValue != null) ? realValue : defaultValue;
308 public void setValue(T newValue) throws ConfigurationException {
314 private static class TestPostBuilder implements PostBuilder {
316 private final Post post = mock(Post.class);
317 private String recipientId = null;
320 public PostBuilder copyPost(Post post) throws NullPointerException {
325 public PostBuilder from(String senderId) {
326 final Sone sone = mock(Sone.class);
327 when(sone.getId()).thenReturn(senderId);
328 when(post.getSone()).thenReturn(sone);
333 public PostBuilder randomId() {
334 when(post.getId()).thenReturn(randomUUID().toString());
339 public PostBuilder withId(String id) {
340 when(post.getId()).thenReturn(id);
345 public PostBuilder currentTime() {
346 when(post.getTime()).thenReturn(currentTimeMillis());
351 public PostBuilder withTime(long time) {
352 when(post.getTime()).thenReturn(time);
357 public PostBuilder withText(String text) {
358 when(post.getText()).thenReturn(text);
363 public PostBuilder to(String recipientId) {
364 this.recipientId = recipientId;
369 public Post build() throws IllegalStateException {
370 when(post.getRecipientId()).thenReturn(fromNullable(recipientId));
376 private static class TestPostReplyBuilder implements PostReplyBuilder {
378 private final PostReply postReply = mock(PostReply.class);
381 public PostReplyBuilder to(String postId) {
382 when(postReply.getPostId()).thenReturn(postId);
387 public PostReply build() throws IllegalStateException {
392 public PostReplyBuilder randomId() {
393 when(postReply.getId()).thenReturn(randomUUID().toString());
398 public PostReplyBuilder withId(String id) {
399 when(postReply.getId()).thenReturn(id);
404 public PostReplyBuilder from(String senderId) {
405 Sone sone = mock(Sone.class);
406 when(sone.getId()).thenReturn(senderId);
407 when(postReply.getSone()).thenReturn(sone);
412 public PostReplyBuilder currentTime() {
413 when(postReply.getTime()).thenReturn(currentTimeMillis());
418 public PostReplyBuilder withTime(long time) {
419 when(postReply.getTime()).thenReturn(time);
424 public PostReplyBuilder withText(String text) {
425 when(postReply.getText()).thenReturn(text);