001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.user.server.rpc;
017:
018: import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
019: import com.google.gwt.user.client.rpc.RemoteService;
020: import com.google.gwt.user.client.rpc.SerializableException;
021: import com.google.gwt.user.client.rpc.SerializationException;
022:
023: import junit.framework.TestCase;
024:
025: import java.lang.reflect.Method;
026:
027: /**
028: * Tests for the {@link com.google.gwt.user.server.rpc.RPC RPC} class.
029: */
030: public class RPCTest extends TestCase {
031:
032: private static interface A extends RemoteService {
033: void method1() throws SerializableException;
034:
035: int method2();
036:
037: int method3(int val);
038: }
039:
040: private static interface B {
041: void method1();
042: }
043:
044: private final String VALID_ENCODED_REQUEST = "3\uffff" + // version
045: "0\uffff" + // flags
046: "4\uffff" + // string table entry count
047: A.class.getName() + "\uffff" + // string table entry #0
048: "method2" + "\uffff" + // string table entry #1
049: "moduleBaseURL" + "\uffff" + // string table entry #2
050: "whitelistHashcode" + "\uffff" + // string table entry #4
051: "3\uffff" + // module base URL
052: "4\uffff" + // whitelist hashcode
053: "1\uffff" + // interface name
054: "2\uffff" + // method name
055: "0\uffff"; // param count
056:
057: private final String INVALID_METHOD_REQUEST = "3\uffff" + // version
058: "0\uffff" + // flags
059: "4\uffff" + // string table entry count
060: A.class.getName() + "\uffff" + // string table entry #0
061: "method3" + "\uffff" + // string table entry #1
062: "moduleBaseURL" + "\uffff" + // string table entry #2
063: "whitelistHashcode" + "\uffff" + // string table entry #4
064: "3\uffff" + // module base URL
065: "4\uffff" + // whitelist hashcode
066: "1\uffff" + // interface name
067: "2\uffff" + // method name
068: "0\uffff"; // param count
069:
070: private final String INVALID_INTERFACE_REQUEST = "3\uffff" + // version
071: "0\uffff" + // flags
072: "4\uffff" + // string table entry count
073: B.class.getName() + "\uffff" + // string table entry #0
074: "method1" + "\uffff" + // string table entry #1
075: "moduleBaseURL" + "\uffff" + // string table entry #2
076: "whitelistHashcode" + "\uffff" + // string table entry #4
077: "3\uffff" + // module base URL
078: "4\uffff" + // whitelist hashcode
079: "1\uffff" + // interface name
080: "2\uffff" + // method name
081: "0\uffff"; // param count
082:
083: private final String VALID_PRE_RPC_RESOURCE_ENCODED_REQUEST = "2\uffff"
084: + // version
085: "0\uffff" + // flags
086: "2\uffff" + // string table entry count
087: A.class.getName() + "\uffff" + // string table entry #0
088: "method2" + "\uffff" + // string table entry #1
089: "1\uffff" + // interface name
090: "2\uffff" + // method name
091: "0\uffff"; // param count
092:
093: /**
094: * Tests for method {@link RPC#decodeRequest(String)}
095: *
096: * <p/> Cases:
097: * <ol>
098: * <li>String == null</li>
099: * <li>String == ""</li>
100: * <li>Valid request
101: * </ol>
102: */
103: public void testDecodeRequestString() {
104: // Case 1
105: try {
106: RPC.decodeRequest(null);
107: fail("Expected NullPointerException");
108: } catch (NullPointerException e) {
109: // expected to get here
110: }
111:
112: // Case 2
113: try {
114: RPC.decodeRequest("");
115: fail("Expected IllegalArgumentException");
116: } catch (IllegalArgumentException e) {
117: // expected to get here
118: }
119:
120: // Case 3
121: RPC.decodeRequest(VALID_ENCODED_REQUEST);
122: }
123:
124: /**
125: * Tests for method {@link RPC#decodeRequest(String, Class)}
126: *
127: * <p/> Cases:
128: * <ol>
129: * <li>String == null</li>
130: * <li>String == ""</li>
131: * <li>Class is null</li>
132: * <li>Class implements RemoteService subinterface</li>
133: * <li>Class implements the requested interface but it is not a subtype of
134: * RemoteService</li>
135: * <li>Class implements RemoteService derived interface but the method does
136: * not exist
137: * </ol>
138: *
139: * @throws NoSuchMethodException
140: * @throws SecurityException
141: */
142: public void testDecodeRequestStringClass()
143: throws SecurityException, NoSuchMethodException {
144: // Case 1
145: try {
146: RPC.decodeRequest(null, null);
147: fail("Expected NullPointerException");
148: } catch (NullPointerException e) {
149: // expected to get here
150: }
151:
152: // Case 2
153: try {
154: RPC.decodeRequest("", null);
155: fail("Expected IllegalArgumentException");
156: } catch (IllegalArgumentException e) {
157: // expected to get here
158: }
159:
160: // Case 3
161: RPCRequest request;
162: request = RPC.decodeRequest(VALID_ENCODED_REQUEST, null);
163: assertEquals(A.class.getMethod("method2"), request.getMethod());
164: assertTrue(request.getParameters().length == 0);
165:
166: // Case 4
167: request = RPC.decodeRequest(VALID_ENCODED_REQUEST, A.class);
168: assertEquals(A.class.getMethod("method2"), request.getMethod());
169: assertTrue(request.getParameters().length == 0);
170:
171: // Case 5
172: try {
173: request = RPC.decodeRequest(INVALID_INTERFACE_REQUEST,
174: B.class);
175: fail("Expected IncompatibleRemoteServiceException");
176: } catch (IncompatibleRemoteServiceException e) {
177: // should get here
178: }
179: // Case 6
180: try {
181: request = RPC
182: .decodeRequest(INVALID_METHOD_REQUEST, A.class);
183: fail("Expected IncompatibleRemoteServiceException");
184: } catch (IncompatibleRemoteServiceException e) {
185: // should get here
186: }
187: }
188:
189: /**
190: * Tests that method
191: * {@link RPC#decodeRequest(String, Class, SerializationPolicyProvider)} can
192: * handle the decoding of requests from pre-RPC resource (whitelist) clients.
193: *
194: * @throws SerializationException
195: */
196: public void testDecodeRequestPreRPCResourceFile() {
197: RPCRequest rpcRequest = RPC.decodeRequest(
198: VALID_PRE_RPC_RESOURCE_ENCODED_REQUEST, A.class, null);
199: SerializationPolicy serializationPolicy = rpcRequest
200: .getSerializationPolicy();
201: assertEquals(RPC.getDefaultSerializationPolicy(),
202: serializationPolicy);
203: }
204:
205: /**
206: * Tests for method {@link RPC#encodeResponseForFailure(Method, Throwable)}.
207: *
208: * Cases:
209: * <ol>
210: * <li>Method == null</li>
211: * <li>Object == null</li>
212: * <li>Method is not specified to throw an exception of the given type</li>
213: * <li>Method is specified to throw an exception of the given type</li>
214: * </ol>
215: *
216: * @throws NoSuchMethodException
217: * @throws SecurityException
218: * @throws SerializationException
219: *
220: */
221: public void testEncodeResponseForFailure()
222: throws SecurityException, NoSuchMethodException,
223: SerializationException {
224: // Case 1
225: RPC.encodeResponseForFailure(null, new SerializableException());
226:
227: Method A_method1 = null;
228: A_method1 = A.class.getMethod("method1");
229:
230: // Case 2
231: try {
232: RPC.encodeResponseForFailure(A_method1, null);
233: fail("Expected NullPointerException");
234: } catch (NullPointerException e) {
235: // expected to get here
236: }
237:
238: // Case 3
239: try {
240: RPC.encodeResponseForFailure(A.class.getMethod("method1"),
241: new IllegalArgumentException());
242: fail("Expected UnexpectedException");
243: } catch (UnexpectedException e) {
244: // expected to get here
245: }
246:
247: // Case 4
248: String str = RPC.encodeResponseForFailure(A.class
249: .getMethod("method1"), new SerializableException());
250: assertTrue(str.indexOf("SerializableException") != -1);
251: }
252:
253: /**
254: * Tests for {@link RPC#encodeResponseForSuccess(Method, Object)}
255: *
256: * Cases:
257: * <ol>
258: * <li>Method == null</li>
259: * <li>Object == null</li>
260: * <li>Method is not specified to return the given type</li>
261: * <li>Method is specified to return the given type</li>
262: * </ol>
263: *
264: * @throws SerializationException
265: * @throws NoSuchMethodException
266: * @throws SecurityException
267: */
268: public void testEncodeResponseForSuccess()
269: throws SerializationException, SecurityException,
270: NoSuchMethodException {
271: Method A_method1 = null;
272: Method A_method2 = null;
273: A_method1 = A.class.getMethod("method1");
274: A_method2 = A.class.getMethod("method2");
275:
276: // Case 1
277: try {
278: RPC.encodeResponseForSuccess(null, new Object());
279: fail("Expected NullPointerException");
280: } catch (NullPointerException e) {
281: // expected to get here
282: }
283:
284: // Case 2
285: RPC.encodeResponseForSuccess(A_method1, null);
286:
287: // Case 3
288: try {
289: RPC.encodeResponseForSuccess(A_method2,
290: new SerializableException());
291: fail("Expected IllegalArgumentException");
292: } catch (IllegalArgumentException e) {
293: // expected to get here
294: }
295:
296: // Case 4
297: RPC.encodeResponseForSuccess(A_method2, new Integer(1));
298: }
299:
300: /**
301: * Tests for {@link RPC#invokeAndEncodeResponse(Object, Method, Object[])}
302: *
303: * Cases:
304: * <ol>
305: * <li>Method == null</li>
306: * <li>Object does not implement Method</li>
307: * <li>Method parameters do not match given parameters
308: * <li>Method throws exception that it is not specified to
309: * <li>Method throws exception that it is specified to throw
310: * </ol>
311: *
312: * @throws NoSuchMethodException
313: * @throws SecurityException
314: * @throws SerializationException
315: *
316: */
317: public void testInvokeAndEncodeResponse() throws SecurityException,
318: NoSuchMethodException, SerializationException {
319: // Case 1
320: try {
321: RPC.invokeAndEncodeResponse(null, null, null);
322: fail("Expected NullPointerException");
323: } catch (NullPointerException e) {
324: // expected to get here
325: }
326:
327: Method A_method1 = A.class.getMethod("method1");
328:
329: // Case 2
330: try {
331: RPC.invokeAndEncodeResponse(new B() {
332: public void method1() {
333: }
334: }, A_method1, null);
335: fail("Expected a SecurityException");
336: } catch (SecurityException e) {
337: // expected to get here
338: }
339:
340: // Case 3
341: try {
342: RPC.invokeAndEncodeResponse(new A() {
343: public void method1() throws SerializableException {
344: }
345:
346: public int method2() {
347: return 0;
348: }
349:
350: public int method3(int val) {
351: return 0;
352: }
353: }, A_method1, new Integer[] { new Integer(1) });
354: fail("Expected a SecurityException");
355: } catch (SecurityException e) {
356: // expected to get here
357: }
358:
359: // Case 4
360: try {
361: RPC.invokeAndEncodeResponse(new A() {
362: public void method1() throws SerializableException {
363: throw new IllegalArgumentException();
364: }
365:
366: public int method2() {
367: return 0;
368: }
369:
370: public int method3(int val) {
371: return 0;
372: }
373: }, A_method1, null);
374: fail("Expected an UnexpectedException");
375: } catch (UnexpectedException e) {
376: // expected to get here
377: }
378:
379: // Case 5
380: RPC.invokeAndEncodeResponse(new A() {
381: public void method1() throws SerializableException {
382: throw new SerializableException();
383: }
384:
385: public int method2() {
386: return 0;
387: }
388:
389: public int method3(int val) {
390: return 0;
391: }
392: }, A_method1, null);
393: }
394: }
|