PageRenderTime 49ms CodeModel.GetById 32ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

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