-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathStandardWebSocketClientMultiMessageTest.java
More file actions
135 lines (108 loc) · 4.99 KB
/
StandardWebSocketClientMultiMessageTest.java
File metadata and controls
135 lines (108 loc) · 4.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package nostr.client.springwebsocket;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.when;
/**
* Tests that StandardWebSocketClient correctly accumulates multiple messages
* before completing when a termination message (EOSE, OK) is received.
*/
class StandardWebSocketClientMultiMessageTest {
@Test
void testAccumulatesMessagesUntilEose() throws Exception {
WebSocketSession session = Mockito.mock(WebSocketSession.class);
when(session.isOpen()).thenReturn(true);
StandardWebSocketClient client = new StandardWebSocketClient(session, 5000, 100);
// Simulate relay responses when send is called
CountDownLatch sendLatch = new CountDownLatch(1);
doAnswer(invocation -> {
sendLatch.countDown();
return null;
}).when(session).sendMessage(any(TextMessage.class));
// Start send in background thread
Thread sendThread = new Thread(() -> {
try {
List<String> result = client.send("[\"REQ\",\"sub1\",{}]");
assertEquals(2, result.size(), "Should receive EVENT + EOSE");
assertTrue(result.get(0).contains("EVENT"), "First message should be EVENT");
assertTrue(result.get(1).contains("EOSE"), "Second message should be EOSE");
} catch (Exception e) {
throw new RuntimeException(e);
}
});
sendThread.start();
// Wait for send to start
assertTrue(sendLatch.await(1, TimeUnit.SECONDS), "Send should have started");
Thread.sleep(50); // Small delay for send() to set up pendingRequest
// Simulate EVENT message (not termination - should NOT complete)
client.handleTextMessage(session, new TextMessage("[\"EVENT\",\"sub1\",{\"id\":\"abc\"}]"));
// Small delay to ensure processing
Thread.sleep(50);
// Simulate EOSE message (termination - should complete)
client.handleTextMessage(session, new TextMessage("[\"EOSE\",\"sub1\"]"));
// Wait for send thread to complete
sendThread.join(2000);
}
@Test
void testCompletesImmediatelyOnOk() throws Exception {
WebSocketSession session = Mockito.mock(WebSocketSession.class);
when(session.isOpen()).thenReturn(true);
StandardWebSocketClient client = new StandardWebSocketClient(session, 5000, 100);
CountDownLatch sendLatch = new CountDownLatch(1);
doAnswer(invocation -> {
sendLatch.countDown();
return null;
}).when(session).sendMessage(any(TextMessage.class));
Thread sendThread = new Thread(() -> {
try {
List<String> result = client.send("[\"EVENT\",{\"id\":\"abc\"}]");
assertEquals(1, result.size(), "Should receive just OK");
assertTrue(result.get(0).contains("OK"), "Message should be OK");
} catch (Exception e) {
throw new RuntimeException(e);
}
});
sendThread.start();
assertTrue(sendLatch.await(1, TimeUnit.SECONDS));
Thread.sleep(50);
// Simulate OK message (termination - should complete immediately)
client.handleTextMessage(session, new TextMessage("[\"OK\",\"abc\",true,\"\"]"));
sendThread.join(2000);
}
@Test
void testEventWithoutEoseTimesOut() throws Exception {
WebSocketSession session = Mockito.mock(WebSocketSession.class);
when(session.isOpen()).thenReturn(true);
// Short timeout for this test
StandardWebSocketClient client = new StandardWebSocketClient(session, 200, 50);
CountDownLatch sendLatch = new CountDownLatch(1);
doAnswer(invocation -> {
sendLatch.countDown();
return null;
}).when(session).sendMessage(any(TextMessage.class));
Thread sendThread = new Thread(() -> {
try {
List<String> result = client.send("[\"REQ\",\"sub1\",{}]");
// Without EOSE, should timeout and return empty
assertTrue(result.isEmpty(), "Should timeout and return empty list");
} catch (Exception e) {
throw new RuntimeException(e);
}
});
sendThread.start();
assertTrue(sendLatch.await(1, TimeUnit.SECONDS));
Thread.sleep(50);
// Simulate EVENT message but no EOSE
client.handleTextMessage(session, new TextMessage("[\"EVENT\",\"sub1\",{\"id\":\"abc\"}]"));
// Don't send EOSE - should timeout
sendThread.join(1000);
}
}