File size: 4,251 Bytes
63522a5 | 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 | import { renderHook, waitFor } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useParams } from "react-router";
import { useUserConversation } from "./query/use-user-conversation";
import { useAppTitle } from "./use-app-title";
import { useConversationStateStore } from "#/stores/conversation-state-store";
import { ExecutionStatus } from "#/types/agent-server/core/base/common";
const renderAppTitleHook = () =>
renderHook(() => useAppTitle(), {
wrapper: ({ children }) => (
<QueryClientProvider client={new QueryClient()}>
{children}
</QueryClientProvider>
),
});
vi.mock("./query/use-user-conversation");
vi.mock("react-router", async () => {
const actual = await vi.importActual("react-router");
return {
...actual,
useParams: vi.fn(),
};
});
describe("useAppTitle", () => {
const mockUseUserConversation = vi.mocked(useUserConversation);
const mockUseParams = vi.mocked(useParams);
beforeEach(() => {
// @ts-expect-error - only returning partial config for test
mockUseUserConversation.mockReturnValue({ data: null });
mockUseParams.mockReturnValue({});
useConversationStateStore.getState().reset();
});
it("returns the OSS app title outside conversations", async () => {
const { result } = renderAppTitleHook();
await waitFor(() => expect(result.current).toBe("OpenHands"));
});
it("returns the conversation title with the OSS app name", async () => {
mockUseParams.mockReturnValue({ conversationId: "123" });
mockUseUserConversation.mockReturnValue({
// @ts-expect-error - only returning partial config for test
data: { title: "My Conversation" },
});
const { result } = renderAppTitleHook();
await waitFor(() =>
expect(result.current).toBe("My Conversation | OpenHands"),
);
});
it("returns the app name while conversation data is loading", async () => {
mockUseParams.mockReturnValue({ conversationId: "123" });
// @ts-expect-error - only returning partial config for test
mockUseUserConversation.mockReturnValue({ data: undefined });
const { result } = renderAppTitleHook();
await waitFor(() => expect(result.current).toBe("OpenHands"));
});
it.each([
[ExecutionStatus.RUNNING, "🟢"],
[ExecutionStatus.FINISHED, "✅"],
[ExecutionStatus.IDLE, "✅"],
[ExecutionStatus.WAITING_FOR_CONFIRMATION, "✅"],
[ExecutionStatus.PAUSED, "⚪"],
[ExecutionStatus.ERROR, "🔴"],
[ExecutionStatus.STUCK, "🔴"],
])(
"prefixes the title with %s emoji for execution status %s",
async (status, emoji) => {
mockUseParams.mockReturnValue({ conversationId: "123" });
mockUseUserConversation.mockReturnValue({
// @ts-expect-error - only returning partial config for test
data: { title: "My Conversation" },
});
useConversationStateStore.getState().setExecutionStatus("123", status);
const { result } = renderAppTitleHook();
await waitFor(() =>
expect(result.current).toBe(`${emoji} My Conversation | OpenHands`),
);
},
);
it("falls back to the conversation's execution_status when the live store is empty", async () => {
mockUseParams.mockReturnValue({ conversationId: "123" });
mockUseUserConversation.mockReturnValue({
// @ts-expect-error - only returning partial config for test
data: {
title: "My Conversation",
execution_status: ExecutionStatus.RUNNING,
},
});
const { result } = renderAppTitleHook();
await waitFor(() =>
expect(result.current).toBe("🟢 My Conversation | OpenHands"),
);
});
it("does not add an emoji when in a conversation but execution status is unknown", async () => {
mockUseParams.mockReturnValue({ conversationId: "123" });
mockUseUserConversation.mockReturnValue({
// @ts-expect-error - only returning partial config for test
data: { title: "My Conversation" },
});
const { result } = renderAppTitleHook();
await waitFor(() =>
expect(result.current).toBe("My Conversation | OpenHands"),
);
});
});
|