feat(editorial): validate publications and preserve partial event updates
This commit is contained in:
1 parent
76f0420d64
commit
db4acbb46e
14 files changed
+613
-16
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { createEventSchema, eventTypeSchema } from "./event";
|
||||
import { createEventSchema, eventTypeSchema, updateEventSchema } from "./event";
|
||||
|
||||
describe("eventTypeSchema", () => {
|
||||
it("accepts valid type", () => {
|
||||
@@ -98,3 +98,27 @@ describe("createEventSchema", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves omitted status and recurrence on partial event updates", () => {
|
||||
expect(updateEventSchema.parse({ title: "Changed" })).toEqual({
|
||||
title: "Changed",
|
||||
});
|
||||
});
|
||||
it("rejects a null event start instead of converting it to the Unix epoch", () => {
|
||||
expect(
|
||||
createEventSchema.safeParse({
|
||||
title: "Event",
|
||||
description: "Details",
|
||||
typeId: 1,
|
||||
startsAt: null,
|
||||
status: "published",
|
||||
}).success,
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("distinguishes an omitted image from explicit image removal", () => {
|
||||
expect(updateEventSchema.parse({ title: "Changed" })).not.toHaveProperty(
|
||||
"image",
|
||||
);
|
||||
expect(updateEventSchema.parse({ image: "" })).toEqual({ image: null });
|
||||
});
|
||||
@@ -25,7 +25,11 @@ export const createEventSchema = z.object({
|
||||
emptyToUndefined,
|
||||
z.coerce.number().int().positive().nullable().optional(),
|
||||
),
|
||||
startsAt: z.coerce.date(),
|
||||
startsAt: z.preprocess(
|
||||
(value) =>
|
||||
value == null || typeof value === "boolean" ? undefined : value,
|
||||
z.coerce.date(),
|
||||
),
|
||||
endsAt: z.preprocess(emptyToUndefined, z.coerce.date().nullable().optional()),
|
||||
maxPlayers: z.preprocess(
|
||||
emptyToUndefined,
|
||||
@@ -45,7 +49,15 @@ export const createEventSchema = z.object({
|
||||
),
|
||||
});
|
||||
|
||||
export const updateEventSchema = createEventSchema.partial();
|
||||
// Zod applies defaults inside optional schemas; partial edits must not reset state.
|
||||
export const updateEventSchema = createEventSchema.partial().extend({
|
||||
status: createEventSchema.shape.status.removeDefault().optional(),
|
||||
isRecurring: createEventSchema.shape.isRecurring.removeDefault().optional(),
|
||||
image: z.preprocess(
|
||||
(value) => (value === "" ? null : value),
|
||||
z.string().max(500).nullable().optional(),
|
||||
),
|
||||
});
|
||||
|
||||
export const eventPrizeSchema = z.object({
|
||||
eventId: z.coerce.number().int().positive(),
|
||||
|
||||
Reference in new issue
Block a user