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