feat: enhance admin API helpers with CRUD operations for collections and seed data management

- Added functions for creating, updating, deleting, and listing collection entries in admin API.
- Introduced seed data management for consistent test content across tests.
- Updated global setup and teardown processes to ensure seeded content is created and cleaned up.
- Refactored existing tests to utilize seeded content for improved reliability and maintainability.
This commit is contained in:
2026-05-12 20:36:06 +00:00
parent 491f495c66
commit 1b24bb2157
17 changed files with 697 additions and 444 deletions
+78 -18
View File
@@ -1,26 +1,86 @@
import { test, expect, API_BASE } from "./fixtures"
import { SEEDED_TEST_CONTENT } from "../fixtures/test-constants"
test.describe("API Health", () => {
test("should respond to API base endpoint", async ({ api }) => {
// tibi-server responds to the base API path
const res = await api.get(`${API_BASE}/`)
// Accept any successful response (200-299), 401 (auth required), or 404 (no root handler)
expect([200, 204, 401, 404]).toContain(res.status())
type ContentApiEntry = {
id?: string
translationKey?: string
lang?: string
path?: string
active?: boolean
blocks?: Array<{ type?: string }>
}
async function getContentEntries(api: { get: Function }, filter: Record<string, unknown>): Promise<ContentApiEntry[]> {
const res = await api.get(`${API_BASE}/content`, {
params: {
filter: JSON.stringify(filter),
},
})
test("should respond to SSR collection", async ({ api }) => {
// The ssr collection is part of the starter kit
const res = await api.get(`${API_BASE}/ssr`)
expect(res.status()).toBeLessThan(500)
})
expect(res.ok()).toBeTruthy()
test("should reject invalid action commands", async ({ api }) => {
const res = await api.post(`${API_BASE}/action`, {
params: { cmd: "nonexistent_action" },
data: {},
const body = (await res.json()) as unknown
return Array.isArray(body) ? (body as ContentApiEntry[]) : []
}
test.describe("Seeded Content API", () => {
test("returns the seeded localized page variants through the public content endpoint", async ({ api }) => {
const deEntries = await getContentEntries(api, {
lang: "de",
path: SEEDED_TEST_CONTENT.home.path,
active: true,
})
// Should return an error, not crash
expect(res.status()).toBeGreaterThanOrEqual(400)
expect(res.status()).toBeLessThan(500)
const enEntries = await getContentEntries(api, {
lang: "en",
path: SEEDED_TEST_CONTENT.home.path,
active: true,
})
expect(deEntries).toHaveLength(1)
expect(enEntries).toHaveLength(1)
expect(deEntries[0].translationKey).toBe(SEEDED_TEST_CONTENT.home.translationKey)
expect(enEntries[0].translationKey).toBe(SEEDED_TEST_CONTENT.home.translationKey)
expect(deEntries[0].blocks?.map((block) => block.type)).toEqual(["hero", "features", "richtext", "accordion"])
expect(enEntries[0].blocks?.map((block) => block.type)).toEqual(["hero", "features", "richtext", "accordion"])
})
test("returns the seeded contact page and an empty result for missing active routes", async ({ api }) => {
const contactEntries = await getContentEntries(api, {
lang: "de",
path: SEEDED_TEST_CONTENT.contact.path,
active: true,
})
const inactiveEntries = await getContentEntries(api, {
lang: "de",
path: SEEDED_TEST_CONTENT.inactive.path,
active: true,
})
const missingEntries = await getContentEntries(api, {
lang: "de",
path: "/playwright-e2e-missing",
active: true,
})
expect(contactEntries).toHaveLength(1)
expect(contactEntries[0].blocks?.map((block) => block.type)).toEqual(["hero", "contact-form"])
expect(inactiveEntries).toHaveLength(0)
expect(missingEntries).toHaveLength(0)
})
test("allows the admin API to inspect the inactive seeded entry", async ({ adminApi }) => {
const res = await adminApi.get(`${API_BASE}/content`, {
params: {
filter: JSON.stringify({
translationKey: SEEDED_TEST_CONTENT.inactive.translationKey,
lang: "de",
}),
},
})
expect(res.ok()).toBeTruthy()
const body = (await res.json()) as ContentApiEntry[]
expect(body).toHaveLength(1)
expect(body[0].active).toBe(false)
expect(body[0].path).toBe(SEEDED_TEST_CONTENT.inactive.path)
})
})