import { describe, expect, it } from "vitest" import { z } from "zod" import { createCrudService } from "./service" type RecordItem = { id: string title: string } describe("crud service contract", () => { it("calls repository in expected order for update and delete", async () => { const calls: string[] = [] const state = new Map([["1", { id: "1", title: "Initial" }]]) const service = createCrudService({ resource: "item", repository: { list: async () => { calls.push("list") return Array.from(state.values()) }, findById: async (id) => { calls.push(`findById:${id}`) return state.get(id) ?? null }, create: async (input: { title: string }) => { calls.push("create") return { id: "2", title: input.title, } }, update: async (id, input: { title?: string }) => { calls.push(`update:${id}`) const current = state.get(id) if (!current) { throw new Error("missing") } const updated = { ...current, ...input, } state.set(id, updated) return updated }, delete: async (id) => { calls.push(`delete:${id}`) const current = state.get(id) if (!current) { throw new Error("missing") } state.delete(id) return current }, }, schemas: { create: z.object({ title: z.string().min(3), }), update: z.object({ title: z.string().min(3).optional(), }), }, }) await service.update("1", { title: "Updated" }) await service.delete("1") expect(calls).toEqual(["findById:1", "update:1", "findById:1", "delete:1"]) }) it("passes parsed payload to repository create/update contracts", async () => { let createPayload: unknown = null let updatePayload: unknown = null const service = createCrudService({ resource: "item", repository: { list: async () => [], findById: async () => ({ id: "1", title: "Existing", }), create: async (input: { title: string }) => { createPayload = input return { id: "2", title: input.title, } }, update: async (_id, input: { title?: string }) => { updatePayload = input return { id: "1", title: input.title ?? "Existing", } }, delete: async () => ({ id: "1", title: "Existing", }), }, schemas: { create: z.object({ title: z.string().trim().min(3), }), update: z.object({ title: z.string().trim().min(3).optional(), }), }, }) await service.create({ title: " Created ", }) await service.update("1", { title: " Updated ", }) expect(createPayload).toEqual({ title: "Created" }) expect(updatePayload).toEqual({ title: "Updated" }) }) })