fix(housekeeping): clear poll question options
This commit is contained in:
1 parent
51eecd0e72
commit
766e7e20c8
2 files changed
+69
-1
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { executeHousekeepingCommand } from "@/actions/housekeeping-command";
|
||||
import { PERMS } from "@/lib/permission-slugs";
|
||||
import {
|
||||
fail,
|
||||
@@ -12,6 +13,30 @@ import type {
|
||||
} from "../queries/content-queries";
|
||||
import { ContentPollWorkflow } from "./poll-workflow";
|
||||
|
||||
const { actionCallbacks } = vi.hoisted(() => ({
|
||||
actionCallbacks: [] as Array<
|
||||
(previous: unknown, formData: FormData) => Promise<unknown>
|
||||
>,
|
||||
}));
|
||||
|
||||
vi.mock("react", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("react")>();
|
||||
return {
|
||||
...actual,
|
||||
useActionState: (
|
||||
action: (previous: unknown, formData: FormData) => Promise<unknown>,
|
||||
initialState: unknown,
|
||||
) => {
|
||||
actionCallbacks.push(action);
|
||||
return [initialState, vi.fn(), false] as const;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("@/actions/housekeeping-command", () => ({
|
||||
executeHousekeepingCommand: vi.fn(),
|
||||
}));
|
||||
|
||||
function context(granted: readonly string[]): HousekeepingCapabilityContext {
|
||||
const permissions = new Set(granted);
|
||||
return {
|
||||
@@ -118,6 +143,11 @@ function renderList(
|
||||
}
|
||||
|
||||
describe("Content Poll workflow", () => {
|
||||
beforeEach(() => {
|
||||
actionCallbacks.length = 0;
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("renders explicit loading, forbidden, dependency-error, empty, and malformed states", () => {
|
||||
expect(renderList(viewer)).toContain('data-housekeeping-state="loading"');
|
||||
expect(
|
||||
@@ -286,6 +316,43 @@ describe("Content Poll workflow", () => {
|
||||
expect(html.match(/name="reason"/gu)).toHaveLength(3);
|
||||
});
|
||||
|
||||
it("submits empty options when changing a choice question to text", async () => {
|
||||
vi.mocked(executeHousekeepingCommand).mockResolvedValue(
|
||||
ok({}, "question-text-update"),
|
||||
);
|
||||
renderToStaticMarkup(
|
||||
<ContentPollWorkflow
|
||||
title="Poll detail"
|
||||
context={editor}
|
||||
result={ok(data([pollItem]), "detail-edit-submit")}
|
||||
routeId="content.engagement.poll-detail"
|
||||
list={list}
|
||||
/>,
|
||||
);
|
||||
const questionUpdate = actionCallbacks[1];
|
||||
if (!questionUpdate)
|
||||
throw new Error("Question update action was not bound");
|
||||
const formData = new FormData();
|
||||
formData.set("question", "Pick a colour");
|
||||
formData.set("type", "text");
|
||||
formData.set("sortOrder", "0");
|
||||
formData.set("options", "");
|
||||
|
||||
await questionUpdate(null, formData);
|
||||
|
||||
expect(executeHousekeepingCommand).toHaveBeenCalledWith({
|
||||
commandId: "content.engagement.poll-question.change",
|
||||
input: {
|
||||
action: "update",
|
||||
id: "21",
|
||||
question: "Pick a colour",
|
||||
type: "text",
|
||||
sortOrder: 0,
|
||||
options: "",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("distinguishes true not-found detail from malformed successful data", () => {
|
||||
const render = (items: ContentQueryData["items"]) =>
|
||||
renderToStaticMarkup(
|
||||
|
||||
@@ -184,6 +184,7 @@ function questionFields(
|
||||
name: "options",
|
||||
label: "Options (one per line)",
|
||||
type: "textarea",
|
||||
emptyValue: "",
|
||||
maxLength: 20_000,
|
||||
defaultValue: question?.options.join("\n"),
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user