mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
test(webchat): align stream assertions with delta batching
This commit is contained in:
parent
bfc5417508
commit
00d774fb85
@ -1,5 +1,6 @@
|
|||||||
package vip.mate.channel.webchat;
|
package vip.mate.channel.webchat;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -84,6 +85,7 @@ import static org.mockito.ArgumentMatchers.isNull;
|
|||||||
})
|
})
|
||||||
class WebChatStreamE2ETest {
|
class WebChatStreamE2ETest {
|
||||||
|
|
||||||
|
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||||
private static final String SECRET = "webchat-it-secret-0123456789";
|
private static final String SECRET = "webchat-it-secret-0123456789";
|
||||||
private static final String API_KEY = "testkey1e2etest01"; // key8 = "testkey1"
|
private static final String API_KEY = "testkey1e2etest01"; // key8 = "testkey1"
|
||||||
private static final long CHANNEL_ID = 9_148_001L;
|
private static final long CHANNEL_ID = 9_148_001L;
|
||||||
@ -224,10 +226,23 @@ class WebChatStreamE2ETest {
|
|||||||
return rows.isEmpty() ? null : rows.get(0);
|
return rows.isEmpty() ? null : rows.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String concatenatedContent(List<SseEvent> events) {
|
||||||
|
return events.stream()
|
||||||
|
.filter(e -> "content_delta".equals(e.name))
|
||||||
|
.map(e -> {
|
||||||
|
try {
|
||||||
|
return OBJECT_MAPPER.readTree(e.data).path("text").asText();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new AssertionError("Invalid content_delta JSON: " + e.data, ex);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.reduce("", String::concat);
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== tests ====================
|
// ==================== tests ====================
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("happy path: meta → content_delta* → done; assistant reply persisted")
|
@DisplayName("happy path: meta → batched content_delta* → done; assistant reply persisted")
|
||||||
void happyPath() throws Exception {
|
void happyPath() throws Exception {
|
||||||
org.mockito.Mockito.when(agentService.chatStructuredStream(
|
org.mockito.Mockito.when(agentService.chatStructuredStream(
|
||||||
eq(AGENT_ID), anyString(), anyString(), anyString(), isNull(), any()))
|
eq(AGENT_ID), anyString(), anyString(), anyString(), isNull(), any()))
|
||||||
@ -240,7 +255,8 @@ class WebChatStreamE2ETest {
|
|||||||
streamPost(API_KEY, "{\"message\":\"hi\",\"visitorId\":\"" + visitorId + "\"}"));
|
streamPost(API_KEY, "{\"message\":\"hi\",\"visitorId\":\"" + visitorId + "\"}"));
|
||||||
|
|
||||||
List<String> names = events.stream().map(e -> e.name).toList();
|
List<String> names = events.stream().map(e -> e.name).toList();
|
||||||
assertThat(names).containsSequence("meta", "content_delta", "content_delta", "done");
|
assertThat(names).containsSequence("meta", "content_delta", "done");
|
||||||
|
assertThat(concatenatedContent(events)).isEqualTo("Hello world!");
|
||||||
|
|
||||||
SseEvent meta = events.stream().filter(e -> "meta".equals(e.name)).findFirst().orElseThrow();
|
SseEvent meta = events.stream().filter(e -> "meta".equals(e.name)).findFirst().orElseThrow();
|
||||||
assertThat(meta.data)
|
assertThat(meta.data)
|
||||||
@ -310,8 +326,9 @@ class WebChatStreamE2ETest {
|
|||||||
byName.computeIfAbsent(e.name, k -> new ArrayList<>()).add(e);
|
byName.computeIfAbsent(e.name, k -> new ArrayList<>()).add(e);
|
||||||
}
|
}
|
||||||
assertThat(byName).containsKeys("meta", "thinking_delta", "content_delta", "done");
|
assertThat(byName).containsKeys("meta", "thinking_delta", "content_delta", "done");
|
||||||
// 2 content_delta events, 1 thinking_delta, exactly one done.
|
// Adjacent upstream chunks may be coalesced on the SSE wire. The
|
||||||
assertThat(byName.get("content_delta")).hasSize(2);
|
// protocol guarantees complete ordered text, not one event per chunk.
|
||||||
|
assertThat(concatenatedContent(events)).isEqualTo("Final answer.");
|
||||||
assertThat(byName.get("thinking_delta")).hasSize(1);
|
assertThat(byName.get("thinking_delta")).hasSize(1);
|
||||||
assertThat(byName.get("done")).hasSize(1);
|
assertThat(byName.get("done")).hasSize(1);
|
||||||
assertThat(byName.get("meta")).hasSize(1);
|
assertThat(byName.get("meta")).hasSize(1);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user