Filter future replies when encoding single posts.
[Sone.git] / src / test / java / net / pterodactylus / sone / fcp / AbstractSoneCommandTest.java
1 /*
2  * Sone - AbstractSoneCommandTest.java - Copyright © 2013 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.sone.fcp;
19
20 import static com.google.common.base.Optional.fromNullable;
21 import static com.google.common.base.Optional.of;
22 import static java.util.Arrays.asList;
23 import static java.util.UUID.randomUUID;
24 import static net.pterodactylus.sone.fcp.AbstractSoneCommand.encodeSone;
25 import static net.pterodactylus.sone.fcp.AbstractSoneCommand.encodeString;
26 import static net.pterodactylus.sone.template.SoneAccessor.getNiceName;
27 import static org.hamcrest.CoreMatchers.is;
28 import static org.hamcrest.CoreMatchers.notNullValue;
29 import static org.hamcrest.CoreMatchers.nullValue;
30 import static org.hamcrest.MatcherAssert.assertThat;
31 import static org.mockito.Matchers.eq;
32 import static org.mockito.Mockito.mock;
33 import static org.mockito.Mockito.when;
34
35 import java.util.List;
36
37 import net.pterodactylus.sone.core.Core;
38 import net.pterodactylus.sone.data.Post;
39 import net.pterodactylus.sone.data.PostReply;
40 import net.pterodactylus.sone.data.Profile;
41 import net.pterodactylus.sone.data.Sone;
42 import net.pterodactylus.sone.database.Database;
43 import net.pterodactylus.sone.freenet.SimpleFieldSetBuilder;
44 import net.pterodactylus.sone.freenet.fcp.FcpException;
45
46 import freenet.node.FSParseException;
47 import freenet.support.SimpleFieldSet;
48 import freenet.support.api.Bucket;
49
50 import com.google.common.base.Optional;
51 import org.junit.Test;
52 import org.mockito.Matchers;
53
54 /**
55  * Unit test for {@link AbstractSoneCommand}.
56  *
57  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
58  */
59 public class AbstractSoneCommandTest {
60
61         private final Core core = mock(Core.class);
62         private final Database database = mock(Database.class);
63         private final AbstractSoneCommand abstractSoneCommand = new AbstractSoneCommand(core) {
64                 @Override
65                 public Response execute(SimpleFieldSet parameters, Bucket data, AccessType accessType) throws FcpException {
66                         return null;
67                 }
68         };
69
70         public AbstractSoneCommandTest() {
71                 when(core.getDatabase()).thenReturn(database);
72         }
73
74         @Test
75         public void testStringEncoding() {
76                 String testString = prepareStringToBeEncoded();
77
78                 String encodedString = encodeString(testString);
79                 assertThat(encodedString, notNullValue());
80                 assertThat(encodedString.length(), is(testString.length() + 3));
81         }
82
83         private String prepareStringToBeEncoded() {
84                 StringBuilder testString = new StringBuilder();
85                 for (int i = 0; i < 4000; ++i) {
86                         testString.append((char) i);
87                 }
88                 return testString.toString();
89         }
90
91         @Test
92         public void testEncodingASone() throws FSParseException {
93                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
94                 SimpleFieldSet soneFieldSet = encodeSone(sone, "Prefix.", Optional.<Sone>absent());
95                 assertThat(soneFieldSet, notNullValue());
96                 assertThat(soneFieldSet.get("Prefix.Name"), is("test"));
97                 assertThat(soneFieldSet.get("Prefix.NiceName"), is("First M. Last"));
98                 assertThat(soneFieldSet.getLong("Prefix.LastUpdated"), is(sone.getTime()));
99                 assertThat(soneFieldSet.get("Prefix.Followed"), nullValue());
100                 assertThat(soneFieldSet.getInt("Prefix.Field.Count"), is(1));
101                 assertThat(soneFieldSet.get("Prefix.Field.0.Name"), is("Test1"));
102                 assertThat(soneFieldSet.get("Prefix.Field.0.Value"), is("Value1"));
103         }
104
105         @Test
106         public void testEncodingAFollowedSone() throws FSParseException {
107                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
108                 Sone localSone = prepareLocalSoneThatFollowsEverybody();
109                 SimpleFieldSet soneFieldSet = encodeSone(sone, "Prefix.", of(localSone));
110                 assertThat(soneFieldSet, notNullValue());
111                 assertThat(soneFieldSet.get("Prefix.Name"), is("test"));
112                 assertThat(soneFieldSet.get("Prefix.NiceName"), is("First M. Last"));
113                 assertThat(soneFieldSet.getLong("Prefix.LastUpdated"), is(sone.getTime()));
114                 assertThat(soneFieldSet.get("Prefix.Followed"), is("true"));
115                 assertThat(soneFieldSet.getInt("Prefix.Field.Count"), is(1));
116                 assertThat(soneFieldSet.get("Prefix.Field.0.Name"), is("Test1"));
117                 assertThat(soneFieldSet.get("Prefix.Field.0.Value"), is("Value1"));
118         }
119
120         @Test
121         public void testEncodingANotFollowedSone() throws FSParseException {
122                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
123                 Sone localSone = prepareLocalSoneThatFollowsNobody();
124                 SimpleFieldSet soneFieldSet = encodeSone(sone, "Prefix.", of(localSone));
125                 assertThat(soneFieldSet, notNullValue());
126                 assertThat(soneFieldSet.get("Prefix.Name"), is("test"));
127                 assertThat(soneFieldSet.get("Prefix.NiceName"), is("First M. Last"));
128                 assertThat(soneFieldSet.getLong("Prefix.LastUpdated"), is(sone.getTime()));
129                 assertThat(soneFieldSet.get("Prefix.Followed"), is("false"));
130                 assertThat(soneFieldSet.getInt("Prefix.Field.Count"), is(1));
131                 assertThat(soneFieldSet.get("Prefix.Field.0.Name"), is("Test1"));
132                 assertThat(soneFieldSet.get("Prefix.Field.0.Value"), is("Value1"));
133         }
134
135         private Sone prepareLocalSoneThatFollowsEverybody() {
136                 Sone sone = mock(Sone.class);
137                 when(sone.hasFriend(Matchers.<String>any())).thenReturn(true);
138                 return sone;
139         }
140
141         private Sone prepareLocalSoneThatFollowsNobody() {
142                 Sone sone = mock(Sone.class);
143                 when(sone.hasFriend(Matchers.<String>any())).thenReturn(false);
144                 return sone;
145         }
146
147         @Test
148         public void testEncodingMultipleSones() throws FSParseException {
149                 List<Sone> sones = prepareMultipleSones();
150                 SimpleFieldSet sonesFieldSet = AbstractSoneCommand.encodeSones(sones, "Prefix.");
151                 assertThat(sonesFieldSet, notNullValue());
152                 assertThat(sonesFieldSet.getInt("Prefix.Count"), is(sones.size()));
153                 assertThat(sonesFieldSet.get("Prefix.0.ID"), is(sones.get(0).getId()));
154                 assertThat(sonesFieldSet.get("Prefix.0.Name"), is(sones.get(0).getName()));
155                 assertThat(sonesFieldSet.get("Prefix.0.NiceName"), is(getNiceName(sones.get(0))));
156                 assertThat(sonesFieldSet.getLong("Prefix.0.Time"), is(sones.get(0).getTime()));
157                 assertThat(sonesFieldSet.get("Prefix.1.ID"), is(sones.get(1).getId()));
158                 assertThat(sonesFieldSet.get("Prefix.1.Name"), is(sones.get(1).getName()));
159                 assertThat(sonesFieldSet.get("Prefix.1.NiceName"), is(getNiceName(sones.get(1))));
160                 assertThat(sonesFieldSet.getLong("Prefix.1.Time"), is(sones.get(1).getTime()));
161                 assertThat(sonesFieldSet.get("Prefix.2.ID"), is(sones.get(2).getId()));
162                 assertThat(sonesFieldSet.get("Prefix.2.Name"), is(sones.get(2).getName()));
163                 assertThat(sonesFieldSet.get("Prefix.2.NiceName"), is(getNiceName(sones.get(2))));
164                 assertThat(sonesFieldSet.getLong("Prefix.2.Time"), is(sones.get(2).getTime()));
165         }
166
167         private List<Sone> prepareMultipleSones() {
168                 Sone sone1 = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test1", "Alpha", "A.", "First", (long) (Math.random() * Long.MAX_VALUE));
169                 Sone sone2 = createSone("KpoohJSbZGltHHG-YsxKV8ojjS5gwScRv50kl3AkLXg", "Test2", "Beta", "B.", "Second", (long) (Math.random() * Long.MAX_VALUE));
170                 Sone sone3 = createSone("-1Q6LhHvx91C1mSjOS3zznRSNUC4OxoHUbhIgBAyW1U", "Test3", "Gamma", "C.", "Third", (long) (Math.random() * Long.MAX_VALUE));
171                 return asList(sone1, sone2, sone3);
172         }
173
174         private Sone createSone(String id, String name, String firstName, String middleName, String lastName, long time) {
175                 Sone sone = mock(Sone.class);
176                 when(sone.getId()).thenReturn(id);
177                 when(sone.getName()).thenReturn(name);
178                 when(sone.getProfile()).thenReturn(prepareProfile(sone, firstName, middleName, lastName));
179                 when(sone.getTime()).thenReturn(time);
180                 return sone;
181         }
182
183         private Sone createLocalSone(String id, String name, String firstName, String middleName, String lastName, long time) {
184                 Sone sone = mock(Sone.class);
185                 when(sone.getId()).thenReturn(id);
186                 when(sone.getName()).thenReturn(name);
187                 when(sone.getProfile()).thenReturn(prepareProfile(sone, firstName, middleName, lastName));
188                 when(sone.getTime()).thenReturn(time);
189                 when(sone.isLocal()).thenReturn(true);
190                 return sone;
191         }
192
193         private Profile prepareProfile(Sone sone, String firstName, String middleName, String lastName) {
194                 Profile profile = new Profile(sone).modify().setFirstName(firstName).setMiddleName(middleName).setLastName(lastName).update();
195                 profile.setField(profile.addField("Test1"), "Value1");
196                 return profile;
197         }
198
199         @Test
200         public void testEncodingReplies() throws FSParseException {
201                 List<PostReply> postReplies = preparePostReplies();
202                 SimpleFieldSet postRepliesFieldSet = AbstractSoneCommand.encodeReplies(postReplies, "Prefix.");
203                 assertThat(postRepliesFieldSet, notNullValue());
204                 assertThat(postRepliesFieldSet.getInt("Prefix.Replies.Count"), is(postReplies.size()));
205                 assertThat(postRepliesFieldSet.get("Prefix.Replies.0.ID"), is(postReplies.get(0).getId()));
206                 assertThat(postRepliesFieldSet.get("Prefix.Replies.0.Sone"), is(postReplies.get(0).getSone().getId()));
207                 assertThat(postRepliesFieldSet.getLong("Prefix.Replies.0.Time"), is(postReplies.get(0).getTime()));
208                 assertThat(postRepliesFieldSet.get("Prefix.Replies.0.Text"), is(postReplies.get(0).getText()));
209                 assertThat(postRepliesFieldSet.get("Prefix.Replies.1.ID"), is(postReplies.get(1).getId()));
210                 assertThat(postRepliesFieldSet.get("Prefix.Replies.1.Sone"), is(postReplies.get(1).getSone().getId()));
211                 assertThat(postRepliesFieldSet.getLong("Prefix.Replies.1.Time"), is(postReplies.get(1).getTime()));
212                 assertThat(postRepliesFieldSet.get("Prefix.Replies.1.Text"), is(postReplies.get(1).getText()));
213                 assertThat(postRepliesFieldSet.get("Prefix.Replies.2.ID"), is(postReplies.get(2).getId()));
214                 assertThat(postRepliesFieldSet.get("Prefix.Replies.2.Sone"), is(postReplies.get(2).getSone().getId()));
215                 assertThat(postRepliesFieldSet.getLong("Prefix.Replies.2.Time"), is(postReplies.get(2).getTime()));
216                 assertThat(postRepliesFieldSet.get("Prefix.Replies.2.Text"), is(postReplies.get(2).getText()));
217         }
218
219         private List<PostReply> preparePostReplies() {
220                 Sone sone1 = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test1", "Alpha", "A.", "First", (long) (Math.random() * Long.MAX_VALUE));
221                 Sone sone2 = createSone("KpoohJSbZGltHHG-YsxKV8ojjS5gwScRv50kl3AkLXg", "Test2", "Beta", "B.", "Second", (long) (Math.random() * Long.MAX_VALUE));
222                 Sone sone3 = createSone("-1Q6LhHvx91C1mSjOS3zznRSNUC4OxoHUbhIgBAyW1U", "Test3", "Gamma", "C.", "Third", (long) (Math.random() * Long.MAX_VALUE));
223                 PostReply postReply1 = createPostReply(sone1, "Text 1");
224                 PostReply postReply2 = createPostReply(sone2, "Text 2");
225                 PostReply postReply3 = createPostReply(sone3, "Text 3");
226                 return asList(postReply1, postReply2, postReply3);
227         }
228
229         private PostReply createPostReply(Sone sone, String text) {
230                 PostReply postReply = mock(PostReply.class);
231                 when(postReply.getId()).thenReturn(randomUUID().toString());
232                 when(postReply.getSone()).thenReturn(sone);
233                 when(postReply.getTime()).thenReturn(System.currentTimeMillis());
234                 when(postReply.getText()).thenReturn(text);
235                 return postReply;
236         }
237
238         private PostReply createFuturePostReply(Sone sone, String text) {
239                 PostReply postReply = createPostReply(sone, text);
240                 when(postReply.getTime()).thenReturn(System.currentTimeMillis() + 86400000);
241                 return postReply;
242         }
243
244         @Test
245         public void testEncodingLikes() throws FSParseException {
246                 List<Sone> likes = prepareMultipleSones();
247                 SimpleFieldSet likesFieldSet = AbstractSoneCommand.encodeLikes(likes, "Prefix.");
248                 assertThat(likesFieldSet, notNullValue());
249                 assertThat(likesFieldSet.getInt("Prefix.Count"), is(likes.size()));
250                 assertThat(likesFieldSet.get("Prefix.0.ID"), is(likes.get(0).getId()));
251                 assertThat(likesFieldSet.get("Prefix.1.ID"), is(likes.get(1).getId()));
252                 assertThat(likesFieldSet.get("Prefix.2.ID"), is(likes.get(2).getId()));
253         }
254
255         @Test
256         public void testParsingAMandatorySone() throws FcpException {
257                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
258                 when(core.getSone(eq("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E"))).thenReturn(of(sone));
259                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
260                 Sone parsedSone = abstractSoneCommand.getMandatorySone(soneFieldSet, "Sone");
261                 assertThat(parsedSone, notNullValue());
262                 assertThat(parsedSone, is(sone));
263         }
264
265         @Test(expected = FcpException.class)
266         public void testParsingANonExistingMandatorySoneCausesAnError() throws FcpException {
267                 when(core.getSone(Matchers.<String>any())).thenReturn(Optional.<Sone>absent());
268                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
269                 abstractSoneCommand.getMandatorySone(soneFieldSet, "Sone");
270         }
271
272         @Test(expected = FcpException.class)
273         public void testParsingAMandatorySoneFromANonExistingFieldCausesAnError() throws FcpException {
274                 when(core.getSone(Matchers.<String>any())).thenReturn(Optional.<Sone>absent());
275                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
276                 abstractSoneCommand.getMandatorySone(soneFieldSet, "RealSone");
277         }
278
279         @Test
280         public void testParsingAMandatoryLocalSone() throws FcpException {
281                 Sone sone = createLocalSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
282                 when(core.getSone(eq("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E"))).thenReturn(of(sone));
283                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
284                 Sone parsedSone = abstractSoneCommand.getMandatoryLocalSone(soneFieldSet, "Sone");
285                 assertThat(parsedSone, notNullValue());
286                 assertThat(parsedSone, is(sone));
287                 assertThat(parsedSone.isLocal(), is(true));
288         }
289
290         @Test(expected = FcpException.class)
291         public void testParsingANonLocalSoneAsMandatoryLocalSoneCausesAnError() throws FcpException {
292                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
293                 when(core.getSone(eq("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E"))).thenReturn(of(sone));
294                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
295                 abstractSoneCommand.getMandatoryLocalSone(soneFieldSet, "Sone");
296         }
297
298         @Test(expected = FcpException.class)
299         public void testParsingAMandatoryLocalSoneFromANonExistingFieldCausesAnError() throws FcpException {
300                 when(core.getSone(Matchers.<String>any())).thenReturn(Optional.<Sone>absent());
301                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
302                 abstractSoneCommand.getMandatoryLocalSone(soneFieldSet, "RealSone");
303         }
304
305         @Test
306         public void testParsingAnExistingOptionalSone() throws FcpException {
307                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
308                 when(core.getSone(eq("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E"))).thenReturn(of(sone));
309                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
310                 Optional<Sone> parsedSone = abstractSoneCommand.getOptionalSone(soneFieldSet, "Sone");
311                 assertThat(parsedSone, notNullValue());
312                 assertThat(parsedSone.isPresent(), is(true));
313                 assertThat(parsedSone.get(), is(sone));
314         }
315
316         @Test
317         public void testParsingANonExistingOptionalSone() throws FcpException {
318                 when(core.getSone(Matchers.<String>any())).thenReturn(Optional.<Sone>absent());
319                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
320                 Optional<Sone> parsedSone = abstractSoneCommand.getOptionalSone(soneFieldSet, "Sone");
321                 assertThat(parsedSone, notNullValue());
322                 assertThat(parsedSone.isPresent(), is(false));
323         }
324
325         @Test(expected = FcpException.class)
326         public void testParsingAnOptionalSoneFromANonExistingFieldCausesAnError() throws FcpException {
327                 when(core.getSone(Matchers.<String>any())).thenReturn(Optional.<Sone>absent());
328                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
329                 abstractSoneCommand.getOptionalSone(soneFieldSet, "RealSone");
330         }
331
332         @Test
333         public void testParsingAPost() throws FcpException {
334                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
335                 Post post = createPost(sone, null, (long) (Math.random() * Long.MAX_VALUE), "Some Text.");
336                 when(database.getPost(eq(post.getId()))).thenReturn(of(post));
337                 SimpleFieldSet postFieldSet = new SimpleFieldSetBuilder().put("Post", post.getId()).get();
338                 Post parsedPost = abstractSoneCommand.getPost(postFieldSet, "Post");
339                 assertThat(parsedPost, notNullValue());
340                 assertThat(parsedPost, is(post));
341         }
342
343         private Post createPost(Sone sone, String recipient, long time, String text) {
344                 Post post = mock(Post.class);
345                 when(post.getId()).thenReturn(randomUUID().toString());
346                 when(post.getSone()).thenReturn(sone);
347                 when(post.getRecipientId()).thenReturn(fromNullable(recipient));
348                 when(post.getTime()).thenReturn(time);
349                 when(post.getText()).thenReturn(text);
350                 return post;
351         }
352
353         @Test(expected = FcpException.class)
354         public void testThatTryingToParseANonExistingPostCausesAnError() throws FcpException {
355                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
356                 Post post = createPost(sone, null, (long) (Math.random() * Long.MAX_VALUE), "Some Text.");
357                 when(database.getPost(Matchers.<String>any())).thenReturn(Optional.<Post>absent());
358                 SimpleFieldSet postFieldSet = new SimpleFieldSetBuilder().put("Post", post.getId()).get();
359                 abstractSoneCommand.getPost(postFieldSet, "Post");
360         }
361
362         @Test(expected = FcpException.class)
363         public void testThatTryingToParseAPostFromANonExistingFieldCausesAnError() throws FcpException {
364                 SimpleFieldSet postFieldSet = new SimpleFieldSetBuilder().get();
365                 abstractSoneCommand.getPost(postFieldSet, "Post");
366         }
367
368         @Test
369         public void testParsingAReply() throws FcpException {
370                 PostReply reply = createPostReply();
371                 when(database.getPostReply(eq(reply.getId()))).thenReturn(of(reply));
372                 SimpleFieldSet replyFieldSet = new SimpleFieldSetBuilder().put("Reply", reply.getId()).get();
373                 PostReply parsedReply = abstractSoneCommand.getReply(replyFieldSet, "Reply");
374                 assertThat(parsedReply, notNullValue());
375                 assertThat(parsedReply, is(reply));
376         }
377
378         private PostReply createPostReply() {
379                 PostReply postReply = mock(PostReply.class);
380                 when(postReply.getId()).thenReturn(randomUUID().toString());
381                 return postReply;
382         }
383
384         @Test(expected = FcpException.class)
385         public void testParsingANonExistingReply() throws FcpException {
386                 PostReply reply = createPostReply();
387                 when(database.getPostReply(Matchers.<String>any())).thenReturn(Optional.<PostReply>absent());
388                 SimpleFieldSet replyFieldSet = new SimpleFieldSetBuilder().put("Reply", reply.getId()).get();
389                 abstractSoneCommand.getReply(replyFieldSet, "Reply");
390         }
391
392         @Test(expected = FcpException.class)
393         public void testParsingAReplyFromANonExistingField() throws FcpException {
394                 SimpleFieldSet replyFieldSet = new SimpleFieldSetBuilder().get();
395                 abstractSoneCommand.getReply(replyFieldSet, "Reply");
396         }
397
398         @Test
399         public void testEncodingAPostWithoutRecipientAndReplies() throws FSParseException {
400                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
401                 Post post = createPost(sone, null, (long) (Math.random() * Long.MAX_VALUE), "Some Text.");
402                 SimpleFieldSet postFieldSet = abstractSoneCommand.encodePost(post, "Post.");
403                 assertThat(postFieldSet, notNullValue());
404                 assertThat(postFieldSet.get("Post.ID"), is(post.getId()));
405                 assertThat(postFieldSet.get("Post.Sone"), is(sone.getId()));
406                 assertThat(postFieldSet.get("Post.Recipient"), nullValue());
407                 assertThat(postFieldSet.getLong("Post.Time"), is(post.getTime()));
408                 assertThat(postFieldSet.get("Post.Text"), is(post.getText()));
409         }
410
411         @Test
412         public void testEncodingAPostWithRecipientWithoutReplies() throws FSParseException {
413                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
414                 Post post = createPost(sone, "KpoohJSbZGltHHG-YsxKV8ojjS5gwScRv50kl3AkLXg", (long) (Math.random() * Long.MAX_VALUE), "Some Text.");
415                 SimpleFieldSet postFieldSet = abstractSoneCommand.encodePost(post, "Post.");
416                 assertThat(postFieldSet, notNullValue());
417                 assertThat(postFieldSet.get("Post.ID"), is(post.getId()));
418                 assertThat(postFieldSet.get("Post.Sone"), is(sone.getId()));
419                 assertThat(postFieldSet.get("Post.Recipient"), is("KpoohJSbZGltHHG-YsxKV8ojjS5gwScRv50kl3AkLXg"));
420                 assertThat(postFieldSet.getLong("Post.Time"), is(post.getTime()));
421                 assertThat(postFieldSet.get("Post.Text"), is(post.getText()));
422         }
423
424         @Test
425         public void testEncodingAPostWithoutRecipientWithReplies() throws FSParseException {
426                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
427                 Post post = createPost(sone, null, (long) (Math.random() * Long.MAX_VALUE), "Some Text.");
428                 PostReply postReply = createPostReply(sone, "Reply.");
429                 when(post.getReplies()).thenReturn(asList(postReply));
430                 SimpleFieldSet postFieldSet = abstractSoneCommand.encodePostWithReplies(post, "Post.");
431                 assertThat(postFieldSet, notNullValue());
432                 assertThat(postFieldSet.get("Post.ID"), is(post.getId()));
433                 assertThat(postFieldSet.get("Post.Sone"), is(sone.getId()));
434                 assertThat(postFieldSet.get("Post.Recipient"), nullValue());
435                 assertThat(postFieldSet.getLong("Post.Time"), is(post.getTime()));
436                 assertThat(postFieldSet.get("Post.Text"), is(post.getText()));
437                 assertThat(postFieldSet.getInt("Post.Replies.Count"), is(1));
438                 assertThat(postFieldSet.get("Post.Replies.0.ID"), is(postReply.getId()));
439                 assertThat(postFieldSet.get("Post.Replies.0.Sone"), is(postReply.getSone().getId()));
440                 assertThat(postFieldSet.getLong("Post.Replies.0.Time"), is(postReply.getTime()));
441                 assertThat(postFieldSet.get("Post.Replies.0.Text"), is(postReply.getText()));
442         }
443
444         @Test
445         public void testEncodingAPostWithoutRecipientWithFutureReplies() throws FSParseException {
446                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
447                 Post post = createPost(sone, null, (long) (Math.random() * Long.MAX_VALUE), "Some Text.");
448                 PostReply postReply = createFuturePostReply(sone, "Reply.");
449                 when(post.getReplies()).thenReturn(asList(postReply));
450                 SimpleFieldSet postFieldSet = abstractSoneCommand.encodePostWithReplies(post, "Post.");
451                 assertThat(postFieldSet, notNullValue());
452                 assertThat(postFieldSet.get("Post.ID"), is(post.getId()));
453                 assertThat(postFieldSet.get("Post.Sone"), is(sone.getId()));
454                 assertThat(postFieldSet.get("Post.Recipient"), nullValue());
455                 assertThat(postFieldSet.getLong("Post.Time"), is(post.getTime()));
456                 assertThat(postFieldSet.get("Post.Text"), is(post.getText()));
457                 assertThat(postFieldSet.getInt("Post.Replies.Count"), is(0));
458                 assertThat(postFieldSet.get("Post.Replies.0.ID"), nullValue());
459                 assertThat(postFieldSet.get("Post.Replies.0.Sone"), nullValue());
460                 assertThat(postFieldSet.get("Post.Replies.0.Time"), nullValue());
461                 assertThat(postFieldSet.get("Post.Replies.0.Text"), nullValue());
462         }
463
464         @Test
465         public void testEncodingAPostWithRecipientAndReplies() throws FSParseException {
466                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
467                 Post post = createPost(sone, "KpoohJSbZGltHHG-YsxKV8ojjS5gwScRv50kl3AkLXg", (long) (Math.random() * Long.MAX_VALUE), "Some Text.");
468                 PostReply postReply = createPostReply(sone, "Reply.");
469                 when(post.getReplies()).thenReturn(asList(postReply));
470                 SimpleFieldSet postFieldSet = abstractSoneCommand.encodePostWithReplies(post, "Post.");
471                 assertThat(postFieldSet, notNullValue());
472                 assertThat(postFieldSet.get("Post.ID"), is(post.getId()));
473                 assertThat(postFieldSet.get("Post.Sone"), is(sone.getId()));
474                 assertThat(postFieldSet.get("Post.Recipient"), is("KpoohJSbZGltHHG-YsxKV8ojjS5gwScRv50kl3AkLXg"));
475                 assertThat(postFieldSet.getLong("Post.Time"), is(post.getTime()));
476                 assertThat(postFieldSet.get("Post.Text"), is(post.getText()));
477                 assertThat(postFieldSet.getInt("Post.Replies.Count"), is(1));
478                 assertThat(postFieldSet.get("Post.Replies.0.ID"), is(postReply.getId()));
479                 assertThat(postFieldSet.get("Post.Replies.0.Sone"), is(postReply.getSone().getId()));
480                 assertThat(postFieldSet.getLong("Post.Replies.0.Time"), is(postReply.getTime()));
481                 assertThat(postFieldSet.get("Post.Replies.0.Text"), is(postReply.getText()));
482         }
483
484 }