import { expect, test } from '@playwright/test' import { PrismaClient } from '@prisma/client' import { anmelden } from './hilfen' /** * Der Demo-Fall mit Kontobewegungen — gegen die echte Anwendung. * * Was hier geprüft wird, ist kein Verhalten der Anwendung, sondern die * Brauchbarkeit der Beispieldaten: Wer die Anwendung zum ersten Mal * ansieht, soll auf den Finanzseiten etwas vorfinden und nicht erst * eine CSV importieren müssen. * * Die Prüfungen sind bewusst grob gehalten — sie sollen anschlagen, wenn * der Demo-Fall leer läuft, und nicht bei jeder geänderten Zahl. */ async function mitDb(arbeit: (db: PrismaClient) => Promise): Promise { const db = new PrismaClient() try { return await arbeit(db) } finally { await db.$disconnect() } } test.describe('Demo-Fall', () => { test('bringt ein Jahr Kontobewegungen mit', async () => { const zahlen = await mitDb(async (db) => { const betreute = await db.betreute.findFirst({ where: { vorname: 'Erika', nachname: 'Musterfrau' }, select: { id: true }, }) if (!betreute) return null const buchungen = await db.buchung.findMany({ where: { betreuteId: betreute.id, geloeschtAm: null }, select: { datum: true }, orderBy: { datum: 'asc' }, }) const ohneNachweis = await db.buchung.count({ where: { betreuteId: betreute.id, belegId: null, belegFehltBegruendung: null }, }) return { buchungen, ohneNachweis } }) test.skip(zahlen === null, 'Kein Demo-Fall in dieser Datenbank.') if (!zahlen) return expect(zahlen.buchungen.length).toBeGreaterThan(50) // Über mindestens zwölf Monate verteilt, nicht alle an einem Tag. const erste = zahlen.buchungen[0]!.datum const letzte = zahlen.buchungen[zahlen.buchungen.length - 1]!.datum const monate = (letzte.getUTCFullYear() - erste.getUTCFullYear()) * 12 + (letzte.getUTCMonth() - erste.getUTCMonth()) expect(monate).toBeGreaterThanOrEqual(11) // Genau ein Fall ohne Beleg und ohne Begründung — sonst hätte die // Belegpflicht nichts zu zeigen, oder zu viel. expect(zahlen.ohneNachweis).toBe(1) }) test('der Kontostand stimmt mit der Summe der Buchungen überein', async () => { const ergebnis = await mitDb(async (db) => { const konto = await db.konto.findFirst({ where: { art: 'GIRO', betreute: { vorname: 'Erika', nachname: 'Musterfrau' } }, select: { id: true }, }) if (!konto) return null const staende = await db.saldostand.findMany({ where: { kontoId: konto.id }, orderBy: { stichtag: 'asc' }, }) if (staende.length < 2) return null const [anfang, ende] = [staende[0]!, staende[staende.length - 1]!] const bewegungen = await db.buchung.findMany({ where: { kontoId: konto.id, geloeschtAm: null, datum: { gt: anfang.stichtag, lte: ende.stichtag }, }, select: { betragCent: true, richtung: true }, }) const summe = bewegungen.reduce( (wert, b) => (b.richtung === 'EINNAHME' ? wert + b.betragCent : wert - b.betragCent), 0n, ) return { erwartet: anfang.betragCent + summe, tatsaechlich: ende.betragCent } }) test.skip(ergebnis === null, 'Kein Demo-Fall mit zwei Kontoständen.') if (!ergebnis) return // Ein Demo-Fall, der sich selbst widerspricht, ist schlimmer als // einer ohne Buchungen: Man rechnet nach und verliert das Vertrauen. expect(ergebnis.tatsaechlich).toBe(ergebnis.erwartet) }) test('die Erkennung wiederkehrender Zahlungen findet mehrere Gruppen', async ({ page }) => { await anmelden(page) await page.goto('/finanzen/wiederkehrend') const inhalt = await page.locator('body').innerText() // Monatliches und Vierteljährliches, beides erkannt. expect(inhalt).toContain('Seniorenzentrum') expect(inhalt).toContain('TeleCare') expect(inhalt).toContain('Beitragsservice') expect(inhalt).toContain('monatlich') expect(inhalt).toContain('vierteljährlich') // Der eigentliche Vorführeffekt: Das Heim steht in drei Schreibweisen // auf dem Auszug und wird trotzdem als eine Zahlung geführt. expect(inhalt).toContain('3 Schreibweisen zusammengefasst') // Die Sterbekasse steht im zweiten Abschnitt: Zu ihr gibt es einen // Vertrag, die Zahlungen sind ihm aber noch nicht zugeordnet. Damit // lässt sich der Handgriff aus der Dauerzahlungs-Zuordnung am // Demo-Fall ausprobieren, statt ihn nur zu beschreiben. expect(inhalt).toContain('Schon einem Vertrag zugeordnet') expect(inhalt).toContain('Nordheim Sterbekasse') expect(inhalt).toContain('als belegt zuordnen') }) test('das Kassenbuch zeigt die Buchungen und die fehlende Quittung', async ({ page }) => { await anmelden(page) await page.goto('/finanzen/buchungen') const inhalt = await page.locator('body').innerText() expect(inhalt).toContain('Heimentgelt') // Die eine Buchung ohne Quittung und ohne Begründung. expect(inhalt).toContain('Modehaus Lindner') }) })