865c6c1d1e
Moves FileViewer, EditorModal, ConfirmDeleteModal, ToastNotice, MdItemList, ScopeBadge, and the shared atoms (Empty/SkeletonRows/CopyButton/formatBytes) into client/src/components/config/ so the upcoming Codex config panel can reuse them. EditorModal now takes a fetchContent callback instead of calling api.ccConfig.file itself; CcConfig.tsx supplies the Claude-specific fetcher. The moved EditorState/ConfirmDeleteState type field widens from CcArtifactType to string so non-Claude callers can use them too, with a cast at the two remaining Claude-specific call sites in CcConfig.tsx.
49 lines
1.6 KiB
TypeScript
49 lines
1.6 KiB
TypeScript
/**
|
|
* @file EditorModal.test.tsx
|
|
* @description Unit tests for the tool-agnostic `EditorModal`: it must load
|
|
* existing content through the injected `fetchContent` callback rather than
|
|
* a hardcoded API, and must refuse to save a create with no name.
|
|
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
|
*/
|
|
|
|
import { describe, it, expect, vi } from "vitest";
|
|
import { render, screen } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { EditorModal } from "../EditorModal";
|
|
|
|
describe("EditorModal", () => {
|
|
it("loads the existing body through the injected fetcher, not a hardcoded API", async () => {
|
|
const fetchContent = vi.fn().mockResolvedValue("old body");
|
|
render(
|
|
<EditorModal
|
|
state={{
|
|
mode: "edit",
|
|
type: "rules",
|
|
scope: "user",
|
|
name: "default",
|
|
filePath: "/r/default.rules",
|
|
}}
|
|
fetchContent={fetchContent}
|
|
onClose={() => {}}
|
|
onSave={async () => {}}
|
|
/>
|
|
);
|
|
expect(fetchContent).toHaveBeenCalledWith("/r/default.rules");
|
|
expect(await screen.findByDisplayValue("old body")).toBeInTheDocument();
|
|
});
|
|
|
|
it("refuses to save a create with no name", async () => {
|
|
const onSave = vi.fn();
|
|
render(
|
|
<EditorModal
|
|
state={{ mode: "create", type: "agents", defaultScope: "user", template: "" }}
|
|
fetchContent={async () => ""}
|
|
onClose={() => {}}
|
|
onSave={onSave}
|
|
/>
|
|
);
|
|
await userEvent.click(screen.getByRole("button", { name: /save/i }));
|
|
expect(onSave).not.toHaveBeenCalled();
|
|
});
|
|
});
|