test: Spiegel-Eingang und Integrationstabellen absichern

Der Eingang des Spiegels ist die einzige Tuer, die ohne Anmeldung
aufgeht. Vier Faelle: ohne Signatur, falsch signiert, zu alt, und der
gute Fall — bei dem eine nicht mehr geschickte Belegung auch hier
verschwinden muss.

Der Testserver bekommt dafuer dasselbe Geheimnis wie der Test. Eine
Pruefung, die immer uebersprungen wird, prueft nichts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Florian Wilde
2026-09-11 23:58:43 +02:00
co-authored by Claude Opus 5
parent 0d0f8503cc
commit 4da2f3d9c6
4 changed files with 234 additions and 0 deletions
+83
View File
@@ -41,6 +41,9 @@ async function scheitert(name: string, tun: () => Promise<unknown>): Promise<voi
}
const kennung = `zzz-test-${Date.now()}`
// Eigene Chatkennung je Lauf, damit das Aufraeumen genau diese Zeile trifft
// und nicht irgendeine, die zufaellig aehnlich aussieht.
const testChatId = BigInt(Date.now())
const testEmail = `${kennung}@example.invalid`
async function aufraeumen(): Promise<void> {
@@ -58,6 +61,12 @@ async function aufraeumen(): Promise<void> {
await db.webauthnChallenge.deleteMany({ where: { kennung } })
await db.pushGeraet.deleteMany({ where: { endpunkt: { contains: kennung } } })
await db.meldungsnachweis.deleteMany({ where: { schluessel: { contains: kennung } } })
await db.spiegelbelegung.deleteMany({ where: { quelleRef: { contains: kennung } } })
await db.telegramKopplung.deleteMany({
where: { code: { contains: kennung.slice(-8) } },
})
await db.telegramChat.deleteMany({ where: { chatId: testChatId } })
await db.integrationszustand.deleteMany({ where: { quelle: 'TELEGRAM' } })
}
async function main(): Promise<void> {
@@ -316,6 +325,76 @@ async function main(): Promise<void> {
).id.length > 0,
)
// --- Integrationen -------------------------------------------------------
// Der Zustand haengt an der Quelle: eine Zeile je Integration, nicht mehr.
await db.integrationszustand.create({
data: { quelle: 'TELEGRAM', merker: '42' },
})
await scheitert('Je Quelle nur ein Integrationszustand', () =>
db.integrationszustand.create({ data: { quelle: 'TELEGRAM' } }),
)
await db.integrationszustand.deleteMany({ where: { quelle: 'TELEGRAM' } })
// Zwei Aufgaben aus derselben Quelle mit derselben Kennung darf es nicht
// geben – sonst legte jeder Lauf dieselbe Sache erneut an.
const ausZammad = await db.aufgabe.create({
data: { titel: `${kennung}-ticket`, quelle: 'ZAMMAD', quelleRef: `${kennung}-1` },
})
pruefe('Aufgabe aus einer Integration anlegen', ausZammad.id.length > 0)
pruefe('Ohne Freigabe wird nicht gespiegelt', ausZammad.spiegeln === false)
await scheitert('Dieselbe Quelle mit derselben Kennung nur einmal (Integration)', () =>
db.aufgabe.create({
data: {
titel: `${kennung}-ticket-doppelt`,
quelle: 'ZAMMAD',
quelleRef: `${kennung}-1`,
},
}),
)
await db.spiegelbelegung.create({
data: {
quelleRef: `${kennung}-zb`,
beginn: new Date(Date.UTC(2026, 2, 17, 8, 0)),
ende: new Date(Date.UTC(2026, 2, 17, 9, 0)),
},
})
await scheitert('Dieselbe gespiegelte Belegung nur einmal', () =>
db.spiegelbelegung.create({
data: {
quelleRef: `${kennung}-zb`,
beginn: new Date(Date.UTC(2026, 2, 18, 8, 0)),
ende: new Date(Date.UTC(2026, 2, 18, 9, 0)),
},
}),
)
const chat = await db.telegramChat.create({
data: { chatId: testChatId, benutzerId: benutzer.id },
})
pruefe('Telegram-Chat empfaengt im Zweifel Meldungen', chat.meldungen === true)
await scheitert('Dieselbe Chatkennung nur einmal', () =>
db.telegramChat.create({ data: { chatId: chat.chatId } }),
)
await db.telegramKopplung.create({
data: {
code: `${kennung.slice(-8)}`,
benutzerId: benutzer.id,
gueltigBis: new Date(Date.now() + 600_000),
},
})
await scheitert('Denselben Kopplungscode nur einmal', () =>
db.telegramKopplung.create({
data: {
code: `${kennung.slice(-8)}`,
benutzerId: benutzer.id,
gueltigBis: new Date(Date.now() + 600_000),
},
}),
)
await db.benutzer.delete({ where: { id: benutzer.id } })
const nachher = await db.auditEintrag.findUnique({ where: { id: audit.id } })
@@ -341,6 +420,10 @@ async function main(): Promise<void> {
'Push-Geräte verschwinden mit dem Benutzer',
(await db.pushGeraet.count({ where: { endpunkt: { contains: kennung } } })) === 0,
)
pruefe(
'Telegram-Chats verschwinden nicht, verlieren aber den Benutzer',
(await db.telegramChat.count({ where: { benutzerId: benutzer.id } })) === 0,
)
pruefe(
'Meldungsnachweise verschwinden mit dem Benutzer',
(await db.meldungsnachweis.count({