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
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
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
116
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
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 }