@oberoncms/core
Version:
OberonCMS is a cloud deployable CMS written in typescript based on the Puck visual editor
125 lines (109 loc) • 3.96 kB
text/typescript
import { describe, expect, it } from "@dev/vitest"
import { getComponentTransformVersions, getTransforms } from "./transforms"
function config(
components: Record<
string,
{
transforms?: Array<
(props: Record<string, unknown>) => Record<string, unknown>
>
}
>,
) {
return { components } as Parameters<typeof getComponentTransformVersions>[0]
}
describe("getComponentTransformVersions", { tags: ["baseline"] }, () => {
it("returns 0 for components with no transforms", () => {
expect(getComponentTransformVersions(config({ Hero: {} }))).toEqual({
Hero: 0,
})
})
it("counts transforms per component", () => {
const identity = (p: Record<string, unknown>) => p
expect(
getComponentTransformVersions(
config({
Hero: { transforms: [identity, identity] },
Card: { transforms: [identity] },
Footer: {},
}),
),
).toEqual({ Hero: 2, Card: 1, Footer: 0 })
})
it("returns empty object for empty components", () => {
expect(getComponentTransformVersions(config({}))).toEqual({})
})
})
describe("getTransforms", { tags: ["baseline"] }, () => {
const addTitle = (props: Record<string, unknown>) => ({
...props,
title: "default",
})
const uppercase = (props: Record<string, unknown>) => ({
...props,
title: String(props.title ?? "").toUpperCase(),
})
it("returns false for transforms when all versions are current", () => {
const result = getTransforms(
{ Hero: 1 },
config({ Hero: { transforms: [addTitle] } }),
)
expect(result.transforms).toBe(false)
expect(result.components).toEqual({ Hero: 1 })
})
it("builds transform for components behind current version", () => {
const result = getTransforms(
{ Hero: 0 },
config({ Hero: { transforms: [addTitle, uppercase] } }),
)
expect(result.components).toEqual({ Hero: 2 })
expect(result.transforms).toBeTruthy()
// Apply the transform pipeline
const transformed = result.transforms && result.transforms.Hero?.({})
expect(transformed).toEqual({ title: "DEFAULT" })
})
it("applies only new transforms (skips already-applied ones)", () => {
const result = getTransforms(
{ Hero: 1 },
config({ Hero: { transforms: [addTitle, uppercase] } }),
)
expect(result.transforms).toBeTruthy()
// Only uppercase should run (index 1), not addTitle (index 0)
const transformed =
result.transforms && result.transforms.Hero?.({ title: "hello" })
expect(transformed).toEqual({ title: "HELLO" })
})
it("treats missing version as latest (no migration needed for new components)", () => {
const result = getTransforms(
{},
config({ Hero: { transforms: [addTitle] } }),
)
expect(result.transforms).toBe(false)
expect(result.components).toEqual({ Hero: 1 })
})
it("handles mix of current and outdated components", () => {
const result = getTransforms(
{ Hero: 1, Card: 0 },
config({
Hero: { transforms: [addTitle] },
Card: { transforms: [addTitle] },
}),
)
expect(result.components).toEqual({ Hero: 1, Card: 1 })
expect(result.transforms).toBeTruthy()
// Only Card needs migration
expect(result.transforms && "Hero" in result.transforms).toBe(false)
expect(result.transforms && "Card" in result.transforms).toBe(true)
})
it("chains multiple pending transforms in order", () => {
const step1 = (props: Record<string, unknown>) => ({ ...props, a: 1 })
const step2 = (props: Record<string, unknown>) => ({ ...props, b: 2 })
const step3 = (props: Record<string, unknown>) => ({ ...props, c: 3 })
const result = getTransforms(
{ Hero: 1 },
config({ Hero: { transforms: [step1, step2, step3] } }),
)
const transformed = result.transforms && result.transforms.Hero?.({})
expect(transformed).toEqual({ b: 2, c: 3 })
})
})