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
This commit is contained in:
+63
-14
@@ -3,10 +3,12 @@ import { asc, eq } from 'drizzle-orm'
|
||||
import { db } from '~/data/db'
|
||||
import { posts } from '~/data/schema'
|
||||
import {
|
||||
assignEntryNumber,
|
||||
createEntry,
|
||||
listEntries,
|
||||
listEntryBlocks,
|
||||
replaceEntryBlocks,
|
||||
setEntryStatus,
|
||||
type EntryCreateValues,
|
||||
} from '~/data/repositories/entries'
|
||||
import { makeBrand, makeProject } from '../support/admin'
|
||||
@@ -26,7 +28,7 @@ function values(projectId: string, slug: string, title = 'Beitrag'): EntryCreate
|
||||
}
|
||||
}
|
||||
|
||||
async function numbersOf(projectId: string): Promise<number[]> {
|
||||
async function numbersOf(projectId: string): Promise<(number | null)[]> {
|
||||
const rows = await db
|
||||
.select({ number: posts.number })
|
||||
.from(posts)
|
||||
@@ -36,28 +38,62 @@ async function numbersOf(projectId: string): Promise<number[]> {
|
||||
return rows.map(row => row.number)
|
||||
}
|
||||
|
||||
describe('createEntry vergibt Beitragsnummern', () => {
|
||||
it('zählt je Projekt getrennt hoch', async () => {
|
||||
async function publish(id: string): Promise<number | null> {
|
||||
const post = await setEntryStatus(id, 'published', new Date())
|
||||
|
||||
return post?.number ?? null
|
||||
}
|
||||
|
||||
describe('Beitragsnummern', () => {
|
||||
it('lässt Entwürfe ohne Nummer', async () => {
|
||||
const brand = await makeBrand()
|
||||
const project = await makeProject(brand.id)
|
||||
|
||||
const created = await createEntry(values(project.id, 'entwurf'))
|
||||
|
||||
expect(created.number).toBeNull()
|
||||
expect(await numbersOf(project.id)).toEqual([null])
|
||||
})
|
||||
|
||||
it('zählt beim Veröffentlichen je Projekt getrennt hoch', async () => {
|
||||
const brand = await makeBrand()
|
||||
const trakk = await makeProject(brand.id, 'trakk', 'Trakk')
|
||||
const orbit = await makeProject(brand.id, 'orbit', 'Orbit')
|
||||
|
||||
await createEntry(values(trakk.id, 'eins'))
|
||||
await createEntry(values(trakk.id, 'zwei'))
|
||||
await createEntry(values(orbit.id, 'eins'))
|
||||
const first = await createEntry(values(trakk.id, 'eins'))
|
||||
const second = await createEntry(values(trakk.id, 'zwei'))
|
||||
const third = await createEntry(values(orbit.id, 'eins'))
|
||||
|
||||
expect(await numbersOf(trakk.id)).toEqual([1, 2])
|
||||
expect(await numbersOf(orbit.id)).toEqual([1])
|
||||
expect(await publish(first.id)).toBe(1)
|
||||
expect(await publish(second.id)).toBe(2)
|
||||
expect(await publish(third.id)).toBe(1)
|
||||
})
|
||||
|
||||
it('vergibt bei gleichzeitigem Anlegen lückenlose Nummern ohne Doppelung', async () => {
|
||||
it('lässt keine Lücke, wenn ein Entwurf dazwischen gelöscht wird', async () => {
|
||||
const brand = await makeBrand()
|
||||
const project = await makeProject(brand.id)
|
||||
|
||||
await Promise.all(
|
||||
const first = await createEntry(values(project.id, 'eins'))
|
||||
const scrapped = await createEntry(values(project.id, 'verworfen'))
|
||||
const second = await createEntry(values(project.id, 'zwei'))
|
||||
|
||||
await publish(first.id)
|
||||
await db.delete(posts).where(eq(posts.id, scrapped.id))
|
||||
await publish(second.id)
|
||||
|
||||
expect(await numbersOf(project.id)).toEqual([1, 2])
|
||||
})
|
||||
|
||||
it('vergibt bei gleichzeitigem Veröffentlichen lückenlose Nummern ohne Doppelung', async () => {
|
||||
const brand = await makeBrand()
|
||||
const project = await makeProject(brand.id)
|
||||
|
||||
const created = await Promise.all(
|
||||
Array.from({ length: 20 }, (_, index) => createEntry(values(project.id, `beitrag-${index}`))),
|
||||
)
|
||||
|
||||
await Promise.all(created.map(entry => publish(entry.id)))
|
||||
|
||||
expect(await numbersOf(project.id)).toEqual(Array.from({ length: 20 }, (_, index) => index + 1))
|
||||
})
|
||||
|
||||
@@ -69,10 +105,23 @@ describe('createEntry vergibt Beitragsnummern', () => {
|
||||
|
||||
const created = await createEntry(values(project.id, 'neuer-beitrag'))
|
||||
|
||||
expect(created.number).toBe(143)
|
||||
expect(await publish(created.id)).toBe(143)
|
||||
})
|
||||
|
||||
it('hängt die Nummer an, wenn der Slug im Projekt schon vergeben ist', async () => {
|
||||
it('vergibt eine bereits gesetzte Nummer nicht neu', async () => {
|
||||
const brand = await makeBrand()
|
||||
const project = await makeProject(brand.id)
|
||||
|
||||
const created = await createEntry(values(project.id, 'eins'))
|
||||
|
||||
await publish(created.id)
|
||||
|
||||
const again = await assignEntryNumber(created.id)
|
||||
|
||||
expect(again?.number).toBe(1)
|
||||
})
|
||||
|
||||
it('hängt eine Zahl an, wenn der Slug im Projekt schon vergeben ist', async () => {
|
||||
const brand = await makeBrand()
|
||||
const project = await makeProject(brand.id)
|
||||
|
||||
@@ -80,7 +129,7 @@ describe('createEntry vergibt Beitragsnummern', () => {
|
||||
const second = await createEntry(values(project.id, 'regel-engine'))
|
||||
|
||||
expect(first.slug).toBe('regel-engine')
|
||||
expect(second.slug).toBe(`regel-engine-${second.number}`)
|
||||
expect(second.slug).toBe('regel-engine-2')
|
||||
})
|
||||
|
||||
it('übernimmt Titel, Autor und Zielgruppe', async () => {
|
||||
@@ -94,7 +143,7 @@ describe('createEntry vergibt Beitragsnummern', () => {
|
||||
authorName: 'Paul',
|
||||
audience: 'customer',
|
||||
status: 'draft',
|
||||
number: 1,
|
||||
number: null,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user