50fa4f8d0694b4c0cf670915ed6f1785d8493de1
[xmlrouter] / impl / src / test / java / org / wamblee / xmlrouter / impl / XMLRouterTest.java
1 /*
2  * Copyright 2005-2011 the original author or authors.
3  * 
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
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
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.
15  */ 
16 package org.wamblee.xmlrouter.impl;
17
18 import static junit.framework.Assert.*;
19 import static org.mockito.Matchers.*;
20 import static org.mockito.Mockito.*;
21
22 import java.util.Arrays;
23 import java.util.Collection;
24
25 import javax.xml.transform.dom.DOMSource;
26
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.wamblee.xmlrouter.common.Id;
30 import org.wamblee.xmlrouter.config.DocumentType;
31 import org.wamblee.xmlrouter.config.Transformation;
32 import org.wamblee.xmlrouter.subscribe.Destination;
33
34 public class XMLRouterTest {
35
36     public static class MyDestination implements Destination {
37
38         private boolean receiveResult;
39         private Collection<String> types;
40
41         public MyDestination(boolean aReceiveResult, Collection<String> aTypes) {
42             receiveResult = aReceiveResult;
43             types = aTypes;
44         }
45
46         @Override
47         public Collection<String> chooseFromTargetTypes(
48             Collection<String> aPossibleTargetTypes) {
49             return types;
50         }
51
52         @Override
53         public String getName() {
54             return "xxx";
55         }
56
57         @Override
58         public boolean receive(DOMSource aEvent) {
59             return receiveResult;
60         }
61     }
62
63     private XMLRouter router;
64     private DOMSource source1;
65     private DOMSource source2;
66     private DOMSource source3;
67
68     private Destination destinationSpy;
69     private Id<Destination> destinationId;
70
71     @Before
72     public void setUp() {
73         router = new XMLRouter();
74         source1 = mock(DOMSource.class);
75         source2 = mock(DOMSource.class);
76         source3 = mock(DOMSource.class);
77     }
78
79     @Test
80     public void testNoInputDocumentsRegistered() {
81         Destination destination = new MyDestination(true, Arrays.asList("any"));
82         destinationSpy = spy(destination);
83
84         destinationId = router.registerDestination(destinationSpy);
85         assertFalse(router.publish("any", source1));
86     }
87
88     @Test
89     public void testOneDestinationNoTransformationSuccess() {
90         destinationSpy = registerDestination(true, "any");
91         registerDocumentType("any");
92
93         assertTrue(router.publish("any", source1));
94         verify(destinationSpy).receive(same(source1));
95
96         // Unregister the destination.
97         router.unregisterDestination(destinationId);
98         reset(destinationSpy);
99         assertFalse(router.publish("any", source2));
100         verifyNoMoreInteractions(destinationSpy);
101     }
102
103     private void registerDocumentType(String aType) {
104         DocumentType type = mock(DocumentType.class);
105         when(type.isInstance(any(DOMSource.class))).thenReturn(true);
106         when(type.getName()).thenReturn(aType);
107         Id<DocumentType> typeId = router.addDocumentType(type);
108     }
109
110     private void registerDocumentType(String aType, DOMSource aSource) {
111         DocumentType type = mock(DocumentType.class);
112         when(type.isInstance(same(aSource))).thenReturn(true);
113         when(type.getName()).thenReturn(aType);
114         Id<DocumentType> typeId = router.addDocumentType(type);
115     }
116
117     private Destination registerDestination(boolean aResult, String... types) {
118         Destination destination = new MyDestination(aResult,
119             Arrays.asList(types));
120         Destination myspy = spy(destination);
121         destinationId = router.registerDestination(myspy);
122         return myspy;
123     }
124
125     @Test
126     public void testOneDestinationNotMatches() {
127         destinationSpy = registerDestination(true);
128         registerDocumentType("any");
129
130         assertFalse(router.publish("any", source1));
131         verify(destinationSpy, never()).receive(any(DOMSource.class));
132     }
133
134     @Test
135     public void testOneDestinationThrowsException() {
136         destinationSpy = registerDestination(true, "any");
137         registerDocumentType("any");
138
139         doThrow(new RuntimeException()).when(destinationSpy).receive(
140             any(DOMSource.class));
141
142         assertFalse(router.publish("any", source1));
143         verify(destinationSpy).receive(same(source1));
144     }
145
146     @Test
147     public void testOneDestinationThrowsExceptionSecondDestinationStillHandled() {
148         testOneDestinationThrowsException();
149         Destination destination2 = new MyDestination(true, Arrays.asList("any"));
150         Destination destinationSpy2 = spy(destination2);
151         Id<Destination> destinationId2 = router
152             .registerDestination(destinationSpy2);
153
154         assertTrue(router.publish("any", source1));
155         verify(destinationSpy2).receive(same(source1));
156     }
157
158     @Test
159     public void testDestinationChooseFromTargetTypesThrowsException() {
160         destinationSpy = registerDestination(true, "any");
161         registerDocumentType("any");
162
163         doThrow(new RuntimeException()).when(destinationSpy)
164             .chooseFromTargetTypes((Collection<String>) anyObject());
165
166         assertFalse(router.publish("any", source1));
167         verify(destinationSpy, never()).receive(same(source1));
168     }
169
170     @Test
171     public void testDestinationChooseFromTargetTypesThrowsExceptionSecondDestinationStillOk() {
172         testDestinationChooseFromTargetTypesThrowsException();
173
174         Destination destination2 = new MyDestination(true, Arrays.asList("any"));
175         Destination destinationSpy2 = spy(destination2);
176         Id<Destination> destinationId2 = router
177             .registerDestination(destinationSpy2);
178         assertTrue(router.publish("any", source1));
179         verify(destinationSpy, never()).receive(same(source1));
180         verify(destinationSpy2).receive(same(source1));
181     }
182
183     @Test
184     public void testDestinationChooseFromTargetTypesReturnsNull() {
185         destinationSpy = registerDestination(true, "any");
186         registerDocumentType("any");
187
188         when(
189             destinationSpy
190                 .chooseFromTargetTypes((Collection<String>) anyObject()))
191             .thenReturn(null);
192
193         assertFalse(router.publish("any", source1));
194         verify(destinationSpy, never()).receive(same(source1));
195     }
196
197     @Test
198     public void testDestinationChooseFromTargetTypesReturnsNullSecondDestinationStillOk() {
199         testDestinationChooseFromTargetTypesReturnsNull();
200
201         Destination destination2 = new MyDestination(true, Arrays.asList("any"));
202         Destination destinationSpy2 = spy(destination2);
203         Id<Destination> destinationId2 = router
204             .registerDestination(destinationSpy2);
205         assertTrue(router.publish("any", source1));
206         verify(destinationSpy, never()).receive(same(source1));
207         verify(destinationSpy2).receive(same(source1));
208     }
209
210     @Test
211     public void testOneTransformationOneDestination() {
212         registerDocumentType("any");
213         Transformation transformation = mock(Transformation.class);
214         when(transformation.getFromType()).thenReturn("any");
215         when(transformation.getToType()).thenReturn("bla");
216         when(transformation.transform(same(source1))).thenReturn(source2);
217         router.addTransformation(transformation);
218
219         Destination destination = mock(Destination.class);
220         when(
221             destination.chooseFromTargetTypes((Collection<String>) anyObject()))
222             .thenReturn(Arrays.asList("bla"));
223
224         router.registerDestination(destination);
225
226         when(destination.receive(any(DOMSource.class))).thenReturn(true);
227         assertTrue(router.publish("bla", source1));
228
229         verify(transformation).transform(source1);
230         verify(destination).receive(same(source2));
231
232         // now the same when the destination rejects the event.
233         when(destination.receive(any(DOMSource.class))).thenReturn(false);
234         assertFalse(router.publish("bla", source1));
235     }
236
237     private Transformation createTransformation(String aFrom, String aTo,
238         DOMSource aSource, DOMSource aTarget) {
239         Transformation transformation = mock(Transformation.class);
240         when(transformation.getFromType()).thenReturn(aFrom);
241         when(transformation.getToType()).thenReturn(aTo);
242         when(transformation.transform(same(aSource))).thenReturn(aTarget);
243         return transformation;
244     }
245
246     @Test
247     public void testOneTransformationReturnsNull() {
248         registerDocumentType("any");
249         Transformation transformation = createTransformation("any", "bla",
250             source1, null);
251
252         router.addTransformation(transformation);
253
254         Destination destination = mock(Destination.class);
255         when(
256             destination.chooseFromTargetTypes((Collection<String>) anyObject()))
257             .thenReturn(Arrays.asList("bla"));
258         router.registerDestination(destination);
259
260         assertFalse(router.publish("bla", source1));
261
262         verify(transformation).transform(source1);
263         verify(destination, never()).receive(any(DOMSource.class));
264
265         // add second transformation that behaves normally
266         Transformation transformation2 = createTransformation("any", "bla2",
267             source1, source2);
268
269         router.addTransformation(transformation2);
270         when(
271             destination.chooseFromTargetTypes((Collection<String>) anyObject()))
272             .thenReturn(Arrays.asList("bla", "bla2"));
273
274         reset(transformation);
275         when(transformation.getFromType()).thenReturn("any");
276         when(transformation.getToType()).thenReturn("bla");
277         when(transformation.transform(same(source1))).thenReturn(null);
278
279         when(destination.receive(any(DOMSource.class))).thenReturn(true);
280         assertTrue(router.publish("bla", source1));
281
282         verify(transformation).transform(source1);
283         verify(transformation2).transform(source1);
284
285         verify(destination).receive(same(source2));
286
287     }
288
289     @Test
290     public void testChooseMultipleDestinationsOneType() {
291         Destination dest1 = registerDestination(true, "any");
292         Destination dest2 = registerDestination(true, "any");
293         registerDocumentType("any");
294
295         assertTrue(router.publish("source", source1));
296
297         verify(dest1).receive(same(source1));
298         verify(dest2).receive(same(source1));
299     }
300
301     @Test
302     public void testMultipleDeliveryToOneDestination() {
303         Destination dest = registerDestination(true, "any", "other");
304         registerDocumentType("any", source1);
305         registerDocumentType("other", source2);
306         Transformation transformation = createTransformation("any", "other",
307             source1, source2);
308         router.addTransformation(transformation);
309
310         assertTrue(router.publish("source", source1));
311
312         verify(dest).receive(same(source1));
313         verify(dest).receive(same(source2));
314     }
315
316     @Test
317     public void testMultipleTransformations() {
318         Destination dest = registerDestination(true, "any", "other");
319         registerDocumentType("any", source1);
320         registerDocumentType("other", source3);
321
322         Transformation t1 = createTransformation("any", "intermediate",
323             source1, source2);
324         router.addTransformation(t1);
325         Transformation t2 = createTransformation("intermediate", "other",
326             source2, source3);
327         router.addTransformation(t2);
328
329         assertTrue(router.publish("source", source1));
330
331         verify(dest).receive(same(source3));
332     }
333 }