Add tests for parsing mandatory Sones.
[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.of;
21 import static java.util.Arrays.asList;
22 import static java.util.UUID.randomUUID;
23 import static net.pterodactylus.sone.fcp.AbstractSoneCommand.encodeSone;
24 import static net.pterodactylus.sone.fcp.AbstractSoneCommand.encodeString;
25 import static net.pterodactylus.sone.template.SoneAccessor.getNiceName;
26 import static org.hamcrest.CoreMatchers.is;
27 import static org.hamcrest.CoreMatchers.notNullValue;
28 import static org.hamcrest.CoreMatchers.nullValue;
29 import static org.hamcrest.MatcherAssert.assertThat;
30 import static org.mockito.Matchers.eq;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.when;
33
34 import java.util.List;
35
36 import net.pterodactylus.sone.core.Core;
37 import net.pterodactylus.sone.data.PostReply;
38 import net.pterodactylus.sone.data.Profile;
39 import net.pterodactylus.sone.data.Sone;
40 import net.pterodactylus.sone.freenet.SimpleFieldSetBuilder;
41 import net.pterodactylus.sone.freenet.fcp.FcpException;
42
43 import freenet.node.FSParseException;
44 import freenet.support.SimpleFieldSet;
45 import freenet.support.api.Bucket;
46
47 import com.google.common.base.Optional;
48 import org.junit.Test;
49 import org.mockito.Matchers;
50
51 /**
52  * Unit test for {@link AbstractSoneCommand}.
53  *
54  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
55  */
56 public class AbstractSoneCommandTest {
57
58         private final Core core = mock(Core.class);
59         private final AbstractSoneCommand abstractSoneCommand = new AbstractSoneCommand(core) {
60                 @Override
61                 public Response execute(SimpleFieldSet parameters, Bucket data, AccessType accessType) throws FcpException {
62                         return null;
63                 }
64         };
65
66         @Test
67         public void testStringEncoding() {
68                 String testString = prepareStringToBeEncoded();
69
70                 String encodedString = encodeString(testString);
71                 assertThat(encodedString, notNullValue());
72                 assertThat(encodedString.length(), is(testString.length() + 3));
73         }
74
75         private String prepareStringToBeEncoded() {
76                 StringBuilder testString = new StringBuilder();
77                 for (int i = 0; i < 4000; ++i) {
78                         testString.append((char) i);
79                 }
80                 return testString.toString();
81         }
82
83         @Test
84         public void testEncodingASone() throws FSParseException {
85                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
86                 SimpleFieldSet soneFieldSet = encodeSone(sone, "Prefix.", Optional.<Sone>absent());
87                 assertThat(soneFieldSet, notNullValue());
88                 assertThat(soneFieldSet.get("Prefix.Name"), is("test"));
89                 assertThat(soneFieldSet.get("Prefix.NiceName"), is("First M. Last"));
90                 assertThat(soneFieldSet.getLong("Prefix.LastUpdated"), is(sone.getTime()));
91                 assertThat(soneFieldSet.get("Prefix.Followed"), nullValue());
92                 assertThat(soneFieldSet.getInt("Prefix.Field.Count"), is(1));
93                 assertThat(soneFieldSet.get("Prefix.Field.0.Name"), is("Test1"));
94                 assertThat(soneFieldSet.get("Prefix.Field.0.Value"), is("Value1"));
95         }
96
97         @Test
98         public void testEncodingAFollowedSone() throws FSParseException {
99                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
100                 Sone localSone = prepareLocalSoneThatFollowsEverybody();
101                 SimpleFieldSet soneFieldSet = encodeSone(sone, "Prefix.", of(localSone));
102                 assertThat(soneFieldSet, notNullValue());
103                 assertThat(soneFieldSet.get("Prefix.Name"), is("test"));
104                 assertThat(soneFieldSet.get("Prefix.NiceName"), is("First M. Last"));
105                 assertThat(soneFieldSet.getLong("Prefix.LastUpdated"), is(sone.getTime()));
106                 assertThat(soneFieldSet.get("Prefix.Followed"), is("true"));
107                 assertThat(soneFieldSet.getInt("Prefix.Field.Count"), is(1));
108                 assertThat(soneFieldSet.get("Prefix.Field.0.Name"), is("Test1"));
109                 assertThat(soneFieldSet.get("Prefix.Field.0.Value"), is("Value1"));
110         }
111
112         @Test
113         public void testEncodingANotFollowedSone() throws FSParseException {
114                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
115                 Sone localSone = prepareLocalSoneThatFollowsNobody();
116                 SimpleFieldSet soneFieldSet = encodeSone(sone, "Prefix.", of(localSone));
117                 assertThat(soneFieldSet, notNullValue());
118                 assertThat(soneFieldSet.get("Prefix.Name"), is("test"));
119                 assertThat(soneFieldSet.get("Prefix.NiceName"), is("First M. Last"));
120                 assertThat(soneFieldSet.getLong("Prefix.LastUpdated"), is(sone.getTime()));
121                 assertThat(soneFieldSet.get("Prefix.Followed"), is("false"));
122                 assertThat(soneFieldSet.getInt("Prefix.Field.Count"), is(1));
123                 assertThat(soneFieldSet.get("Prefix.Field.0.Name"), is("Test1"));
124                 assertThat(soneFieldSet.get("Prefix.Field.0.Value"), is("Value1"));
125         }
126
127         private Sone prepareLocalSoneThatFollowsEverybody() {
128                 Sone sone = mock(Sone.class);
129                 when(sone.hasFriend(Matchers.<String>any())).thenReturn(true);
130                 return sone;
131         }
132
133         private Sone prepareLocalSoneThatFollowsNobody() {
134                 Sone sone = mock(Sone.class);
135                 when(sone.hasFriend(Matchers.<String>any())).thenReturn(false);
136                 return sone;
137         }
138
139         @Test
140         public void testEncodingMultipleSones() throws FSParseException {
141                 List<Sone> sones = prepareMultipleSones();
142                 SimpleFieldSet sonesFieldSet = AbstractSoneCommand.encodeSones(sones, "Prefix.");
143                 assertThat(sonesFieldSet, notNullValue());
144                 assertThat(sonesFieldSet.getInt("Prefix.Count"), is(sones.size()));
145                 assertThat(sonesFieldSet.get("Prefix.0.ID"), is(sones.get(0).getId()));
146                 assertThat(sonesFieldSet.get("Prefix.0.Name"), is(sones.get(0).getName()));
147                 assertThat(sonesFieldSet.get("Prefix.0.NiceName"), is(getNiceName(sones.get(0))));
148                 assertThat(sonesFieldSet.getLong("Prefix.0.Time"), is(sones.get(0).getTime()));
149                 assertThat(sonesFieldSet.get("Prefix.1.ID"), is(sones.get(1).getId()));
150                 assertThat(sonesFieldSet.get("Prefix.1.Name"), is(sones.get(1).getName()));
151                 assertThat(sonesFieldSet.get("Prefix.1.NiceName"), is(getNiceName(sones.get(1))));
152                 assertThat(sonesFieldSet.getLong("Prefix.1.Time"), is(sones.get(1).getTime()));
153                 assertThat(sonesFieldSet.get("Prefix.2.ID"), is(sones.get(2).getId()));
154                 assertThat(sonesFieldSet.get("Prefix.2.Name"), is(sones.get(2).getName()));
155                 assertThat(sonesFieldSet.get("Prefix.2.NiceName"), is(getNiceName(sones.get(2))));
156                 assertThat(sonesFieldSet.getLong("Prefix.2.Time"), is(sones.get(2).getTime()));
157         }
158
159         private List<Sone> prepareMultipleSones() {
160                 Sone sone1 = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test1", "Alpha", "A.", "First", (long) (Math.random() * Long.MAX_VALUE));
161                 Sone sone2 = createSone("KpoohJSbZGltHHG-YsxKV8ojjS5gwScRv50kl3AkLXg", "Test2", "Beta", "B.", "Second", (long) (Math.random() * Long.MAX_VALUE));
162                 Sone sone3 = createSone("-1Q6LhHvx91C1mSjOS3zznRSNUC4OxoHUbhIgBAyW1U", "Test3", "Gamma", "C.", "Third", (long) (Math.random() * Long.MAX_VALUE));
163                 return asList(sone1, sone2, sone3);
164         }
165
166         private Sone createSone(String id, String name, String firstName, String middleName, String lastName, long time) {
167                 Sone sone = mock(Sone.class);
168                 when(sone.getId()).thenReturn(id);
169                 when(sone.getName()).thenReturn(name);
170                 when(sone.getProfile()).thenReturn(prepareProfile(sone, firstName, middleName, lastName));
171                 when(sone.getTime()).thenReturn(time);
172                 return sone;
173         }
174
175         private Profile prepareProfile(Sone sone, String firstName, String middleName, String lastName) {
176                 Profile profile = new Profile(sone).modify().setFirstName(firstName).setMiddleName(middleName).setLastName(lastName).update();
177                 profile.setField(profile.addField("Test1"), "Value1");
178                 return profile;
179         }
180
181         @Test
182         public void testEncodingReplies() throws FSParseException {
183                 List<PostReply> postReplies = preparePostReplies();
184                 SimpleFieldSet postRepliesFieldSet = AbstractSoneCommand.encodeReplies(postReplies, "Prefix.");
185                 assertThat(postRepliesFieldSet, notNullValue());
186                 assertThat(postRepliesFieldSet.getInt("Prefix.Replies.Count"), is(postReplies.size()));
187                 assertThat(postRepliesFieldSet.get("Prefix.Replies.0.ID"), is(postReplies.get(0).getId()));
188                 assertThat(postRepliesFieldSet.get("Prefix.Replies.0.Sone"), is(postReplies.get(0).getSone().getId()));
189                 assertThat(postRepliesFieldSet.getLong("Prefix.Replies.0.Time"), is(postReplies.get(0).getTime()));
190                 assertThat(postRepliesFieldSet.get("Prefix.Replies.0.Text"), is(postReplies.get(0).getText()));
191                 assertThat(postRepliesFieldSet.get("Prefix.Replies.1.ID"), is(postReplies.get(1).getId()));
192                 assertThat(postRepliesFieldSet.get("Prefix.Replies.1.Sone"), is(postReplies.get(1).getSone().getId()));
193                 assertThat(postRepliesFieldSet.getLong("Prefix.Replies.1.Time"), is(postReplies.get(1).getTime()));
194                 assertThat(postRepliesFieldSet.get("Prefix.Replies.1.Text"), is(postReplies.get(1).getText()));
195                 assertThat(postRepliesFieldSet.get("Prefix.Replies.2.ID"), is(postReplies.get(2).getId()));
196                 assertThat(postRepliesFieldSet.get("Prefix.Replies.2.Sone"), is(postReplies.get(2).getSone().getId()));
197                 assertThat(postRepliesFieldSet.getLong("Prefix.Replies.2.Time"), is(postReplies.get(2).getTime()));
198                 assertThat(postRepliesFieldSet.get("Prefix.Replies.2.Text"), is(postReplies.get(2).getText()));
199         }
200
201         private List<PostReply> preparePostReplies() {
202                 Sone sone1 = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test1", "Alpha", "A.", "First", (long) (Math.random() * Long.MAX_VALUE));
203                 Sone sone2 = createSone("KpoohJSbZGltHHG-YsxKV8ojjS5gwScRv50kl3AkLXg", "Test2", "Beta", "B.", "Second", (long) (Math.random() * Long.MAX_VALUE));
204                 Sone sone3 = createSone("-1Q6LhHvx91C1mSjOS3zznRSNUC4OxoHUbhIgBAyW1U", "Test3", "Gamma", "C.", "Third", (long) (Math.random() * Long.MAX_VALUE));
205                 PostReply postReply1 = createPostReply(sone1, "Text 1");
206                 PostReply postReply2 = createPostReply(sone2, "Text 2");
207                 PostReply postReply3 = createPostReply(sone3, "Text 3");
208                 return asList(postReply1, postReply2, postReply3);
209         }
210
211         private PostReply createPostReply(Sone sone, String text) {
212                 PostReply postReply = mock(PostReply.class);
213                 when(postReply.getId()).thenReturn(randomUUID().toString());
214                 when(postReply.getSone()).thenReturn(sone);
215                 when(postReply.getTime()).thenReturn((long) (Math.random() * Long.MAX_VALUE));
216                 when(postReply.getText()).thenReturn(text);
217                 return postReply;
218         }
219
220         @Test
221         public void testEncodingLikes() throws FSParseException {
222                 List<Sone> likes = prepareMultipleSones();
223                 SimpleFieldSet likesFieldSet = AbstractSoneCommand.encodeLikes(likes, "Prefix.");
224                 assertThat(likesFieldSet, notNullValue());
225                 assertThat(likesFieldSet.getInt("Prefix.Count"), is(likes.size()));
226                 assertThat(likesFieldSet.get("Prefix.0.ID"), is(likes.get(0).getId()));
227                 assertThat(likesFieldSet.get("Prefix.1.ID"), is(likes.get(1).getId()));
228                 assertThat(likesFieldSet.get("Prefix.2.ID"), is(likes.get(2).getId()));
229         }
230
231         @Test
232         public void testParsingAMandatorySone() throws FcpException {
233                 Sone sone = createSone("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E", "Test", "First", "M.", "Last", (long) (Math.random() * Long.MAX_VALUE));
234                 when(core.getSone(eq("jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E"))).thenReturn(of(sone));
235                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
236                 Sone parsedSone = abstractSoneCommand.getMandatorySone(soneFieldSet, "Sone");
237                 assertThat(parsedSone, notNullValue());
238                 assertThat(parsedSone, is(sone));
239         }
240
241         @Test(expected = FcpException.class)
242         public void testParsingANonExistingMandatorySoneCausesAnError() throws FcpException {
243                 when(core.getSone(Matchers.<String>any())).thenReturn(Optional.<Sone>absent());
244                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
245                 abstractSoneCommand.getMandatorySone(soneFieldSet, "Sone");
246         }
247
248         @Test(expected = FcpException.class)
249         public void testParsingAMandatorySoneFromANonExistingFieldCausesAnError() throws FcpException {
250                 when(core.getSone(Matchers.<String>any())).thenReturn(Optional.<Sone>absent());
251                 SimpleFieldSet soneFieldSet = new SimpleFieldSetBuilder().put("Sone", "jXH8d-eFdm14R69WyaCgQoSjaY0jl-Ut6etlXjK0e6E").get();
252                 abstractSoneCommand.getMandatorySone(soneFieldSet, "RealSone");
253         }
254
255 }