11package eu .chargetime .ocpp .test ;
22
3- import static org .mockito .Mockito .*;
4-
53import eu .chargetime .ocpp .*;
64import eu .chargetime .ocpp .feature .Feature ;
5+ import eu .chargetime .ocpp .model .Confirmation ;
76import eu .chargetime .ocpp .model .Request ;
87import eu .chargetime .ocpp .model .SessionInformation ;
9- import java .util .Optional ;
10- import java .util .UUID ;
8+ import eu .chargetime .ocpp .model .TestConfirmation ;
119import org .junit .Before ;
1210import org .junit .Test ;
1311import org .junit .runner .RunWith ;
1412import org .mockito .Mock ;
1513import org .mockito .junit .MockitoJUnitRunner ;
1614
15+ import java .util .Optional ;
16+ import java .util .UUID ;
17+ import java .util .concurrent .CompletableFuture ;
18+ import java .util .concurrent .ExecutionException ;
19+ import java .util .concurrent .TimeoutException ;
20+
21+ import static org .hamcrest .CoreMatchers .equalTo ;
22+ import static org .hamcrest .CoreMatchers .is ;
23+ import static org .hamcrest .MatcherAssert .assertThat ;
24+ import static org .junit .Assert .assertThrows ;
25+ import static org .mockito .Mockito .*;
26+
1727/*
1828 ChargeTime.eu - Java-OCA-OCPP
1929
@@ -58,7 +68,7 @@ public class ServerTest {
5868 @ Mock private Request request ;
5969 @ Mock private SessionInformation information ;
6070 @ Mock private IFeatureRepository featureRepository ;
61- @ Mock private IPromiseRepository promiseRepository ;
71+ @ Mock IPromiseRepository promiseRepository ;
6272
6373 @ Before
6474 public void setup () {
@@ -75,8 +85,10 @@ public void setup() {
7585 .when (serverEvents )
7686 .newSession (any (), any ());
7787
88+ when (promiseRepository .createPromise (any ())).then (invocation -> new CompletableFuture <Confirmation >());
7889 when (featureRepository .findFeature (any ())).thenReturn (Optional .of (feature ));
7990 when (session .getFeatureRepository ()).thenReturn (featureRepository );
91+ when (session .storeRequest (any ())).thenAnswer (invocation -> UUID .randomUUID ().toString ());
8092 server = new Server (listener , promiseRepository );
8193 }
8294
@@ -143,4 +155,74 @@ public void send_aMessage_validatesMessage() throws Exception {
143155 // Then
144156 verify (request , times (1 )).validate ();
145157 }
158+
159+ @ Test
160+ public void send_aMessage_promiseCompletes () throws Exception {
161+ // Given
162+ server .open (LOCALHOST , PORT , serverEvents );
163+ listenerEvents .newSession (session , information );
164+ CompletableFuture <Confirmation > internalFuture = new CompletableFuture <>();
165+ when (promiseRepository .createPromise (any ())).thenReturn (internalFuture );
166+
167+ // When
168+ CompletableFuture <Confirmation > returnedFuture = server .send (sessionIndex , request );
169+ TestConfirmation confirmation = new TestConfirmation ();
170+ internalFuture .complete (confirmation );
171+
172+ // Then
173+ assertThat (returnedFuture , is (internalFuture ));
174+ assertThat (returnedFuture .isDone (), is (true ));
175+ assertThat (returnedFuture .get (), is (confirmation ));
176+ verify (session , times (1 )).removeRequest (any ());
177+ verify (promiseRepository , times (1 )).removePromise (any ());
178+ }
179+
180+ @ Test
181+ public void send_aMessage_promiseCompletesExceptionally () throws Exception {
182+ // Given
183+ server .open (LOCALHOST , PORT , serverEvents );
184+ listenerEvents .newSession (session , information );
185+ CompletableFuture <Confirmation > internalFuture = new CompletableFuture <>();
186+ when (promiseRepository .createPromise (any ())).thenReturn (internalFuture );
187+
188+ // When
189+ CompletableFuture <Confirmation > returnedFuture = server .send (sessionIndex , request );
190+ internalFuture .completeExceptionally (new IllegalStateException ());
191+
192+ // Then
193+ assertThat (returnedFuture , is (internalFuture ));
194+ assertThat (returnedFuture .isDone (), is (true ));
195+ assertThat (returnedFuture .isCompletedExceptionally (), is (true ));
196+ ExecutionException executionException = assertThrows (ExecutionException .class , returnedFuture ::get );
197+ assertThat (executionException .getCause ().getClass (), is (equalTo (IllegalStateException .class )));
198+ verify (session , times (1 )).removeRequest (any ());
199+ verify (promiseRepository , times (1 )).removePromise (any ());
200+ }
201+
202+ @ Test
203+ public void send_aMessage_promiseCompletesWithTimeout () throws Exception {
204+ // Given
205+ server .open (LOCALHOST , PORT , serverEvents );
206+ listenerEvents .newSession (session , information );
207+ CompletableFuture <Confirmation > internalFuture = new CompletableFuture <>();
208+ when (promiseRepository .createPromise (any ())).thenReturn (internalFuture );
209+
210+ // When
211+ CompletableFuture <Confirmation > returnedFuture = server .send (sessionIndex , request );
212+ // If the client uses at least Java 9, it could use CompletableFuture::orTimeout(..).
213+ // returnedFuture.orTimeout(50, TimeUnit.MILLISECONDS);
214+ assertThat (returnedFuture .isDone (), is (false ));
215+ Thread .sleep (100 );
216+ // .. alternatively, it can be implemented manually
217+ returnedFuture .completeExceptionally (new TimeoutException ());
218+
219+ // Then
220+ assertThat (returnedFuture , is (internalFuture ));
221+ assertThat (returnedFuture .isDone (), is (true ));
222+ assertThat (returnedFuture .isCompletedExceptionally (), is (true ));
223+ ExecutionException executionException = assertThrows (ExecutionException .class , returnedFuture ::get );
224+ assertThat (executionException .getCause ().getClass (), is (equalTo (TimeoutException .class )));
225+ verify (session , times (1 )).removeRequest (any ());
226+ verify (promiseRepository , times (1 )).removePromise (any ());
227+ }
146228}
0 commit comments