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 .TimeUnit ;
20+ import java .util .concurrent .TimeoutException ;
21+
22+ import static org .hamcrest .CoreMatchers .equalTo ;
23+ import static org .hamcrest .CoreMatchers .is ;
24+ import static org .hamcrest .MatcherAssert .assertThat ;
25+ import static org .junit .Assert .assertThrows ;
26+ import static org .mockito .Mockito .*;
27+
1728/*
1829 ChargeTime.eu - Java-OCA-OCPP
1930
@@ -58,7 +69,7 @@ public class ServerTest {
5869 @ Mock private Request request ;
5970 @ Mock private SessionInformation information ;
6071 @ Mock private IFeatureRepository featureRepository ;
61- @ Mock private IPromiseRepository promiseRepository ;
72+ @ Mock IPromiseRepository promiseRepository ;
6273
6374 @ Before
6475 public void setup () {
@@ -75,8 +86,10 @@ public void setup() {
7586 .when (serverEvents )
7687 .newSession (any (), any ());
7788
89+ when (promiseRepository .createPromise (any ())).then (invocation -> new CompletableFuture <Confirmation >());
7890 when (featureRepository .findFeature (any ())).thenReturn (Optional .of (feature ));
7991 when (session .getFeatureRepository ()).thenReturn (featureRepository );
92+ when (session .storeRequest (any ())).thenAnswer (invocation -> UUID .randomUUID ().toString ());
8093 server = new Server (listener , promiseRepository );
8194 }
8295
@@ -143,4 +156,74 @@ public void send_aMessage_validatesMessage() throws Exception {
143156 // Then
144157 verify (request , times (1 )).validate ();
145158 }
159+
160+ @ Test
161+ public void send_aMessage_promiseCompletes () throws Exception {
162+ // Given
163+ server .open (LOCALHOST , PORT , serverEvents );
164+ listenerEvents .newSession (session , information );
165+ CompletableFuture <Confirmation > internalFuture = new CompletableFuture <>();
166+ when (promiseRepository .createPromise (any ())).thenReturn (internalFuture );
167+
168+ // When
169+ CompletableFuture <Confirmation > returnedFuture = server .send (sessionIndex , request );
170+ TestConfirmation confirmation = new TestConfirmation ();
171+ internalFuture .complete (confirmation );
172+
173+ // Then
174+ assertThat (returnedFuture , is (internalFuture ));
175+ assertThat (returnedFuture .isDone (), is (true ));
176+ assertThat (returnedFuture .get (), is (confirmation ));
177+ verify (session , times (1 )).removeRequest (any ());
178+ verify (promiseRepository , times (1 )).removePromise (any ());
179+ }
180+
181+ @ Test
182+ public void send_aMessage_promiseCompletesExceptionally () throws Exception {
183+ // Given
184+ server .open (LOCALHOST , PORT , serverEvents );
185+ listenerEvents .newSession (session , information );
186+ CompletableFuture <Confirmation > internalFuture = new CompletableFuture <>();
187+ when (promiseRepository .createPromise (any ())).thenReturn (internalFuture );
188+
189+ // When
190+ CompletableFuture <Confirmation > returnedFuture = server .send (sessionIndex , request );
191+ internalFuture .completeExceptionally (new IllegalStateException ());
192+
193+ // Then
194+ assertThat (returnedFuture , is (internalFuture ));
195+ assertThat (returnedFuture .isDone (), is (true ));
196+ assertThat (returnedFuture .isCompletedExceptionally (), is (true ));
197+ ExecutionException executionException = assertThrows (ExecutionException .class , returnedFuture ::get );
198+ assertThat (executionException .getCause ().getClass (), is (equalTo (IllegalStateException .class )));
199+ verify (session , times (1 )).removeRequest (any ());
200+ verify (promiseRepository , times (1 )).removePromise (any ());
201+ }
202+
203+ @ Test
204+ public void send_aMessage_promiseCompletesWithTimeout () throws Exception {
205+ // Given
206+ server .open (LOCALHOST , PORT , serverEvents );
207+ listenerEvents .newSession (session , information );
208+ CompletableFuture <Confirmation > internalFuture = new CompletableFuture <>();
209+ when (promiseRepository .createPromise (any ())).thenReturn (internalFuture );
210+
211+ // When
212+ CompletableFuture <Confirmation > returnedFuture = server .send (sessionIndex , request );
213+ // If the client uses at least Java 9, it could use CompletableFuture::orTimeout(..).
214+ returnedFuture .orTimeout (50 , TimeUnit .MILLISECONDS );
215+ assertThat (returnedFuture .isDone (), is (false ));
216+ Thread .sleep (100 );
217+ // .. alternatively, it can be implemented manually
218+ // returnedFuture.completeExceptionally(new TimeoutException());
219+
220+ // Then
221+ assertThat (returnedFuture , is (internalFuture ));
222+ assertThat (returnedFuture .isDone (), is (true ));
223+ assertThat (returnedFuture .isCompletedExceptionally (), is (true ));
224+ ExecutionException executionException = assertThrows (ExecutionException .class , returnedFuture ::get );
225+ assertThat (executionException .getCause ().getClass (), is (equalTo (TimeoutException .class )));
226+ verify (session , times (1 )).removeRequest (any ());
227+ verify (promiseRepository , times (1 )).removePromise (any ());
228+ }
146229}
0 commit comments