Direct catalog picks walk name, description, and photo, then stakeholders; leftover drafts no longer skip that path. In-flow template picks keep community identity. Exit on a direct template preview leaves immediately because nothing has been collected yet. Co-authored-by: Cursor <cursoragent@cursor.com>
136 lines
4.1 KiB
TypeScript
136 lines
4.1 KiB
TypeScript
import { renderHook, act } from "@testing-library/react";
|
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
import type { CreateFlowState } from "../../../app/(app)/create/types";
|
|
import { useTemplateReviewActions } from "../../../app/(app)/create/hooks/useTemplateReviewActions";
|
|
import { loadTemplateReviewBySlug } from "../../../lib/create/loadTemplateReviewBySlug";
|
|
|
|
vi.mock("../../../lib/create/loadTemplateReviewBySlug", () => ({
|
|
loadTemplateReviewBySlug: vi.fn(),
|
|
}));
|
|
|
|
const templateBody = {
|
|
sections: [
|
|
{
|
|
categoryName: "Communication",
|
|
entries: [{ title: "Signal" }],
|
|
},
|
|
],
|
|
};
|
|
|
|
const loadedTemplate = {
|
|
ok: true as const,
|
|
template: {
|
|
id: "t1",
|
|
slug: "mutual-aid-mondays",
|
|
title: "Mutual Aid Mondays",
|
|
category: null,
|
|
description: null,
|
|
body: templateBody,
|
|
sortOrder: 0,
|
|
featured: false,
|
|
},
|
|
};
|
|
|
|
describe("useTemplateReviewActions", () => {
|
|
const router = { push: vi.fn() };
|
|
const updateState = vi.fn();
|
|
const markCreateFlowInteraction = vi.fn();
|
|
let applied: CreateFlowState | undefined;
|
|
const replaceState = vi.fn(
|
|
(updater: (_prev: CreateFlowState) => CreateFlowState) => {
|
|
applied = updater({});
|
|
},
|
|
);
|
|
|
|
beforeEach(() => {
|
|
vi.mocked(loadTemplateReviewBySlug).mockReset();
|
|
vi.mocked(loadTemplateReviewBySlug).mockResolvedValue(loadedTemplate);
|
|
router.push.mockReset();
|
|
updateState.mockReset();
|
|
markCreateFlowInteraction.mockReset();
|
|
replaceState.mockClear();
|
|
applied = undefined;
|
|
});
|
|
|
|
function renderActions(
|
|
state: CreateFlowState,
|
|
fromCreateWizard = false,
|
|
) {
|
|
return renderHook(() =>
|
|
useTemplateReviewActions({
|
|
pathname: "/create/review-template/mutual-aid-mondays",
|
|
state,
|
|
updateState,
|
|
replaceState,
|
|
router,
|
|
fromCreateWizard,
|
|
markCreateFlowInteraction,
|
|
}),
|
|
);
|
|
}
|
|
|
|
it("direct Use without changes walks identity from community-name", async () => {
|
|
const { result } = renderActions({});
|
|
|
|
await act(async () => {
|
|
await result.current.handleUseWithoutChanges();
|
|
});
|
|
|
|
expect(markCreateFlowInteraction).toHaveBeenCalled();
|
|
expect(router.push).toHaveBeenCalledWith("/create/community-name");
|
|
expect(applied?.pendingTemplateAction).toEqual({
|
|
slug: "mutual-aid-mondays",
|
|
mode: "useWithoutChanges",
|
|
});
|
|
});
|
|
|
|
it("direct Use without changes ignores a leftover draft title", async () => {
|
|
replaceState.mockImplementation(
|
|
(updater: (_prev: CreateFlowState) => CreateFlowState) => {
|
|
applied = updater({
|
|
title: "Neighborhood",
|
|
communityContext: "Stale description",
|
|
currentStep: "confirm-stakeholders",
|
|
});
|
|
},
|
|
);
|
|
const { result } = renderActions({ title: "Neighborhood" });
|
|
|
|
await act(async () => {
|
|
await result.current.handleUseWithoutChanges();
|
|
});
|
|
|
|
expect(router.push).toHaveBeenCalledWith("/create/community-name");
|
|
expect(applied?.title).toBeUndefined();
|
|
expect(applied?.communityContext).toBeUndefined();
|
|
expect(applied?.currentStep).toBeUndefined();
|
|
expect(applied?.pendingTemplateAction?.mode).toBe("useWithoutChanges");
|
|
});
|
|
|
|
it("in-flow Use without changes skips identity and keeps the community name", async () => {
|
|
replaceState.mockImplementation(
|
|
(updater: (_prev: CreateFlowState) => CreateFlowState) => {
|
|
applied = updater({
|
|
title: "Neighborhood",
|
|
communityContext: "We meet weekly",
|
|
templateReviewEntryFromCreateFlow: true,
|
|
});
|
|
},
|
|
);
|
|
const { result } = renderActions(
|
|
{ title: "Neighborhood", templateReviewEntryFromCreateFlow: true },
|
|
true,
|
|
);
|
|
|
|
await act(async () => {
|
|
await result.current.handleUseWithoutChanges();
|
|
});
|
|
|
|
expect(router.push).toHaveBeenCalledWith("/create/confirm-stakeholders");
|
|
expect(applied?.title).toBe("Neighborhood");
|
|
expect(applied?.communityContext).toBe("We meet weekly");
|
|
expect(applied?.pendingTemplateAction).toBeUndefined();
|
|
expect(applied?.templateReviewBackSlug).toBe("mutual-aid-mondays");
|
|
});
|
|
});
|