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