66import javafx .collections .ListChangeListener ;
77import org .junit .jupiter .api .BeforeAll ;
88import org .junit .jupiter .api .Test ;
9+ import org .junit .jupiter .api .Timeout ;
910
1011import java .util .concurrent .CountDownLatch ;
1112import java .util .concurrent .TimeUnit ;
1516import static org .assertj .core .api .Assertions .assertThat ;
1617
1718@ WireMockTest
19+ @ Timeout (10 ) // Global timeout för alla tester i klassen
1820class HelloModelTest {
1921
2022 @ BeforeAll
@@ -23,9 +25,8 @@ static void setupJavaFX() {
2325 if (!Platform .isFxApplicationThread ()) {
2426 Platform .startup (() -> {});
2527 }
26- } catch (UnsupportedOperationException e ) {
28+ } catch (IllegalStateException | UnsupportedOperationException e ) {
2729 System .out .println ("Headless environment detected – skipping JavaFX startup" );
28- } catch (IllegalStateException e ) {
2930 }
3031 }
3132
@@ -39,7 +40,8 @@ void shouldSendMessageThroughConnection() throws InterruptedException {
3940 CountDownLatch latch = new CountDownLatch (1 );
4041 model .sendMessageAsync (success -> latch .countDown ());
4142
42- assertThat (latch .await (1 , TimeUnit .SECONDS )).isTrue ();
43+ boolean completed = latch .await (5 , TimeUnit .SECONDS );
44+ assertThat (completed ).as ("Timed out waiting for message send" ).isTrue ();
4345 assertThat (connectionSpy .message ).isEqualTo ("Hello World" );
4446 }
4547
@@ -63,7 +65,8 @@ void shouldHandleMultipleConsecutiveSends() throws InterruptedException {
6365 latch .countDown ();
6466 });
6567
66- latch .await (1 , TimeUnit .SECONDS );
68+ boolean completed = latch .await (5 , TimeUnit .SECONDS );
69+ assertThat (completed ).as ("Timed out waiting for consecutive sends" ).isTrue ();
6770 assertThat (results [0 ]).isTrue ();
6871 assertThat (results [1 ]).isTrue ();
6972 assertThat (connectionSpy .message ).isEqualTo ("Second" );
@@ -87,7 +90,8 @@ void shouldRejectBlankMessages() throws InterruptedException {
8790 latch .countDown ();
8891 });
8992
90- latch .await (1 , TimeUnit .SECONDS );
93+ boolean completed = latch .await (5 , TimeUnit .SECONDS );
94+ assertThat (completed ).as ("Timed out waiting for blank message rejection" ).isTrue ();
9195 assertThat (wasSuccessful [0 ]).isFalse ();
9296 assertThat (connectionSpy .message ).isNull ();
9397 }
@@ -107,7 +111,8 @@ void shouldFailWhenSendingEmptyText() throws InterruptedException {
107111 latch .countDown ();
108112 });
109113
110- latch .await (1 , TimeUnit .SECONDS );
114+ boolean completed = latch .await (5 , TimeUnit .SECONDS );
115+ assertThat (completed ).as ("Timed out waiting for empty text rejection" ).isTrue ();
111116 assertThat (wasSuccessful [0 ]).isFalse ();
112117 assertThat (connectionSpy .message ).isNull ();
113118 }
@@ -126,7 +131,8 @@ void shouldFailWhenSendingNullMessage() throws InterruptedException {
126131 latch .countDown ();
127132 });
128133
129- latch .await (1 , TimeUnit .SECONDS );
134+ boolean completed = latch .await (5 , TimeUnit .SECONDS );
135+ assertThat (completed ).as ("Timed out waiting for null message rejection" ).isTrue ();
130136 assertThat (wasSuccessful [0 ]).isFalse ();
131137 assertThat (connectionSpy .message ).isNull ();
132138 }
@@ -153,7 +159,8 @@ public void receive(Consumer<NtfyMessageDto> messageHandler) { }
153159 latch .countDown ();
154160 });
155161
156- latch .await (1 , TimeUnit .SECONDS );
162+ boolean completed = latch .await (5 , TimeUnit .SECONDS );
163+ assertThat (completed ).as ("Timed out waiting for connection failure" ).isTrue ();
157164 assertThat (wasSuccessful [0 ]).isFalse ();
158165 assertThat (model .getMessageToSend ()).isEqualTo ("Fail this message" );
159166 }
@@ -174,17 +181,13 @@ public void receive(Consumer<NtfyMessageDto> messageHandler) { }
174181 CountDownLatch latch = new CountDownLatch (1 );
175182 boolean [] wasSuccessful = new boolean [1 ];
176183
177- try {
178- model .sendMessageAsync (success -> {
179- wasSuccessful [0 ] = success ;
180- latch .countDown ();
181- });
182- } catch (Exception ex ) {
183- wasSuccessful [0 ] = false ;
184+ model .sendMessageAsync (success -> {
185+ wasSuccessful [0 ] = success ;
184186 latch .countDown ();
185- }
187+ });
186188
187- latch .await (1 , TimeUnit .SECONDS );
189+ boolean completed = latch .await (5 , TimeUnit .SECONDS );
190+ assertThat (completed ).as ("Timed out waiting for exception handling" ).isTrue ();
188191 assertThat (wasSuccessful [0 ]).isFalse ();
189192 }
190193
@@ -206,7 +209,8 @@ void shouldAddIncomingMessageToList() throws InterruptedException {
206209
207210 connectionSpy .simulateIncoming (incomingMsg );
208211
209- assertThat (latch .await (1 , TimeUnit .SECONDS )).isTrue ();
212+ boolean completed = latch .await (5 , TimeUnit .SECONDS );
213+ assertThat (completed ).as ("Timed out waiting for incoming message" ).isTrue ();
210214 assertThat (model .getMessages ()).contains (incomingMsg );
211215 }
212216
@@ -224,7 +228,7 @@ void shouldDiscardNullIncomingMessage() throws InterruptedException {
224228
225229 connectionSpy .simulateIncoming (null );
226230
227- boolean messageAdded = latch .await (1 , TimeUnit .SECONDS );
231+ boolean messageAdded = latch .await (5 , TimeUnit .SECONDS );
228232 assertThat (messageAdded ).isFalse ();
229233 assertThat (model .getMessages ()).isEmpty ();
230234 }
@@ -247,7 +251,7 @@ void shouldIgnoreMessagesWithBlankContent() throws InterruptedException {
247251 connectionSpy .simulateIncoming (whitespaceMsg );
248252 connectionSpy .simulateIncoming (emptyMsg );
249253
250- boolean messageAdded = latch .await (1 , TimeUnit .SECONDS );
254+ boolean messageAdded = latch .await (5 , TimeUnit .SECONDS );
251255 assertThat (messageAdded ).isFalse ();
252256 assertThat (model .getMessages ()).isEmpty ();
253257 }
@@ -268,7 +272,7 @@ void shouldRejectAllInvalidIncomingMessages() throws InterruptedException {
268272 connectionSpy .simulateIncoming (new NtfyMessageDto ("id2" , 2 , "message" , "room" , " " ));
269273 connectionSpy .simulateIncoming (null );
270274
271- boolean messageAdded = latch .await (1 , TimeUnit .SECONDS );
275+ boolean messageAdded = latch .await (5 , TimeUnit .SECONDS );
272276 assertThat (messageAdded ).isFalse ();
273277 assertThat (model .getMessages ()).isEmpty ();
274278 }
@@ -286,7 +290,8 @@ void shouldCommunicateWithMockedServer(WireMockRuntimeInfo wmInfo) throws Interr
286290 CountDownLatch latch = new CountDownLatch (1 );
287291 model .sendMessageAsync (success -> latch .countDown ());
288292
289- assertThat (latch .await (1 , TimeUnit .SECONDS )).isTrue ();
293+ boolean completed = latch .await (5 , TimeUnit .SECONDS );
294+ assertThat (completed ).as ("Timed out waiting for server communication" ).isTrue ();
290295 verify (postRequestedFor (urlEqualTo ("/mytopic" ))
291296 .withRequestBody (matching ("Hello World" )));
292297 }
0 commit comments