1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shindig.social.opensocial.service;
19
20 import org.apache.shindig.common.testing.FakeGadgetToken;
21 import org.apache.shindig.common.util.ImmediateFuture;
22 import org.apache.shindig.social.core.util.BeanAtomConverter;
23 import org.apache.shindig.social.core.util.BeanJsonConverter;
24 import org.apache.shindig.social.core.util.BeanXStreamAtomConverter;
25 import org.apache.shindig.social.core.util.BeanXStreamConverter;
26 import org.apache.shindig.social.core.util.BeanXmlConverter;
27
28 import com.google.common.collect.ImmutableMap;
29 import com.google.common.collect.Maps;
30
31 import com.google.inject.Provider;
32
33 import junit.framework.TestCase;
34 import org.easymock.classextension.EasyMock;
35 import org.json.JSONArray;
36 import org.json.JSONObject;
37
38 import java.io.ByteArrayInputStream;
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.io.PrintWriter;
42 import java.util.concurrent.Future;
43 import javax.servlet.ServletInputStream;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpServletResponse;
46
47 /***
48 *
49 */
50 public class JsonRpcServletTest extends TestCase {
51
52 private static final FakeGadgetToken FAKE_GADGET_TOKEN = new FakeGadgetToken()
53 .setOwnerId("john.doe").setViewerId("john.doe");
54
55 private HttpServletRequest req;
56 private HttpServletResponse res;
57 private JsonRpcServlet servlet;
58
59 private PersonHandler peopleHandler;
60 private ActivityHandler activityHandler;
61 private AppDataHandler appDataHandler;
62
63 private BeanJsonConverter jsonConverter;
64 private BeanXStreamConverter xmlConverter;
65
66 @Override protected void setUp() throws Exception {
67 servlet = new JsonRpcServlet();
68 req = EasyMock.createMock(HttpServletRequest.class);
69 res = EasyMock.createMock(HttpServletResponse.class);
70 jsonConverter = EasyMock.createMock(BeanJsonConverter.class);
71 xmlConverter = EasyMock.createMock(BeanXStreamConverter.class);
72 BeanXStreamAtomConverter atomConverter = EasyMock.createMock(BeanXStreamAtomConverter.class);
73
74 peopleHandler = EasyMock.createMock(PersonHandler.class);
75 activityHandler = EasyMock.createMock(ActivityHandler.class);
76 appDataHandler = EasyMock.createMock(AppDataHandler.class);
77
78 HandlerDispatcher dispatcher = new StandardHandlerDispatcher(constant(peopleHandler),
79 constant(activityHandler), constant(appDataHandler));
80 servlet.setHandlerDispatcher(dispatcher);
81
82 servlet.setBeanConverters(jsonConverter, xmlConverter, atomConverter);
83 }
84
85
86 private static <T> Provider<T> constant(final T value) {
87 return new Provider<T>() {
88 public T get() {
89 return value;
90 }
91 };
92 }
93
94 public void testPeopleMethodRecognition() throws Exception {
95 verifyHandlerWasFoundForMethod("{method:people.get,id:id,params:{userId:5,groupId:@self}}",
96 peopleHandler);
97 }
98
99 public void testActivitiesMethodRecognition() throws Exception {
100 verifyHandlerWasFoundForMethod("{method:activities.get,id:id,params:{userId:5,groupId:@self}}",
101 activityHandler);
102 }
103
104 public void testAppDataMethodRecognition() throws Exception {
105 verifyHandlerWasFoundForMethod("{method:appdata.get,id:id,params:{userId:5,groupId:@self}}",
106 appDataHandler);
107 }
108
109 public void testInvalidService() throws Exception {
110 String json = "{method:junk.get,id:id,params:{userId:5,groupId:@self}}";
111 setupRequest(json);
112
113 JSONObject err = new JSONObject(
114 "{id:id,error:{message:'notImplemented: The service junk is not implemented',code:501}}");
115
116 PrintWriter writerMock = EasyMock.createMock(PrintWriter.class);
117 EasyMock.expect(res.getWriter()).andReturn(writerMock);
118 writerMock.write(EasyMock.eq(err.toString()));
119 EasyMock.expectLastCall();
120
121 EasyMock.replay(req, res, jsonConverter, writerMock);
122 servlet.service(req, res);
123 EasyMock.verify(req, res, jsonConverter, writerMock);
124 EasyMock.reset(req, res, jsonConverter);
125 }
126
127
128 /***
129 * Tests a data handler that returns a failed Future.
130 * @throws Exception on failure
131 */
132 public void testFailedRequest() throws Exception {
133 setupRequest("{id:id,method:appdata.get}");
134 EasyMock.expect(appDataHandler.handleItem(EasyMock.isA(RpcRequestItem.class)));
135 EasyMock.expectLastCall().andReturn(
136 ImmediateFuture.errorInstance(new RuntimeException("FAILED")));
137
138 JSONObject err = new JSONObject(
139 "{id:id,error:{message:'internalError: FAILED',code:500}}");
140
141 PrintWriter writerMock = EasyMock.createMock(PrintWriter.class);
142 EasyMock.expect(res.getWriter()).andReturn(writerMock);
143 writerMock.write(EasyMock.eq(err.toString()));
144 EasyMock.expectLastCall();
145
146 EasyMock.replay(req, res, appDataHandler, jsonConverter, writerMock);
147 servlet.service(req, res);
148 EasyMock.verify(req, res, appDataHandler, jsonConverter, writerMock);
149 EasyMock.reset(req, res, appDataHandler, jsonConverter);
150 }
151
152 private void verifyHandlerWasFoundForMethod(String json, DataRequestHandler handler)
153 throws Exception {
154 setupRequest(json);
155
156 String resultObject = "my lovely json";
157
158 EasyMock.expect(handler.handleItem(EasyMock.isA(RequestItem.class)));
159 EasyMock.expectLastCall().andReturn(ImmediateFuture.newInstance(resultObject));
160
161 EasyMock.expect(jsonConverter.convertToJson(resultObject))
162 .andReturn(new JSONObject(ImmutableMap.of("foo", "bar")));
163
164 JSONObject result = new JSONObject();
165 result.put("id", "id");
166 result.put("data", ImmutableMap.of("foo", "bar"));
167 PrintWriter writerMock = EasyMock.createMock(PrintWriter.class);
168 EasyMock.expect(res.getWriter()).andReturn(writerMock);
169 writerMock.write(EasyMock.eq(result.toString()));
170 EasyMock.expectLastCall();
171
172 EasyMock.replay(req, res, handler, jsonConverter, writerMock);
173 servlet.service(req, res);
174 EasyMock.verify(req, res, handler, jsonConverter, writerMock);
175 EasyMock.reset(req, res, handler, jsonConverter);
176 }
177
178 public void testBasicBatch() throws Exception {
179 String batchJson =
180 "[{method:people.get,id:'1'},{method:activities.get,id:'2'}]";
181 setupRequest(batchJson);
182
183 String resultObject = "my lovely json";
184 Future<?> responseItemFuture = ImmediateFuture.newInstance(resultObject);
185 EasyMock.expect(peopleHandler.handleItem(EasyMock.isA(RequestItem.class)));
186 EasyMock.expectLastCall().andReturn(responseItemFuture);
187 EasyMock.expect(activityHandler.handleItem(EasyMock.isA(RequestItem.class)));
188 EasyMock.expectLastCall().andReturn(responseItemFuture);
189
190 EasyMock.expect(jsonConverter.convertToJson(resultObject))
191 .andStubReturn(new JSONObject(ImmutableMap.of("foo", "bar")));
192
193 JSONArray result = new JSONArray("[{id:'1',data:{foo:'bar'}}," + "{id:'2',data:{foo:'bar'}}]");
194 PrintWriter writerMock = EasyMock.createMock(PrintWriter.class);
195 EasyMock.expect(res.getWriter()).andReturn(writerMock);
196 writerMock.write(EasyMock.eq(result.toString()));
197 EasyMock.expectLastCall();
198
199 EasyMock.replay(req, res, peopleHandler, activityHandler, jsonConverter, writerMock);
200 servlet.service(req, res);
201 EasyMock.verify(req, res, peopleHandler, activityHandler, jsonConverter, writerMock);
202 EasyMock.reset(req, res, peopleHandler, activityHandler, jsonConverter);
203 }
204
205 public void testGetExecution() throws Exception {
206 EasyMock.expect(req.getParameterMap()).andStubReturn(
207 ImmutableMap.of("method", new String[]{"people.get"}, "id", new String[]{"1"}));
208 EasyMock.expect(req.getMethod()).andStubReturn("GET");
209 EasyMock.expect(req.getAttribute(EasyMock.isA(String.class))).andReturn(FAKE_GADGET_TOKEN);
210 EasyMock.expect(req.getCharacterEncoding()).andStubReturn("UTF-8");
211 res.setCharacterEncoding("UTF-8");
212
213 String resultObject = "my lovely json";
214
215 Future<?> responseItemFuture = ImmediateFuture.newInstance(resultObject);
216 EasyMock.expect(peopleHandler.handleItem(EasyMock.isA(RequestItem.class)));
217 EasyMock.expectLastCall().andReturn(responseItemFuture);
218
219 EasyMock.expect(jsonConverter.convertToJson(resultObject))
220 .andReturn(new JSONObject(ImmutableMap.of("foo", "bar")));
221
222 JSONObject result = new JSONObject("{id:'1',data:{foo:'bar'}}");
223 PrintWriter writerMock = EasyMock.createMock(PrintWriter.class);
224 EasyMock.expect(res.getWriter()).andReturn(writerMock);
225 writerMock.write(EasyMock.eq(result.toString()));
226 EasyMock.expectLastCall();
227
228 EasyMock.replay(req, res, peopleHandler, activityHandler, jsonConverter, writerMock);
229 servlet.service(req, res);
230 EasyMock.verify(req, res, peopleHandler, activityHandler, jsonConverter, writerMock);
231 EasyMock.reset(req, res, peopleHandler, activityHandler, jsonConverter);
232 }
233
234 private void setupRequest(String json) throws IOException {
235 final InputStream in = new ByteArrayInputStream(json.getBytes());
236 ServletInputStream stream = new ServletInputStream() {
237 @Override
238 public int read() throws IOException {
239 return in.read();
240 }
241 };
242
243 EasyMock.expect(req.getInputStream()).andStubReturn(stream);
244 EasyMock.expect(req.getMethod()).andStubReturn("POST");
245 EasyMock.expect(req.getAttribute(EasyMock.isA(String.class))).andReturn(FAKE_GADGET_TOKEN);
246 EasyMock.expect(req.getCharacterEncoding()).andStubReturn("UTF-8");
247 res.setCharacterEncoding("UTF-8");
248 res.setContentType("application/json");
249 }
250
251 }