Files
logbuch/tests/scripts/seed.test.ts
T
Matthias G 2fd71fd406 Number entries on publish, delete media, read the cover
- drafts stay unnumbered, the number is handed out when an entry goes live
- DELETE /api/v1/media/:id and a delete control in the media library
- cover_media_id in the draft read, coverMediaId and coverUrl in the archive read
2026-08-01 12:25:01 +02:00

96 lines
3.2 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { eq } from 'drizzle-orm'
import { db } from '~/data/db'
import { apiClients, blocks, brands, postTypes, posts, projects } from '~/data/schema'
import { seed } from '../../scripts/seed'
async function counts() {
return {
brands: (await db.select().from(brands)).length,
projects: (await db.select().from(projects)).length,
posts: (await db.select().from(posts)).length,
blocks: (await db.select().from(blocks)).length,
clients: (await db.select().from(apiClients)).length,
}
}
describe('seed', () => {
it('legt Marken, Projekte und Beiträge an', async () => {
await seed()
const projectRows = await db.select().from(projects)
const postRows = await db.select().from(posts)
expect(projectRows.map(project => project.slug)).toEqual(
expect.arrayContaining(['trakk', 'mta360', 'mta-telematik', 'orbit', 'pulsar']),
)
expect(postRows.length).toBeGreaterThanOrEqual(6)
expect(postRows.every(post => post.status !== 'published' || (post.number ?? 0) > 0)).toBe(true)
})
it('ist zweimal hintereinander ausführbar', async () => {
await seed()
await expect(seed()).resolves.toBeUndefined()
})
it('erzeugt beim zweiten Lauf keine Dubletten', async () => {
await seed()
const first = await counts()
await seed()
const second = await counts()
expect(second).toEqual(first)
})
it('gibt jedem Beispielprojekt ein eigenes Kürzel', async () => {
await seed()
const projectRows = await db.select().from(projects)
const codes = new Map(projectRows.map(project => [project.slug, project.code]))
expect(codes.get('trakk')).toBe('TRK')
expect(codes.get('mta360')).toBe('MTA')
expect(codes.get('mta-telematik')).toBe('TEL')
expect(codes.get('orbit')).toBe('ORB')
expect(codes.get('pulsar')).toBe('PLS')
expect(new Set(codes.values()).size).toBe(codes.size)
})
it('hält die Kürzel auch beim zweiten Lauf', async () => {
await seed()
await seed()
const projectRows = await db.select().from(projects)
expect(projectRows.every(project => project.code !== null)).toBe(true)
})
it('ordnet jedem Beispielbeitrag die Beitragsart zu, die er vor der Umstellung hatte', async () => {
await seed()
const rows = await db
.select({ slug: posts.slug, key: postTypes.key })
.from(posts)
.innerJoin(postTypes, eq(postTypes.id, posts.typeId))
const byPost = new Map(rows.map(row => [row.slug, row.key]))
expect(byPost.get('regel-engine-bedingung-trifft-aktion')).toBe('feature')
expect(byPost.get('spalten-per-rechtsklick-verwalten')).toBe('improvement')
expect(byPost.get('zehntausend-tracker-auf-einer-karte')).toBe('feature')
expect(byPost.get('sla-uhr-zaehlt-feiertage-nicht-mehr-mit')).toBe('fix')
expect(byPost.get('lokale-tabellen-konfigurationen-entfallen')).toBe('breaking')
expect(byPost.get('ein-eingang-fuer-alle-kommentare')).toBe('info')
expect(byPost.size).toBe(6)
})
it('legt genau einen internen Beitrag an, damit die Sichtbarkeit prüfbar bleibt', async () => {
await seed()
const internal = (await db.select().from(posts)).filter(post => post.audience === 'internal')
expect(internal.map(post => post.slug)).toEqual(['ein-eingang-fuer-alle-kommentare'])
})
})