View Javadoc
1   package com.atlassian.plugin.event.impl;
2   
3   import com.atlassian.event.api.EventListener;
4   import com.atlassian.event.api.EventPublisher;
5   import com.atlassian.plugin.event.PluginEventListener;
6   import org.junit.After;
7   import org.junit.Before;
8   import org.junit.Test;
9   import org.junit.runner.RunWith;
10  import org.mockito.Mock;
11  import org.mockito.junit.MockitoJUnitRunner;
12  
13  import static org.hamcrest.core.IsNull.notNullValue;
14  import static org.junit.Assert.assertEquals;
15  import static org.junit.Assert.assertThat;
16  import static org.junit.Assert.fail;
17  import static org.mockito.ArgumentMatchers.any;
18  import static org.mockito.ArgumentMatchers.anyString;
19  import static org.mockito.Mockito.mock;
20  import static org.mockito.Mockito.never;
21  import static org.mockito.Mockito.times;
22  import static org.mockito.Mockito.verify;
23  
24  @RunWith(MockitoJUnitRunner.class)
25  public class TestDefaultPluginEventManager {
26      private final Object someObject = new Object();
27      private final String someString = "string";
28  
29      @Mock
30      private MethodTestListener methodTestListener;
31  
32      private DefaultPluginEventManager defaultPluginEventManager;
33  
34      @Before
35      public void createDefaultPluginEventManager() {
36          defaultPluginEventManager = new DefaultPluginEventManager();
37          assertThat(defaultPluginEventManager.getEventPublisher(), notNullValue(EventPublisher.class));
38      }
39  
40      @After
41      public void discardDefaultPluginEventManager() {
42          defaultPluginEventManager = null;
43      }
44  
45      @Test
46      public void broadcastCallsListenerChannelForType() {
47          defaultPluginEventManager.register(methodTestListener);
48          defaultPluginEventManager.broadcast(someObject);
49          verify(methodTestListener).channel(someObject);
50          verify(methodTestListener, never()).channel(anyString());
51      }
52  
53      @Test
54      public void broadcastCallsListenerChannelForSupertype() {
55          final Integer someInteger = 0;
56          defaultPluginEventManager.register(methodTestListener);
57          defaultPluginEventManager.broadcast(someInteger);
58          verify(methodTestListener).channel(someInteger);
59          verify(methodTestListener, never()).channel(anyString());
60      }
61  
62      @Test
63      public void broadcastCallsListenerChannelForTypeAndSupertype() {
64          defaultPluginEventManager.register(methodTestListener);
65          defaultPluginEventManager.broadcast(someString);
66          // The cast ensures we verify both overloads are called
67          verify(methodTestListener).channel((Object) someString);
68          verify(methodTestListener).channel(someString);
69      }
70  
71      @Test
72      public void listenerCalledOnceEvenIfRegisteredTwice() {
73          defaultPluginEventManager.register(methodTestListener);
74          defaultPluginEventManager.register(methodTestListener);
75          defaultPluginEventManager.broadcast(someObject);
76          verify(methodTestListener).channel(someObject);
77          verify(methodTestListener, never()).channel(anyString());
78      }
79  
80      @Test
81      public void registerUnmatchingListenerThrows() {
82          BadListener badListener = mock(BadListener.class);
83          try {
84              defaultPluginEventManager.register(badListener);
85              fail();
86          } catch (IllegalArgumentException ex) {
87              // test passed
88          }
89          verify(badListener, never()).someMethod();
90      }
91  
92      @Test
93      public void customSelectorMatchesAndOverridesDefault() {
94          ListenerMethodSelector onEventSelector = method -> "onEvent".equals(method.getName());
95          defaultPluginEventManager = new DefaultPluginEventManager(onEventSelector);
96          defaultPluginEventManager.register(methodTestListener);
97          defaultPluginEventManager.broadcast(someString);
98          verify(methodTestListener).onEvent(someString);
99          verify(methodTestListener, never()).channel(any());
100         verify(methodTestListener, never()).channel(anyString());
101     }
102 
103     @Test
104     public void overlappingSelectorsBothMatch() {
105         ListenerMethodSelector firstSelector = new MethodNameListenerMethodSelector();
106         ListenerMethodSelector secondSelector = new MethodNameListenerMethodSelector();
107         defaultPluginEventManager = new DefaultPluginEventManager(firstSelector, secondSelector);
108         defaultPluginEventManager.register(methodTestListener);
109         defaultPluginEventManager.broadcast(someObject);
110         verify(methodTestListener, times(2)).channel(someObject);
111     }
112 
113     @Test
114     public void broadcastCallsAnnotatedMethods() {
115         // I don't believe this can be done with mocks, because the stub
116         // is not annotated, and i don't see a way of getting it annotated.
117         AnnotationTestListener listener = new AnnotationTestListener();
118         defaultPluginEventManager.register(listener);
119         defaultPluginEventManager.broadcast(someObject);
120         assertEquals(1, listener.eventListenerCalled);
121         assertEquals(1, listener.pluginEventListenerCalled);
122     }
123 
124     @Test
125     public void unregisterStopsBroadcastSendingEvents() {
126         defaultPluginEventManager.register(methodTestListener);
127         defaultPluginEventManager.broadcast(someObject);
128         verify(methodTestListener).channel(someObject);
129         defaultPluginEventManager.unregister(methodTestListener);
130         defaultPluginEventManager.broadcast(someObject);
131         // This checks it was called once, i.e. first broadcast
132         verify(methodTestListener).channel(someObject);
133     }
134 
135     @Test(expected = IllegalArgumentException.class)
136     public void registerNullThrows() {
137         defaultPluginEventManager.register(null);
138     }
139 
140     @Test(expected = IllegalArgumentException.class)
141     public void unregisterNullThrows() {
142         defaultPluginEventManager.unregister(null);
143     }
144 
145     public static class AnnotationTestListener {
146         int pluginEventListenerCalled = 0;
147         int eventListenerCalled = 0;
148 
149         @PluginEventListener
150         public void doEventOld(Object obj) {
151             ++pluginEventListenerCalled;
152         }
153 
154         @EventListener
155         public void doEventNew(Object obj) {
156             ++eventListenerCalled;
157         }
158     }
159 
160     public static class MethodTestListener {
161         public void channel(Object object) {
162         }
163 
164         public void channel(String string) {
165         }
166 
167         public void onEvent(String string) {
168         }
169     }
170 
171     public static class BadListener {
172         public void someMethod() {
173         }
174     }
175 }