2 * Copyright 2005-2011 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.xmlrouter.impl;
18 import static org.mockito.Matchers.*;
19 import static org.mockito.Mockito.*;
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.logging.Level;
25 import javax.xml.transform.dom.DOMSource;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.wamblee.general.SystemClock;
30 import org.wamblee.xmlrouter.common.Id;
31 import org.wamblee.xmlrouter.config.DocumentType;
32 import org.wamblee.xmlrouter.config.Transformation;
33 import org.wamblee.xmlrouter.listener.EventInfo;
34 import org.wamblee.xmlrouter.listener.EventListener;
35 import org.wamblee.xmlrouter.listener.LoggingEventListener;
36 import org.wamblee.xmlrouter.subscribe.Destination;
38 public class XMLRouterTest {
40 public static class MyDestination implements Destination {
42 private boolean receiveResult;
43 private Collection<String> types;
45 public MyDestination(boolean aReceiveResult, Collection<String> aTypes) {
46 receiveResult = aReceiveResult;
51 public Collection<String> chooseFromTargetTypes(
52 Collection<String> aPossibleTargetTypes) {
57 public String getName() {
62 public boolean receive(DOMSource aEvent) {
67 private XMLRouter router;
68 private DOMSource source1;
69 private DOMSource source2;
70 private DOMSource source3;
72 private Destination destinationSpy;
73 private Id<Destination> destinationId;
74 private EventListener listener;
78 EventListener logListener = new LoggingEventListener(Level.INFO);
79 listener = spy(logListener);
80 router = new XMLRouter(new SystemClock(), listener);
81 source1 = mock(DOMSource.class);
82 source2 = mock(DOMSource.class);
83 source3 = mock(DOMSource.class);
87 public void testNoInputDocumentsRegistered() {
88 Destination destination = new MyDestination(true, Arrays.asList("any"));
89 destinationSpy = spy(destination);
91 destinationId = router.registerDestination(destinationSpy);
92 router.publish("any", source1);
93 verify(listener).notDelivered(any(EventInfo.class));
97 public void testOneDestinationNoTransformationSuccess() {
98 destinationSpy = registerDestination(true, "any");
99 registerDocumentType("any");
101 router.publish("any", source1);
102 verify(listener).delivered(any(EventInfo.class),
103 anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
104 verify(destinationSpy).receive(same(source1));
106 // Unregister the destination.
107 router.unregisterDestination(destinationId);
109 router.publish("any", source2);
110 verify(listener).notDelivered(any(EventInfo.class));
111 verifyNoMoreInteractions(destinationSpy);
114 private void resetMocks() {
115 reset(destinationSpy);
119 private void registerDocumentType(String aType) {
120 DocumentType type = mock(DocumentType.class);
121 when(type.isInstance(any(DOMSource.class))).thenReturn(true);
122 when(type.getName()).thenReturn(aType);
123 Id<DocumentType> typeId = router.addDocumentType(type);
126 private void registerDocumentType(String aType, DOMSource aSource) {
127 DocumentType type = mock(DocumentType.class);
128 when(type.isInstance(same(aSource))).thenReturn(true);
129 when(type.getName()).thenReturn(aType);
130 Id<DocumentType> typeId = router.addDocumentType(type);
133 private Destination registerDestination(boolean aResult, String... types) {
134 Destination destination = new MyDestination(aResult,
135 Arrays.asList(types));
136 Destination myspy = spy(destination);
137 destinationId = router.registerDestination(myspy);
142 public void testOneDestinationNotMatches() {
143 destinationSpy = registerDestination(true);
144 registerDocumentType("any");
146 router.publish("any", source1);
147 verify(listener).notDelivered(any(EventInfo.class));
148 verify(destinationSpy, never()).receive(any(DOMSource.class));
152 public void testOneDestinationThrowsException() {
153 destinationSpy = registerDestination(true, "any");
154 registerDocumentType("any");
156 doThrow(new RuntimeException()).when(destinationSpy).receive(
157 any(DOMSource.class));
159 router.publish("any", source1);
160 verify(listener).notDelivered(any(EventInfo.class));
161 verify(destinationSpy).receive(same(source1));
165 public void testOneDestinationThrowsExceptionSecondDestinationStillHandled() {
166 testOneDestinationThrowsException();
167 Destination destination2 = new MyDestination(true, Arrays.asList("any"));
168 Destination destinationSpy2 = spy(destination2);
169 Id<Destination> destinationId2 = router
170 .registerDestination(destinationSpy2);
172 router.publish("any", source1);
173 verify(listener).delivered(any(EventInfo.class),
174 anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
176 verify(destinationSpy2).receive(same(source1));
181 public void testDestinationChooseFromTargetTypesThrowsException() {
182 destinationSpy = registerDestination(true, "any");
183 registerDocumentType("any");
185 doThrow(new RuntimeException()).when(destinationSpy)
186 .chooseFromTargetTypes((Collection<String>) anyObject());
188 router.publish("any", source1);
189 verify(listener).notDelivered(any(EventInfo.class));
190 verify(destinationSpy, never()).receive(same(source1));
194 public void testDestinationChooseFromTargetTypesThrowsExceptionSecondDestinationStillOk() {
195 testDestinationChooseFromTargetTypesThrowsException();
197 Destination destination2 = new MyDestination(true, Arrays.asList("any"));
198 Destination destinationSpy2 = spy(destination2);
199 Id<Destination> destinationId2 = router
200 .registerDestination(destinationSpy2);
201 router.publish("any", source1);
202 verify(listener).delivered(any(EventInfo.class),
203 anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
205 verify(destinationSpy, never()).receive(same(source1));
206 verify(destinationSpy2).receive(same(source1));
210 public void testDestinationChooseFromTargetTypesReturnsNull() {
211 destinationSpy = registerDestination(true, "any");
212 registerDocumentType("any");
216 .chooseFromTargetTypes((Collection<String>) anyObject()))
219 router.publish("any", source1);
220 verify(listener).notDelivered(any(EventInfo.class));
221 verify(destinationSpy, never()).receive(same(source1));
225 public void testDestinationChooseFromTargetTypesReturnsNullSecondDestinationStillOk() {
226 testDestinationChooseFromTargetTypesReturnsNull();
228 Destination destination2 = new MyDestination(true, Arrays.asList("any"));
229 Destination destinationSpy2 = spy(destination2);
230 Id<Destination> destinationId2 = router
231 .registerDestination(destinationSpy2);
232 router.publish("any", source1);
233 verify(listener).delivered(any(EventInfo.class),
234 anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
236 verify(destinationSpy, never()).receive(same(source1));
237 verify(destinationSpy2).receive(same(source1));
241 public void testOneTransformationOneDestination() {
242 registerDocumentType("any");
243 Transformation transformation = mock(Transformation.class);
244 when(transformation.getName()).thenReturn("trans");
245 when(transformation.getFromType()).thenReturn("any");
246 when(transformation.getToType()).thenReturn("bla");
247 when(transformation.transform(same(source1))).thenReturn(source2);
248 router.addTransformation(transformation);
250 Destination destination = mock(Destination.class);
252 destination.chooseFromTargetTypes((Collection<String>) anyObject()))
253 .thenReturn(Arrays.asList("bla"));
255 router.registerDestination(destination);
257 when(destination.receive(any(DOMSource.class))).thenReturn(true);
258 router.publish("bla", source1);
259 verify(listener).delivered(any(EventInfo.class),
260 anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
262 verify(transformation).transform(source1);
263 verify(destination).receive(same(source2));
265 // now the same when the destination rejects the event.
266 when(destination.receive(any(DOMSource.class))).thenReturn(false);
267 router.publish("bla", source1);
268 verify(listener).notDelivered(any(EventInfo.class));
271 private Transformation createTransformation(String aFrom, String aTo,
272 DOMSource aSource, DOMSource aTarget) {
273 Transformation transformation = mock(Transformation.class);
274 when(transformation.getName()).thenReturn("trans");
275 when(transformation.getFromType()).thenReturn(aFrom);
276 when(transformation.getToType()).thenReturn(aTo);
277 when(transformation.transform(same(aSource))).thenReturn(aTarget);
278 return transformation;
282 public void testOneTransformationReturnsNull() {
283 registerDocumentType("any");
284 Transformation transformation = createTransformation("any", "bla",
287 router.addTransformation(transformation);
289 Destination destination = mock(Destination.class);
291 destination.chooseFromTargetTypes((Collection<String>) anyObject()))
292 .thenReturn(Arrays.asList("bla"));
293 router.registerDestination(destination);
295 router.publish("bla", source1);
296 verify(listener).notDelivered(any(EventInfo.class));
298 verify(transformation).transform(source1);
299 verify(destination, never()).receive(any(DOMSource.class));
301 // add second transformation that behaves normally
302 Transformation transformation2 = createTransformation("any", "bla2",
305 router.addTransformation(transformation2);
307 destination.chooseFromTargetTypes((Collection<String>) anyObject()))
308 .thenReturn(Arrays.asList("bla", "bla2"));
310 reset(transformation);
311 when(transformation.getName()).thenReturn("trans");
312 when(transformation.getFromType()).thenReturn("any");
313 when(transformation.getToType()).thenReturn("bla");
314 when(transformation.transform(same(source1))).thenReturn(null);
316 when(destination.receive(any(DOMSource.class))).thenReturn(true);
317 router.publish("bla", source1);
318 verify(listener).delivered(any(EventInfo.class),
319 anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
321 verify(transformation).transform(source1);
322 verify(transformation2).transform(source1);
324 verify(destination).receive(same(source2));
329 public void testChooseMultipleDestinationsOneType() {
330 Destination dest1 = registerDestination(true, "any");
331 Destination dest2 = registerDestination(true, "any");
332 registerDocumentType("any");
334 router.publish("source", source1);
335 verify(listener, times(2)).delivered(any(EventInfo.class),
336 anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
338 verify(dest1).receive(same(source1));
339 verify(dest2).receive(same(source1));
343 public void testMultipleDeliveryToOneDestination() {
344 Destination dest = registerDestination(true, "any", "other");
345 registerDocumentType("any", source1);
346 registerDocumentType("other", source2);
347 Transformation transformation = createTransformation("any", "other",
349 router.addTransformation(transformation);
351 router.publish("source", source1);
352 verify(listener, times(2)).delivered(any(EventInfo.class),
353 anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
355 verify(dest).receive(same(source1));
356 verify(dest).receive(same(source2));
360 public void testMultipleTransformations() {
361 Destination dest = registerDestination(true, "other");
362 registerDocumentType("any", source1);
363 registerDocumentType("other", source3);
365 Transformation t1 = createTransformation("any", "intermediate",
367 router.addTransformation(t1);
368 Transformation t2 = createTransformation("intermediate", "other",
370 router.addTransformation(t2);
372 router.publish("source", source1);
373 verify(listener).delivered(any(EventInfo.class),
374 anyListOf(Transformation.class), anyLong(), anyString(), eq(true));
376 verify(dest).receive(same(source3));
380 public void testDestinationGivesError() {
381 Destination destination = mock(Destination.class);
382 when(destination.getName()).thenReturn("name");
383 when(destination.chooseFromTargetTypes(anyCollectionOf(String.class)))
384 .thenReturn(Arrays.asList("any"));
385 doThrow(new RuntimeException("x")).when(destination).receive(
386 any(DOMSource.class));
387 router.registerDestination(destination);
389 registerDocumentType("any");
391 router.publish("source", source1);
393 verify(listener).delivered(any(EventInfo.class),
394 anyListOf(Transformation.class), anyLong(), anyString(), eq(false));