Sign-in was clearing the staged file before it uploaded, and review only read the server URL, so a chosen logo disappeared after the upload step.
121 lines
3.8 KiB
TypeScript
121 lines
3.8 KiB
TypeScript
import { useSearchParams } from "next/navigation";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { useCreateFlow } from "../../app/(app)/create/context/CreateFlowContext";
|
|
import { PostLoginDraftTransfer } from "../../app/(app)/create/PostLoginDraftTransfer";
|
|
import {
|
|
CREATE_FLOW_ANONYMOUS_KEY,
|
|
CREATE_FLOW_TRANSFER_PENDING_KEY,
|
|
} from "../../app/(app)/create/utils/anonymousDraftStorage";
|
|
import { saveDraftToServer } from "../../lib/create/api";
|
|
import { flushPendingCommunityAvatar } from "../../lib/create/flushPendingCommunityAvatar";
|
|
import { clearPendingCommunityAvatarFile } from "../../lib/create/pendingCommunityAvatarUpload";
|
|
import {
|
|
renderWithProviders as render,
|
|
screen,
|
|
waitFor,
|
|
} from "../utils/test-utils";
|
|
import "@testing-library/jest-dom/vitest";
|
|
|
|
vi.mock("../../lib/create/api", () => ({
|
|
fetchDraftFromServer: vi.fn().mockResolvedValue(null),
|
|
saveDraftToServer: vi.fn().mockResolvedValue({ ok: true }),
|
|
}));
|
|
|
|
vi.mock("../../lib/create/flushPendingCommunityAvatar", () => ({
|
|
flushPendingCommunityAvatar: vi.fn(),
|
|
forgetFlushedCommunityAvatarUrl: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("../../lib/create/pendingCommunityAvatarUpload", () => ({
|
|
clearPendingCommunityAvatarFile: vi.fn().mockResolvedValue(undefined),
|
|
readPendingCommunityAvatarFile: vi.fn().mockResolvedValue(null),
|
|
storePendingCommunityAvatarFile: vi.fn(),
|
|
}));
|
|
|
|
function mockSearchParams(value: string) {
|
|
vi.mocked(useSearchParams).mockReturnValue(
|
|
new URLSearchParams(value) as NonNullable<
|
|
ReturnType<typeof useSearchParams>
|
|
>,
|
|
);
|
|
}
|
|
|
|
function StateProbe() {
|
|
const { state } = useCreateFlow();
|
|
return (
|
|
<div>
|
|
<span data-testid="title">{state.title ?? ""}</span>
|
|
<span data-testid="avatar">{state.communityAvatarUrl ?? ""}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
describe("PostLoginDraftTransfer", () => {
|
|
beforeEach(() => {
|
|
localStorage.clear();
|
|
localStorage.setItem(
|
|
CREATE_FLOW_ANONYMOUS_KEY,
|
|
JSON.stringify({ title: "Garden Club" }),
|
|
);
|
|
localStorage.setItem(CREATE_FLOW_TRANSFER_PENDING_KEY, "1");
|
|
mockSearchParams("syncDraft=1");
|
|
vi.mocked(flushPendingCommunityAvatar).mockReset();
|
|
vi.mocked(saveDraftToServer).mockClear();
|
|
vi.mocked(clearPendingCommunityAvatarFile).mockClear();
|
|
});
|
|
|
|
it("uploads the staged logo before clearing the anonymous draft", async () => {
|
|
let draftStillPresent = false;
|
|
vi.mocked(flushPendingCommunityAvatar).mockImplementation(async () => {
|
|
draftStillPresent =
|
|
localStorage.getItem(CREATE_FLOW_ANONYMOUS_KEY) != null;
|
|
return { status: "uploaded", url: "/api/uploads/from-guest" };
|
|
});
|
|
|
|
render(
|
|
<>
|
|
<PostLoginDraftTransfer
|
|
sessionUser={{ id: "user-1", email: "maya@example.com" }}
|
|
/>
|
|
<StateProbe />
|
|
</>,
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByTestId("avatar")).toHaveTextContent(
|
|
"/api/uploads/from-guest",
|
|
);
|
|
});
|
|
expect(draftStillPresent).toBe(true);
|
|
expect(localStorage.getItem(CREATE_FLOW_ANONYMOUS_KEY)).toBeNull();
|
|
expect(saveDraftToServer).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
title: "Garden Club",
|
|
communityAvatarUrl: "/api/uploads/from-guest",
|
|
}),
|
|
);
|
|
expect(clearPendingCommunityAvatarFile).toHaveBeenCalled();
|
|
});
|
|
|
|
it("keeps the staged file when the upload fails", async () => {
|
|
vi.mocked(flushPendingCommunityAvatar).mockResolvedValue({
|
|
status: "failed",
|
|
});
|
|
|
|
render(
|
|
<>
|
|
<PostLoginDraftTransfer
|
|
sessionUser={{ id: "user-1", email: "maya@example.com" }}
|
|
/>
|
|
<StateProbe />
|
|
</>,
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByTestId("title")).toHaveTextContent("Garden Club");
|
|
});
|
|
expect(clearPendingCommunityAvatarFile).not.toHaveBeenCalled();
|
|
expect(screen.getByTestId("avatar")).toHaveTextContent("");
|
|
});
|
|
});
|