125 lines
3.1 KiB
TypeScript
125 lines
3.1 KiB
TypeScript
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<string, RecordItem>([["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" })
|
|
})
|
|
})
|