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.
108 lines
3.7 KiB
TypeScript
108 lines
3.7 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { CreateFlowUploadValidationError } from "../../lib/create/createFlowUploadValidation";
|
|
|
|
const readPendingCommunityAvatarFile = vi.fn();
|
|
const clearPendingCommunityAvatarFile = vi.fn();
|
|
const uploadCreateFlowFile = vi.fn();
|
|
|
|
vi.mock("../../lib/create/pendingCommunityAvatarUpload", () => ({
|
|
readPendingCommunityAvatarFile: (...args: unknown[]) =>
|
|
readPendingCommunityAvatarFile(...args),
|
|
clearPendingCommunityAvatarFile: (...args: unknown[]) =>
|
|
clearPendingCommunityAvatarFile(...args),
|
|
}));
|
|
|
|
vi.mock("../../lib/create/uploadToServer", () => ({
|
|
uploadCreateFlowFile: (...args: unknown[]) => uploadCreateFlowFile(...args),
|
|
}));
|
|
|
|
import {
|
|
flushPendingCommunityAvatar,
|
|
forgetFlushedCommunityAvatarUrl,
|
|
stateWithPendingCommunityAvatar,
|
|
} from "../../lib/create/flushPendingCommunityAvatar";
|
|
|
|
const pending = new File([new Uint8Array([1, 2, 3])], "logo.png", {
|
|
type: "image/png",
|
|
});
|
|
|
|
describe("flushPendingCommunityAvatar", () => {
|
|
beforeEach(() => {
|
|
readPendingCommunityAvatarFile.mockReset();
|
|
clearPendingCommunityAvatarFile.mockReset();
|
|
uploadCreateFlowFile.mockReset();
|
|
clearPendingCommunityAvatarFile.mockResolvedValue(undefined);
|
|
forgetFlushedCommunityAvatarUrl();
|
|
});
|
|
|
|
it("does nothing when no file is staged", async () => {
|
|
readPendingCommunityAvatarFile.mockResolvedValue(null);
|
|
await expect(flushPendingCommunityAvatar()).resolves.toEqual({
|
|
status: "none",
|
|
});
|
|
expect(uploadCreateFlowFile).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("uploads once and remembers the url after the file is cleared", async () => {
|
|
readPendingCommunityAvatarFile
|
|
.mockResolvedValueOnce(pending)
|
|
.mockResolvedValue(null);
|
|
uploadCreateFlowFile.mockResolvedValue({ url: "/api/uploads/logo" });
|
|
|
|
const [first, second] = await Promise.all([
|
|
flushPendingCommunityAvatar(),
|
|
flushPendingCommunityAvatar(),
|
|
]);
|
|
|
|
expect(first).toEqual({ status: "uploaded", url: "/api/uploads/logo" });
|
|
expect(second).toEqual(first);
|
|
expect(uploadCreateFlowFile).toHaveBeenCalledTimes(1);
|
|
expect(clearPendingCommunityAvatarFile).toHaveBeenCalledTimes(1);
|
|
|
|
await expect(flushPendingCommunityAvatar()).resolves.toEqual({
|
|
status: "uploaded",
|
|
url: "/api/uploads/logo",
|
|
});
|
|
expect(uploadCreateFlowFile).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("drops an invalid file and leaves a transient failure staged", async () => {
|
|
readPendingCommunityAvatarFile.mockResolvedValue(pending);
|
|
uploadCreateFlowFile.mockRejectedValueOnce(
|
|
new CreateFlowUploadValidationError("tooLarge"),
|
|
);
|
|
|
|
await expect(flushPendingCommunityAvatar()).resolves.toEqual({
|
|
status: "invalid",
|
|
});
|
|
expect(clearPendingCommunityAvatarFile).toHaveBeenCalledTimes(1);
|
|
|
|
uploadCreateFlowFile.mockRejectedValueOnce(new Error("network"));
|
|
await expect(flushPendingCommunityAvatar()).resolves.toEqual({
|
|
status: "failed",
|
|
});
|
|
expect(clearPendingCommunityAvatarFile).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("copies a successful upload onto publish state and blocks on failure", async () => {
|
|
readPendingCommunityAvatarFile.mockResolvedValue(pending);
|
|
uploadCreateFlowFile.mockResolvedValue({ url: "/api/uploads/logo" });
|
|
|
|
await expect(
|
|
stateWithPendingCommunityAvatar({ title: "Garden" }),
|
|
).resolves.toEqual({
|
|
ok: true,
|
|
state: { title: "Garden", communityAvatarUrl: "/api/uploads/logo" },
|
|
});
|
|
|
|
forgetFlushedCommunityAvatarUrl();
|
|
uploadCreateFlowFile.mockRejectedValueOnce(new Error("network"));
|
|
await expect(
|
|
stateWithPendingCommunityAvatar({
|
|
title: "Garden",
|
|
communityAvatarFileName: "logo.png",
|
|
}),
|
|
).resolves.toEqual({ ok: false, reason: "upload_failed" });
|
|
});
|
|
});
|