import { expect, test } from '@playwright/test' import { PrismaClient } from '@prisma/client' import { anmelden } from './hilfen' /** * Schreiben erzeugen — gegen die echte Anwendung. * * Der eigentliche Gewinn dieses Issues ist nicht der Brieftext (den gab es * schon), sondern was danach passiert: Word-Datei, Ablage als * Ausgangsdokument, Wiedervorlage. Genau dieser Teil lässt sich mit * Einheitstests nicht prüfen — er berührt Objektspeicher, Datenbank und * Download. */ const VERTRAG = 'Prüfhausen Police (Test Schreiben)' const GESELLSCHAFT = 'Prüfhausen Lebensversicherung' async function mitDb(arbeit: (db: PrismaClient) => Promise): Promise { const db = new PrismaClient() try { return await arbeit(db) } finally { await db.$disconnect() } } async function aufraeumen(): Promise { await mitDb(async (db) => { await db.dokument.deleteMany({ where: { titel: { contains: 'Rückkaufswert' } } }) await db.dokument.deleteMany({ where: { empfaenger: { contains: 'Prüfhausen' } } }) await db.frist.deleteMany({ where: { titel: { contains: 'Antwort abwarten' } } }) await db.kontakt.deleteMany({ where: { name: { contains: 'Prüfhausen' } } }) await db.vertrag.deleteMany({ where: { bezeichnung: VERTRAG } }) }) } async function vertragAnlegen(): Promise { await mitDb(async (db) => { const betreute = await db.betreute.findMany({ where: { geloeschtAm: null }, select: { id: true }, }) for (const person of betreute) { await db.vertrag.create({ data: { betreuteId: person.id, bezeichnung: VERTRAG, gesellschaft: GESELLSCHAFT, art: 'LEBENSVERSICHERUNG', beitragCent: 4250n, rhythmus: 'MONATLICH', beginnAm: new Date(Date.UTC(2015, 0, 1)), }, }) } }) } /** * Findet die Vertrags-ID der AKTIVEN betreuten Person. * * Welche Person aktiv ist, haengt an einem Cookie — die Datenbank allein * weiss es nicht. Der Weg ueber die Vertragsliste ist zugleich der Weg, * den ein Mensch nimmt. */ async function vertragIdAusOberflaeche(page: import('@playwright/test').Page): Promise { await page.goto('/vertraege') const link = page.getByRole('link', { name: new RegExp(VERTRAG.replace(/[()]/g, '.')) }).first() await expect(link).toBeVisible() const ziel = await link.getAttribute('href') return (ziel ?? '').split('/').pop() ?? '' } test.describe('Schreiben erzeugen', () => { test.beforeAll(async () => { await aufraeumen() await vertragAnlegen() }) test.afterAll(async () => { await aufraeumen() }) test('baut den Entwurf mit Bestellungsabsatz und lässt ihn bearbeiten', async ({ page }) => { await anmelden(page) await page.goto('/schreiben/neu?art=FREI') const brief = page.locator('textarea#text') await expect(brief).toBeVisible() const text = await brief.inputValue() // Ohne den Nachweis der Vertretungsmacht antwortet keine Stelle — // deshalb steht er auch im freien Entwurf drin. expect(text).toMatch(/Betreuungsgericht|bestellt/i) // Und die Lücken sind sichtbar, nicht stillschweigend leer. expect(text).toContain('[') await brief.fill(`${text}\n\nZusatz aus dem Test.`) expect(await brief.inputValue()).toContain('Zusatz aus dem Test.') }) test('erzeugt aus dem Vertrag heraus einen Rückkaufswert-Entwurf', async ({ page }) => { await anmelden(page) const vertragId = await vertragIdAusOberflaeche(page) expect(vertragId).not.toBe('') await page.goto(`/schreiben/neu?art=RUECKKAUFSWERT&vertragId=${vertragId}`) await expect(page.locator('input#empfaengerName')).toHaveValue(GESELLSCHAFT) await expect(page.locator('input#betreff')).not.toHaveValue('') // Die Wiedervorlage ist vorbelegt — 28 Tage. await expect(page.locator('input#wiedervorlageAm')).not.toHaveValue('') const text = await page.locator('textarea#text').inputValue() expect(text).toContain('Rückkaufswert') }) test('liefert die Word-Datei aus', async ({ page }) => { await anmelden(page) await page.goto('/schreiben/neu?art=FREI') await page.locator('input#empfaengerName').fill('Prüfhausen Amt') const [download] = await Promise.all([ page.waitForEvent('download'), page.getByRole('button', { name: 'Als Word-Datei' }).click(), ]) // Sprechender, sortierbarer Name mit Datum vorn. expect(download.suggestedFilename()).toMatch(/^\d{4}-\d{2}-\d{2}_.*\.docx$/) expect(download.suggestedFilename()).toContain('Pruefhausen') }) test('legt das Schreiben in die Akte und setzt die Wiedervorlage', async ({ page }) => { await anmelden(page) const vertragId = await vertragIdAusOberflaeche(page) await page.goto(`/schreiben/neu?art=RUECKKAUFSWERT&vertragId=${vertragId}`) await page.getByRole('button', { name: 'In die Akte legen' }).click() await expect(page.getByText('Das Schreiben liegt in der Akte.')).toBeVisible({ timeout: 30_000, }) await expect(page.getByText(/Wiedervorlage zum/)).toBeVisible() // Und es steht wirklich in der Dokumentenliste, als Ausgang. // // Bewusst ohne tr/li: Die Liste rendert Tabelle UND Karten, je nach // Bildschirmbreite ist eine davon versteckt. Ein Treffer auf die // unsichtbare Fassung sähe wie ein Fehler aus. await page.goto('/dokumente?richtung=AUSGANG') // Die Zusammenfassungszeile gibt es nur einmal — anders als den Titel, // der in Tabelle UND Kartenliste steht. await expect(page.getByText('1 Dokument passen zu den Filtern')).toBeVisible() await expect(page.locator('body')).toContainText('Auskunft über Rückkaufswert') await expect(page.locator('body')).toContainText('Ausgang') // Die Wiedervorlage steht in der Fristenliste. await page.goto('/fristen') await expect(page.getByText(/Antwort abwarten/).first()).toBeVisible() }) test('legt aus einer freien Anschrift einen Kontakt an', async ({ page }) => { await anmelden(page) await page.goto('/schreiben/neu?art=FREI') await page.locator('input#empfaengerName').fill('Prüfhausen Sozialamt') await page.locator('textarea#empfaengerAnschrift').fill('Musterweg 3\n96450 Coburg') await page.getByRole('button', { name: 'Als Kontakt merken' }).click() await expect(page.getByText(/steht jetzt in den Kontakten/)).toBeVisible() // Beim nächsten Mal steht er zur Auswahl. await page.goto('/schreiben/neu?art=FREI') await expect(page.locator('select#kontaktAuswahl')).toContainText('Prüfhausen Sozialamt') }) })