Files
sass-mohfarawati/tests/integration/media.test.ts
T
Moh e2e06be86e test: add comprehensive automated test coverage
- Vitest multi-project setup (unit / integration / component)
- Real-Postgres integration harness via in-process PGlite (TEST_DATABASE_URL
  override), migrations applied per worker; production code untouched
- Unit: routing, locale, validation/Zod schemas, metadata, mail, site-theme,
  marquee, media, portfolio helpers, plus architecture-rule tests
- Integration: Prisma data layer, API routes, and all server actions
- Component: UI primitives and form components (jsdom + Testing Library)
- 371 tests passing
2026-08-06 02:27:20 +02:00

138 lines
4.7 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
countMediaUsageReferences,
createMediaAsset,
deleteEntityMediaUsages,
getAdminMediaAssets,
getMediaAssetById,
getMediaOptions,
getPortfolioMediaBindings,
replaceEntityMediaUsages,
} from "@/lib/media";
import { prisma } from "@/lib/prisma";
import { createMediaAsset as seedAsset } from "@/tests/helpers/factories";
describe("createMediaAsset / getMediaAssetById", () => {
it("creates and reads back an asset with usages", async () => {
const created = await createMediaAsset({
source: "EXTERNAL",
kind: "IMAGE",
url: "https://cdn/x.png",
fileName: "x.png",
label: "X",
});
const found = await getMediaAssetById(created.id);
expect(found?.url).toBe("https://cdn/x.png");
expect(found?.usages).toEqual([]);
});
it("returns null for a missing asset", async () => {
expect(await getMediaAssetById("nope")).toBeNull();
});
});
describe("getMediaOptions", () => {
it("filters by kind", async () => {
await seedAsset({ kind: "IMAGE" });
await seedAsset({ kind: "DOCUMENT" });
const images = await getMediaOptions({ kind: "IMAGE" });
expect(images.every((a) => a.kind === "IMAGE")).toBe(true);
const all = await getMediaOptions();
expect(all.length).toBe(2);
});
});
describe("getAdminMediaAssets", () => {
it("returns newest first with usage details", async () => {
const a = await seedAsset();
await createMediaUsageFor(a.id);
const list = await getAdminMediaAssets();
expect(list.length).toBe(1);
expect(list[0].usages.length).toBe(1);
});
});
describe("replaceEntityMediaUsages", () => {
it("replaces existing usages transactionally", async () => {
const a1 = await seedAsset();
const a2 = await seedAsset();
await replaceEntityMediaUsages({
entityType: "portfolio-project",
entityId: "p1",
usages: [{ assetId: a1.id, usageType: "PORTFOLIO_COVER", fieldKey: "cover" }],
});
expect(await countMediaUsageReferences(a1.id)).toBe(1);
await replaceEntityMediaUsages({
entityType: "portfolio-project",
entityId: "p1",
usages: [{ assetId: a2.id, usageType: "PORTFOLIO_COVER", fieldKey: "cover" }],
});
expect(await countMediaUsageReferences(a1.id)).toBe(0);
expect(await countMediaUsageReferences(a2.id)).toBe(1);
});
it("clears usages when given an empty list", async () => {
const a1 = await seedAsset();
await replaceEntityMediaUsages({
entityType: "portfolio-project",
entityId: "p2",
usages: [{ assetId: a1.id, usageType: "PORTFOLIO_ASSET", fieldKey: "a" }],
});
await replaceEntityMediaUsages({ entityType: "portfolio-project", entityId: "p2", usages: [] });
expect(await countMediaUsageReferences(a1.id)).toBe(0);
});
});
describe("deleteEntityMediaUsages", () => {
it("removes only the target entity's usages", async () => {
const a1 = await seedAsset();
await replaceEntityMediaUsages({
entityType: "portfolio-project",
entityId: "keep",
usages: [{ assetId: a1.id, usageType: "PORTFOLIO_ASSET", fieldKey: "a" }],
});
await replaceEntityMediaUsages({
entityType: "portfolio-project",
entityId: "drop",
usages: [{ assetId: a1.id, usageType: "PORTFOLIO_ASSET", fieldKey: "b" }],
});
await deleteEntityMediaUsages("portfolio-project", "drop");
expect(await countMediaUsageReferences(a1.id)).toBe(1);
});
});
describe("getPortfolioMediaBindings", () => {
it("routes usages into cover / section / asset buckets", async () => {
const cover = await seedAsset();
const section = await seedAsset();
const asset = await seedAsset();
await prisma.mediaUsage.createMany({
data: [
{ assetId: cover.id, usageType: "PORTFOLIO_COVER", entityType: "portfolio-project", entityId: "proj", fieldKey: "cover" },
{ assetId: section.id, usageType: "PORTFOLIO_SECTION", entityType: "portfolio-project", entityId: "proj", fieldKey: "sec_1" },
{ assetId: asset.id, usageType: "PORTFOLIO_ASSET", entityType: "portfolio-project", entityId: "proj", fieldKey: "ast_1" },
],
});
const bindings = await getPortfolioMediaBindings("proj");
expect(bindings.coverAssetId).toBe(cover.id);
expect(bindings.sectionAssetIds.sec_1).toBe(section.id);
expect(bindings.assetIds.ast_1).toBe(asset.id);
});
it("returns empty bindings for an unknown project", async () => {
const bindings = await getPortfolioMediaBindings("missing");
expect(bindings).toEqual({ coverAssetId: null, sectionAssetIds: {}, assetIds: {} });
});
});
async function createMediaUsageFor(assetId: string) {
await prisma.mediaUsage.create({
data: { assetId, usageType: "GENERIC", entityType: "e", entityId: "1", fieldKey: "f" },
});
}