/sigmah/src/test/java/org/sigmah/client/dispatch/remote/RemoteDispatcherTest.java

http://sigma-h.googlecode.com/ · Java · 255 lines · 162 code · 66 blank · 27 comment · 0 complexity · ffaa6f0dce3273a74282a5341fedefac MD5 · raw file

  1. /*
  2. * All Sigmah code is released under the GNU General Public License v3
  3. * See COPYRIGHT.txt and LICENSE.txt.
  4. */
  5. package org.sigmah.client.dispatch.remote;
  6. import com.google.gwt.user.client.rpc.AsyncCallback;
  7. import org.easymock.Capture;
  8. import org.easymock.IAnswer;
  9. import org.junit.Before;
  10. import org.junit.Test;
  11. import org.sigmah.client.dispatch.CommandProxy;
  12. import org.sigmah.client.dispatch.remote.cache.ProxyResult;
  13. import org.sigmah.client.mock.MockEventBus;
  14. import org.sigmah.shared.command.Command;
  15. import org.sigmah.shared.command.GetSchema;
  16. import org.sigmah.shared.command.RemoteCommandServiceAsync;
  17. import org.sigmah.shared.command.result.CommandResult;
  18. import org.sigmah.shared.dto.SchemaDTO;
  19. import org.sigmah.shared.exception.CommandException;
  20. import java.util.Collections;
  21. import static org.easymock.EasyMock.*;
  22. public class RemoteDispatcherTest {
  23. private static final String AUTH_TOKEN = "XYZ";
  24. private RemoteCommandServiceAsync service;
  25. private RemoteDispatcher dispatcher;
  26. private CommandProxy proxy;
  27. private Capture<AsyncCallback> remoteCallback = new Capture<AsyncCallback>();
  28. @Before
  29. public void setUp() {
  30. service = createMock("remoteService", RemoteCommandServiceAsync.class);
  31. proxy = createMock("proxy", CommandProxy.class);
  32. dispatcher = new RemoteDispatcher(service, new MockEventBus(),
  33. new Authentication(1, AUTH_TOKEN, "alex@alex.com"));
  34. }
  35. @Test
  36. public void commandShouldBeSentToServerIfThereAreNoProxiesAndNoPendingCommands() {
  37. // define our expectations
  38. expectRemoteCall(new GetSchema());
  39. replay(service);
  40. // trigger a call
  41. dispatcher.execute(new GetSchema(), null, makeNullCallback());
  42. dispatcher.processPendingCommands();
  43. // verify that the command was dispatched to the server
  44. verify(service);
  45. }
  46. @Test
  47. public void duplicateCommandsShouldBeMergedWithPendingRequests() {
  48. expectRemoteCall(new GetSchema());
  49. replay(service);
  50. // simulate successive dispatches of the same command from different
  51. // components of the application
  52. dispatcher.execute(new GetSchema(), null, makeNullCallback());
  53. dispatcher.execute(new GetSchema(), null, makeNullCallback());
  54. dispatcher.processPendingCommands();
  55. // verify that only one command was sent
  56. verify(service);
  57. }
  58. @Test
  59. public void duplicateCommandsShouldBeMergedWithExecutingRequests() {
  60. expectRemoteCall(new GetSchema());
  61. replay(service);
  62. // simulate successive dispatches of the same command from different
  63. // components of the application
  64. dispatcher.execute(new GetSchema(), null, makeNullCallback());
  65. dispatcher.processPendingCommands();
  66. dispatcher.execute(new GetSchema(), null, makeNullCallback());
  67. // verify that only one command was sent
  68. verify(service);
  69. }
  70. @Test
  71. public void mergedCommandsShouldEachReceiveACallback() {
  72. expectRemoteCall(new GetSchema());
  73. andCallbackWihSuccess(new SchemaDTO());
  74. replay(service);
  75. AsyncCallback callback1 = makeCallbackThatExpectsNonNullSuccess();
  76. AsyncCallback callback2 = makeCallbackThatExpectsNonNullSuccess();
  77. // simulate successive dispatches of the same command from different
  78. // components of the application
  79. dispatcher.execute(new GetSchema(), null, callback1);
  80. dispatcher.execute(new GetSchema(), null, callback2);
  81. dispatcher.processPendingCommands();
  82. // verify that only one command was sent
  83. verify(callback1);
  84. verify(callback2);
  85. }
  86. @Test
  87. public void commandsSuccessfullyExecutedThroughProxiesShouldNotBeSentToServer() {
  88. GetSchema command = new GetSchema();
  89. expect(proxy.maybeExecute(eq(command))).andReturn(new ProxyResult(new SchemaDTO()));
  90. replay(proxy);
  91. replay(service); // no calls should be made to the remote service
  92. AsyncCallback callback = makeCallbackThatExpectsNonNullSuccess();
  93. dispatcher.registerProxy(GetSchema.class, proxy);
  94. dispatcher.execute(new GetSchema(), null, callback);
  95. dispatcher.processPendingCommands();
  96. verify(proxy, service, callback);
  97. }
  98. @Test
  99. public void commandsUnsuccessfullyExecutedThroughProxiesShouldBeSentToServer() {
  100. GetSchema command = new GetSchema();
  101. expect(proxy.maybeExecute(eq(command))).andReturn(ProxyResult.couldNotExecute());
  102. replay(proxy);
  103. expectRemoteCall(command);
  104. andCallbackWihSuccess(new SchemaDTO());
  105. replay(service);
  106. AsyncCallback callback = makeCallbackThatExpectsNonNullSuccess();
  107. dispatcher.registerProxy(GetSchema.class, proxy);
  108. dispatcher.execute(new GetSchema(), null, callback);
  109. dispatcher.processPendingCommands();
  110. verify(proxy, service, callback);
  111. }
  112. @Test
  113. public void commandExceptionsShouldBeCalledBackWithFailure() {
  114. expectRemoteCall(new GetSchema());
  115. andCallbackWihSuccess(new CommandException()); // remote call succeeded, command failed
  116. replay(service);
  117. AsyncCallback callback = makeCallbackThatExpectsFailure();
  118. dispatcher.execute(new GetSchema(), null, callback);
  119. dispatcher.processPendingCommands();
  120. verify(service, callback);
  121. }
  122. /**
  123. * The RemoteDispatcher will group and bundle commands together-- we
  124. * need to make sure that different components remain isolated from
  125. * failures within other components.
  126. */
  127. @Test
  128. public void exceptionsThrownByCallbacksDoNotDistubOthers() {
  129. expectRemoteCall(new GetSchema());
  130. andCallbackWihSuccess(new SchemaDTO());
  131. replay(service);
  132. // Here we set up one component that will call request a command
  133. // but something will go wrong when the command return (successfully)
  134. // the error is unrelated to the remote command -- it just happens to be
  135. // there.
  136. dispatcher.execute(new GetSchema(), null, new AsyncCallback<SchemaDTO>() {
  137. @Override
  138. public void onFailure(Throwable caught) {
  139. }
  140. @Override
  141. public void onSuccess(SchemaDTO result) {
  142. throw new Error();
  143. }
  144. });
  145. // the second command independently requests the same command,
  146. // we need to make sure we receive a result
  147. AsyncCallback secondCallback = makeCallbackThatExpectsNonNullSuccess();
  148. dispatcher.execute(new GetSchema(), null, secondCallback);
  149. dispatcher.processPendingCommands();
  150. verify(secondCallback);
  151. }
  152. private AsyncCallback<SchemaDTO> makeNullCallback() {
  153. return new AsyncCallback<SchemaDTO>() {
  154. @Override
  155. public void onFailure(Throwable throwable) {
  156. }
  157. @Override
  158. public void onSuccess(SchemaDTO o) {
  159. }
  160. };
  161. }
  162. private AsyncCallback makeCallbackThatExpectsNonNullSuccess() {
  163. AsyncCallback callback = createMock(AsyncCallback.class);
  164. callback.onSuccess(notNull());
  165. replay(callback);
  166. return callback;
  167. }
  168. private AsyncCallback makeCallbackThatExpectsFailure() {
  169. AsyncCallback callback = createMock(AsyncCallback.class);
  170. callback.onFailure(isA(Throwable.class));
  171. replay(callback);
  172. return callback;
  173. }
  174. private void expectRemoteCall(GetSchema command) {
  175. service.execute(
  176. eq(AUTH_TOKEN),
  177. eq(Collections.<Command>singletonList(command)),
  178. capture(remoteCallback));
  179. }
  180. private void andCallbackWihSuccess(final CommandResult result) {
  181. expectLastCall().andAnswer(new IAnswer<Object>() {
  182. @Override
  183. public Object answer() throws Throwable {
  184. ((AsyncCallback) getCurrentArguments()[2]).onSuccess(Collections.singletonList(result));
  185. return null;
  186. }
  187. });
  188. }
  189. }