mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-10-04 02:33:47 +10:00
test: remove redundant cases and repeated setup
This commit is contained in:
@@ -478,174 +478,6 @@ describe("agentService.messages.send", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("merges an answered ask-user-question tool result into the existing assistant message", async () => {
|
||||
const activeThread = buildActiveThread();
|
||||
const userMessage = {
|
||||
id: "message-user-1",
|
||||
userId: "user-1",
|
||||
threadId: "thread-1",
|
||||
role: "user",
|
||||
status: "completed",
|
||||
sequence: 0,
|
||||
uiMessage: {
|
||||
id: "ui-user-1",
|
||||
role: "user",
|
||||
parts: [{ type: "text", text: "Change the name" }],
|
||||
},
|
||||
};
|
||||
const unansweredAssistantMessage = {
|
||||
id: "message-assistant-1",
|
||||
userId: "user-1",
|
||||
threadId: "thread-1",
|
||||
role: "assistant",
|
||||
status: "completed",
|
||||
sequence: 1,
|
||||
uiMessage: {
|
||||
id: "ui-assistant-1",
|
||||
role: "assistant",
|
||||
parts: [
|
||||
{
|
||||
type: "tool-ask_user_question",
|
||||
toolCallId: "call-1",
|
||||
state: "input-available",
|
||||
input: {
|
||||
question: "How broadly should I rename?",
|
||||
choices: ["Only change the main resume header name"],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const answeredAssistantMessage = {
|
||||
...unansweredAssistantMessage,
|
||||
uiMessage: {
|
||||
...unansweredAssistantMessage.uiMessage,
|
||||
parts: [
|
||||
{
|
||||
type: "tool-ask_user_question",
|
||||
toolCallId: "call-1",
|
||||
state: "output-available",
|
||||
input: {
|
||||
question: "How broadly should I rename?",
|
||||
choices: ["Only change the main resume header name"],
|
||||
},
|
||||
output: "Only change the main resume header name",
|
||||
callProviderMetadata: { openai: { itemId: "fc_duplicate_item" } },
|
||||
resultProviderMetadata: { openai: { itemId: "fc_duplicate_item" } },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const answeredAssistantModelInput = {
|
||||
...answeredAssistantMessage.uiMessage,
|
||||
parts: [
|
||||
{
|
||||
type: "tool-ask_user_question",
|
||||
toolCallId: "call-1",
|
||||
state: "output-available",
|
||||
input: {
|
||||
question: "How broadly should I rename?",
|
||||
choices: ["Only change the main resume header name"],
|
||||
},
|
||||
output: "Only change the main resume header name",
|
||||
},
|
||||
],
|
||||
};
|
||||
const updateSets: unknown[] = [];
|
||||
|
||||
dbMock.select
|
||||
.mockImplementationOnce(() => selectLimitResult([activeThread]))
|
||||
.mockImplementationOnce(() => selectOrderByResult([userMessage, unansweredAssistantMessage]))
|
||||
.mockImplementationOnce(() => selectOrderByResult([userMessage, answeredAssistantMessage]));
|
||||
|
||||
dbMock.update.mockImplementation(() => ({
|
||||
set: vi.fn((value) => {
|
||||
updateSets.push(value);
|
||||
return { where: vi.fn(async () => undefined) };
|
||||
}),
|
||||
}));
|
||||
|
||||
claimActiveAgentRunMock.mockResolvedValue(true);
|
||||
aiProvidersServiceMock.getRunnableById.mockResolvedValue({
|
||||
id: "provider-1",
|
||||
provider: "openai",
|
||||
model: "gpt-5",
|
||||
apiKey: "secret",
|
||||
baseURL: null,
|
||||
});
|
||||
aiProvidersServiceMock.markUsed.mockResolvedValue(undefined);
|
||||
|
||||
const [{ convertToModelMessages, ToolLoopAgent }, { agentStreamLifecycle }] = await Promise.all([
|
||||
import("ai"),
|
||||
import("./streams"),
|
||||
]);
|
||||
vi.mocked(convertToModelMessages).mockResolvedValue([
|
||||
{ role: "user", content: [{ type: "text", text: "Change the name" }] },
|
||||
{
|
||||
role: "assistant",
|
||||
content: [{ type: "tool-call", toolCallId: "call-1", toolName: "ask_user_question", input: {} }],
|
||||
},
|
||||
{
|
||||
role: "tool",
|
||||
content: [
|
||||
{
|
||||
type: "tool-result",
|
||||
toolCallId: "call-1",
|
||||
toolName: "ask_user_question",
|
||||
output: "Only change the main resume header name",
|
||||
},
|
||||
],
|
||||
},
|
||||
] as never);
|
||||
class MockToolLoopAgent {
|
||||
stream = vi.fn(async () => ({ toUIMessageStream: vi.fn(() => new ReadableStream()) }));
|
||||
}
|
||||
vi.mocked(ToolLoopAgent).mockImplementation(MockToolLoopAgent as never);
|
||||
vi.mocked(agentStreamLifecycle.create).mockResolvedValue(new ReadableStream());
|
||||
vi.mocked(streamToEventIterator).mockReturnValue("iterator" as never);
|
||||
|
||||
const { agentService } = await import("./service");
|
||||
|
||||
await agentService.messages.send({
|
||||
threadId: "thread-1",
|
||||
userId: "user-1",
|
||||
message: {
|
||||
id: "ui-assistant-1",
|
||||
role: "assistant",
|
||||
parts: [
|
||||
{
|
||||
type: "tool-ask_user_question",
|
||||
toolCallId: "call-1",
|
||||
state: "output-available",
|
||||
input: {
|
||||
question: "How broadly should I rename?",
|
||||
choices: ["Only change the main resume header name"],
|
||||
},
|
||||
output: "Only change the main resume header name",
|
||||
},
|
||||
],
|
||||
// biome-ignore lint/suspicious/noExplicitAny: minimal fixture for unit test
|
||||
} as any,
|
||||
});
|
||||
|
||||
expect(dbMock.insert).not.toHaveBeenCalled();
|
||||
expect(updateSets).toContainEqual(
|
||||
expect.objectContaining({
|
||||
uiMessage: expect.objectContaining({
|
||||
parts: [
|
||||
expect.objectContaining({
|
||||
type: "tool-ask_user_question",
|
||||
toolCallId: "call-1",
|
||||
state: "output-available",
|
||||
output: "Only change the main resume header name",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect(convertToModelMessages).toHaveBeenCalledWith([userMessage.uiMessage, answeredAssistantModelInput]);
|
||||
});
|
||||
|
||||
// Regression (defect 8): a question continuation streams into the SAME uiMessage id; onFinish
|
||||
// must upsert the existing assistant row instead of inserting a duplicate row.
|
||||
it("continues the existing assistant row on a question continuation instead of inserting a duplicate", async () => {
|
||||
@@ -673,27 +505,41 @@ describe("agentService.messages.send", () => {
|
||||
parts: [{ type: "tool-ask_user_question", toolCallId: "call-1", state: "input-available", input: question }],
|
||||
},
|
||||
};
|
||||
const answeredAssistantModelInput = {
|
||||
...unansweredAssistantMessage.uiMessage,
|
||||
parts: [
|
||||
{
|
||||
type: "tool-ask_user_question",
|
||||
toolCallId: "call-1",
|
||||
state: "output-available",
|
||||
input: question,
|
||||
output: "Only the header",
|
||||
},
|
||||
],
|
||||
};
|
||||
const answeredAssistantMessage = {
|
||||
...unansweredAssistantMessage,
|
||||
uiMessage: {
|
||||
...unansweredAssistantMessage.uiMessage,
|
||||
parts: [
|
||||
{
|
||||
type: "tool-ask_user_question",
|
||||
toolCallId: "call-1",
|
||||
state: "output-available",
|
||||
input: question,
|
||||
output: "Only the header",
|
||||
},
|
||||
],
|
||||
...answeredAssistantModelInput,
|
||||
parts: answeredAssistantModelInput.parts.map((part) => ({
|
||||
...part,
|
||||
callProviderMetadata: { openai: { itemId: "fc_duplicate_item" } },
|
||||
resultProviderMetadata: { openai: { itemId: "fc_duplicate_item" } },
|
||||
})),
|
||||
},
|
||||
};
|
||||
const updateSets: unknown[] = [];
|
||||
|
||||
dbMock.select
|
||||
.mockImplementationOnce(() => selectLimitResult([activeThread]))
|
||||
.mockImplementationOnce(() => selectOrderByResult([userMessage, unansweredAssistantMessage]))
|
||||
.mockImplementationOnce(() => selectOrderByResult([userMessage, answeredAssistantMessage]));
|
||||
dbMock.update.mockImplementation(() => ({ set: vi.fn(() => ({ where: vi.fn(async () => undefined) })) }));
|
||||
dbMock.update.mockImplementation(() => ({
|
||||
set: vi.fn((value) => {
|
||||
updateSets.push(value);
|
||||
return { where: vi.fn(async () => undefined) };
|
||||
}),
|
||||
}));
|
||||
|
||||
claimActiveAgentRunMock.mockResolvedValue(true);
|
||||
aiProvidersServiceMock.getRunnableById.mockResolvedValue({
|
||||
@@ -735,9 +581,12 @@ describe("agentService.messages.send", () => {
|
||||
threadId: "thread-1",
|
||||
userId: "user-1",
|
||||
// biome-ignore lint/suspicious/noExplicitAny: minimal fixture for unit test
|
||||
message: answeredAssistantMessage.uiMessage as any,
|
||||
message: answeredAssistantModelInput as any,
|
||||
});
|
||||
|
||||
expect(updateSets).toContainEqual(expect.objectContaining({ uiMessage: answeredAssistantModelInput }));
|
||||
expect(convertToModelMessages).toHaveBeenCalledWith([userMessage.uiMessage, answeredAssistantModelInput]);
|
||||
|
||||
const onFinish = uiStreamOptions?.onFinish as (event: Record<string, unknown>) => Promise<void>;
|
||||
const continuedMessage = {
|
||||
...answeredAssistantMessage.uiMessage,
|
||||
|
||||
Reference in New Issue
Block a user