import { beforeEach, describe, expect, it, vi } from "vitest"; vi.mock("next/cache", async () => ({ revalidatePath: (await import("@/tests/helpers/next-mocks")).revalidatePath })); vi.mock("next/navigation", async () => ({ redirect: (await import("@/tests/helpers/next-mocks")).redirect })); vi.mock("next/dist/client/components/redirect-error", async () => ({ isRedirectError: (await import("@/tests/helpers/next-mocks")).isRedirectError, })); vi.mock("@/lib/admin-auth", async () => { const m = await import("@/tests/helpers/next-mocks"); return { isAdminAuthenticated: m.isAdminAuthenticated, clearAdminSessionCookie: m.clearAdminSessionCookie }; }); import { eq } from "drizzle-orm"; import { createMediaAssetAction, deleteMediaAssetAction } from "@/app/_admin/media/actions"; import { db } from "@/lib/db"; import { mediaAsset } from "@/lib/db/schema"; import { removeManagedMediaFile } from "@/lib/media-storage"; import { createMediaAsset, createMediaUsage } from "@/tests/helpers/factories"; import { canManageUploads } from "@/tests/helpers/fs-capability"; import { adminAuth, captureRedirect, formDataFrom, resetNextMocks } from "@/tests/helpers/next-mocks"; beforeEach(() => { resetNextMocks(); }); describe("createMediaAssetAction", () => { it("errors when no file is provided", async () => { const url = await captureRedirect(() => createMediaAssetAction(formDataFrom({ kind: "IMAGE", label: "L" }))); expect(url).toContain("error="); expect(await db.$count(mediaAsset)).toBe(0); }); it.skipIf(!canManageUploads)("creates an asset from an uploaded file", async () => { const file = new File([new Uint8Array([0x89, 0x50, 0x4e, 0x47])], "pic.png", { type: "image/png" }); const url = await captureRedirect(() => createMediaAssetAction(formDataFrom({ kind: "IMAGE", label: "Pic", file })), ); expect(url).toContain("success="); const assets = await db.select().from(mediaAsset); expect(assets.length).toBe(1); expect(assets[0].source).toBe("UPLOAD"); await removeManagedMediaFile(assets[0].url); }); it("redirects unauthenticated callers to the admin root", async () => { adminAuth.authenticated = false; const url = await captureRedirect(() => createMediaAssetAction(formDataFrom({ kind: "IMAGE", label: "L" }))); expect(url).toBe("/"); }); }); describe("deleteMediaAssetAction", () => { it("errors when the asset does not exist", async () => { const url = await captureRedirect(() => deleteMediaAssetAction(formDataFrom({ assetId: "missing" }))); expect(url).toContain("error="); }); it("refuses to delete an asset that is still in use", async () => { const asset = await createMediaAsset(); await createMediaUsage(asset.id); const url = await captureRedirect(() => deleteMediaAssetAction(formDataFrom({ assetId: asset.id }))); expect(url).toContain("error="); expect((await db.query.mediaAsset.findFirst({ where: eq(mediaAsset.id, asset.id) })) ?? null).not.toBeNull(); }); it("deletes an unused external asset", async () => { const asset = await createMediaAsset({ url: "https://cdn/external.png" }); const url = await captureRedirect(() => deleteMediaAssetAction(formDataFrom({ assetId: asset.id }))); expect(url).toContain("success="); expect((await db.query.mediaAsset.findFirst({ where: eq(mediaAsset.id, asset.id) })) ?? null).toBeNull(); }); it("redirects unauthenticated callers to the admin root", async () => { adminAuth.authenticated = false; const url = await captureRedirect(() => deleteMediaAssetAction(formDataFrom({ assetId: "x" }))); expect(url).toBe("/"); }); });