207 lines
5.0 KiB
TypeScript
207 lines
5.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import {
|
|
assetInputSchema,
|
|
categoryInputSchema,
|
|
projectInputSchema,
|
|
sectionInputSchema,
|
|
} from "../lib/portfolio-validation";
|
|
|
|
describe("portfolio validation", () => {
|
|
it("accepts a valid category payload", () => {
|
|
expect(
|
|
categoryInputSchema.parse({
|
|
slug: "branding",
|
|
nameAr: "الهوية",
|
|
nameEn: "Branding",
|
|
nameDe: "Branding",
|
|
descriptionAr: "وصف",
|
|
descriptionEn: "Description",
|
|
descriptionDe: "Beschreibung",
|
|
sortOrder: 1,
|
|
isActive: true,
|
|
}).slug,
|
|
).toBe("branding");
|
|
});
|
|
|
|
it("rejects invalid project slugs", () => {
|
|
expect(() =>
|
|
projectInputSchema.parse({
|
|
categoryId: "cat_1",
|
|
slug: "Invalid Slug",
|
|
viewMode: "GRID",
|
|
titleAr: "عنوان",
|
|
titleEn: "Title",
|
|
titleDe: "Titel",
|
|
summaryAr: "ملخص",
|
|
summaryEn: "Summary",
|
|
summaryDe: "Zusammenfassung",
|
|
clientName: "Client",
|
|
projectYear: 2025,
|
|
serviceLabelAr: "خدمة",
|
|
serviceLabelEn: "Service",
|
|
serviceLabelDe: "Service",
|
|
previewUrl: "https://example.com",
|
|
currentCoverImagePath: "",
|
|
coverMedia: {
|
|
mode: "external",
|
|
assetId: "",
|
|
url: "https://example.com/cover.jpg",
|
|
label: "Cover",
|
|
kind: "IMAGE",
|
|
},
|
|
sortOrder: 1,
|
|
isFeatured: false,
|
|
isPublished: true,
|
|
sections: [],
|
|
assets: [],
|
|
}),
|
|
).toThrow(/slug/i);
|
|
});
|
|
|
|
it("accepts valid section and asset payloads", () => {
|
|
expect(
|
|
sectionInputSchema.parse({
|
|
type: "RICH_TEXT",
|
|
titleAr: "العنوان",
|
|
titleEn: "Title",
|
|
titleDe: "Titel",
|
|
bodyAr: "النص",
|
|
bodyEn: "Body",
|
|
bodyDe: "Text",
|
|
imagePath: "/uploads/media/covers/example.svg",
|
|
media: {
|
|
mode: "library",
|
|
assetId: "asset_1",
|
|
url: "",
|
|
label: "Section Image",
|
|
kind: "IMAGE",
|
|
},
|
|
linkUrl: "https://example.com",
|
|
sortOrder: 0,
|
|
}).type,
|
|
).toBe("RICH_TEXT");
|
|
|
|
expect(
|
|
sectionInputSchema.parse({
|
|
type: "GALLERY",
|
|
titleAr: "معرض",
|
|
titleEn: "Single Image",
|
|
titleDe: "Einzelbild",
|
|
bodyAr: "",
|
|
bodyEn: "",
|
|
bodyDe: "",
|
|
imagePath: "/uploads/media/sections/example.svg",
|
|
media: {
|
|
mode: "library",
|
|
assetId: "asset_2",
|
|
url: "",
|
|
label: "Single Image",
|
|
kind: "IMAGE",
|
|
},
|
|
linkUrl: "",
|
|
sortOrder: 1,
|
|
}).type,
|
|
).toBe("GALLERY");
|
|
|
|
expect(
|
|
assetInputSchema.parse({
|
|
kind: "IMAGE",
|
|
filePath: "/uploads/media/assets/example.svg",
|
|
fileFieldName: "",
|
|
media: {
|
|
mode: "external",
|
|
assetId: "",
|
|
url: "https://example.com/example.svg",
|
|
label: "Example",
|
|
kind: "IMAGE",
|
|
},
|
|
altAr: "بديل",
|
|
altEn: "Alt",
|
|
altDe: "Alt",
|
|
sortOrder: 0,
|
|
}).kind,
|
|
).toBe("IMAGE");
|
|
});
|
|
|
|
it("accepts valid project view modes", () => {
|
|
expect(
|
|
projectInputSchema.parse({
|
|
categoryId: "cat_1",
|
|
slug: "case-study-entry",
|
|
viewMode: "CASE_STUDY",
|
|
titleAr: "عنوان",
|
|
titleEn: "Title",
|
|
titleDe: "Titel",
|
|
summaryAr: "ملخص",
|
|
summaryEn: "Summary",
|
|
summaryDe: "Zusammenfassung",
|
|
clientName: "Client",
|
|
projectYear: 2025,
|
|
serviceLabelAr: "خدمة",
|
|
serviceLabelEn: "Service",
|
|
serviceLabelDe: "Service",
|
|
previewUrl: "https://example.com",
|
|
currentCoverImagePath: "",
|
|
coverMedia: {
|
|
mode: "external",
|
|
assetId: "",
|
|
url: "https://example.com/cover.jpg",
|
|
label: "Cover",
|
|
kind: "IMAGE",
|
|
},
|
|
sortOrder: 1,
|
|
isFeatured: false,
|
|
isPublished: true,
|
|
sections: [],
|
|
assets: [],
|
|
}).viewMode,
|
|
).toBe("CASE_STUDY");
|
|
});
|
|
|
|
it("rejects invalid media payloads", () => {
|
|
expect(() =>
|
|
assetInputSchema.parse({
|
|
kind: "IMAGE",
|
|
filePath: "",
|
|
fileFieldName: "",
|
|
media: {
|
|
mode: "external",
|
|
assetId: "",
|
|
url: "not-a-url",
|
|
label: "Broken",
|
|
kind: "IMAGE",
|
|
},
|
|
altAr: "بديل",
|
|
altEn: "Alt",
|
|
altDe: "Alt",
|
|
sortOrder: 0,
|
|
}),
|
|
).toThrow(/url/i);
|
|
});
|
|
|
|
it("rejects link sections without a link", () => {
|
|
expect(() =>
|
|
sectionInputSchema.parse({
|
|
type: "LINK",
|
|
titleAr: "رابط",
|
|
titleEn: "Link",
|
|
titleDe: "Link",
|
|
bodyAr: "",
|
|
bodyEn: "",
|
|
bodyDe: "",
|
|
imagePath: "",
|
|
media: {
|
|
mode: "upload",
|
|
assetId: "",
|
|
url: "",
|
|
label: "",
|
|
kind: "IMAGE",
|
|
},
|
|
linkUrl: "",
|
|
sortOrder: 0,
|
|
}),
|
|
).toThrow(/link/i);
|
|
});
|
|
});
|