mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 06:57:10 +00:00
98 lines
3.3 KiB
TypeScript
98 lines
3.3 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
|
|
import { createChatState, createChatStateStore } from "../../../src/features/chat/chat-state";
|
|
import { ThreadIdentityController } from "../../../src/features/chat/thread-identity-controller";
|
|
import type { RestoredThreadController } from "../../../src/features/chat/restored-thread-controller";
|
|
import type { RestoredThreadPlaceholderState } from "../../../src/features/chat/view-lifecycle";
|
|
import type { Thread } from "../../../src/generated/app-server/v2/Thread";
|
|
|
|
function thread(id: string, name: string | null = null): Thread {
|
|
return {
|
|
id,
|
|
sessionId: id,
|
|
forkedFromId: null,
|
|
preview: "",
|
|
ephemeral: false,
|
|
modelProvider: "openai",
|
|
createdAt: 0,
|
|
updatedAt: 0,
|
|
status: { type: "idle" },
|
|
path: null,
|
|
cwd: "/vault",
|
|
cliVersion: "test",
|
|
source: "appServer",
|
|
threadSource: null,
|
|
agentNickname: null,
|
|
agentRole: null,
|
|
gitInfo: null,
|
|
name,
|
|
turns: [],
|
|
};
|
|
}
|
|
|
|
function createController() {
|
|
const stateStore = createChatStateStore(createChatState());
|
|
const restoredPlaceholder = vi.fn<() => RestoredThreadPlaceholderState | null>(() => null);
|
|
const restoredRename = vi.fn();
|
|
const restoredThread = {
|
|
clear: vi.fn(),
|
|
isPending: vi.fn(() => false),
|
|
placeholder: restoredPlaceholder,
|
|
rename: restoredRename,
|
|
} as unknown as RestoredThreadController;
|
|
const host = {
|
|
stateStore,
|
|
restoredThread,
|
|
invalidateResumeWork: vi.fn(),
|
|
clearDeferredRestoredThreadHydration: vi.fn(),
|
|
resetThreadTurnPresence: vi.fn(),
|
|
notifyActiveThreadIdentityChanged: vi.fn(),
|
|
refreshTabHeader: vi.fn(),
|
|
refreshLiveState: vi.fn(),
|
|
render: vi.fn(),
|
|
};
|
|
return { controller: new ThreadIdentityController(host), host, restoredPlaceholder, restoredRename, stateStore };
|
|
}
|
|
|
|
describe("ThreadIdentityController", () => {
|
|
it("clears the active thread when it is archived", () => {
|
|
const { controller, host, stateStore } = createController();
|
|
stateStore.dispatch({
|
|
type: "thread/resumed",
|
|
thread: thread("thread"),
|
|
cwd: "/vault",
|
|
model: null,
|
|
reasoningEffort: null,
|
|
serviceTier: null,
|
|
approvalPolicy: null,
|
|
approvalsReviewer: null,
|
|
activePermissionProfile: null,
|
|
});
|
|
|
|
controller.notifyThreadArchived("thread");
|
|
|
|
expect(stateStore.getState().activeThreadId).toBeNull();
|
|
expect(host.invalidateResumeWork).toHaveBeenCalledOnce();
|
|
expect(host.resetThreadTurnPresence).toHaveBeenCalledWith(false);
|
|
expect(host.notifyActiveThreadIdentityChanged).toHaveBeenCalledOnce();
|
|
expect(host.render).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it("updates listed and restored thread titles on rename notifications", () => {
|
|
const { controller, host, restoredPlaceholder, restoredRename, stateStore } = createController();
|
|
stateStore.dispatch({ type: "thread/list-applied", threads: [thread("thread", "Old")] });
|
|
restoredPlaceholder.mockReturnValue({
|
|
kind: "placeholder",
|
|
threadId: "thread",
|
|
title: "Old",
|
|
explicitName: "Old",
|
|
loading: null,
|
|
});
|
|
|
|
controller.notifyThreadRenamed("thread", "New");
|
|
|
|
expect(stateStore.getState().listedThreads[0]?.name).toBe("New");
|
|
expect(restoredRename).toHaveBeenCalledWith("thread", "New");
|
|
expect(host.render).toHaveBeenCalledOnce();
|
|
});
|
|
});
|