Jeder Vorgang ist eine kleine Akte: Kopfdaten, Aufgabenliste zum Abhaken, Genehmigungsstufen und ein Zeitstrahl, der Dokumente, Kontaktprotokolle, Fristen, Buchungen und Statuswechsel zusammenfuehrt. Die abnahmerelevante Regel: Ein genehmigungspflichtiger Vorgang laesst sich nicht auf VOLLZOGEN setzen, solange kein Beschlussdokument hinterlegt ist. Geprueft wird in darfStatusWechseln() UND in der Server Action - nicht nur im UI, wo das Auswahlfeld die Stufe ohnehin gar nicht erst anbietet. Hintergrund ist § 1858 BGB: die Genehmigung muss vor dem Rechtsgeschaeft vorliegen, nicht danach. Neun Vorlagen mit durchdachter Aufgabenreihenfolge. Bei Wohnungs- aufloesung und Hausverkauf erzwingen sie die Kette Mitteilung -> Genehmigung -> Rechtsgeschaeft; ein Test prueft das. Kanban ohne Drag-and-Drop: Statuswechsel laufen ueber Auswahlfeld und Knopf. Am Handy ist das verlaesslicher, und am Schreibtisch kostet es einen Klick mehr statt einer verlorenen Karte. Zeitzonen: alsTag() bildet den oertlichen Kalendertag auf Mitternacht UTC ab. Ohne das rutscht in Deutschland jede Faelligkeit einen Tag zurueck. 33 Tests. Etappe: 2 Phase: Alltag
495 lines
17 KiB
TypeScript
495 lines
17 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
darfStatusWechseln,
|
|
GENEHMIGUNGSKETTE,
|
|
moeglicheStatusWechsel,
|
|
naechsterStatus,
|
|
RECHTSGRUNDLAGEN,
|
|
stufeVon,
|
|
} from '@/lib/vorgaenge/genehmigungskette'
|
|
import { VORLAGEN, vorlageAnwenden, vorlageFinden } from '@/lib/vorgaenge/vorlagen'
|
|
import { zeitstrahlBauen } from '@/lib/vorgaenge/zeitstrahl'
|
|
import {
|
|
nachfassenFaellig,
|
|
sachstandsanfrageErzeugen,
|
|
} from '@/lib/vorgaenge/sachstandsanfrage'
|
|
|
|
/**
|
|
* Diese Tests beschreiben, was fachlich gelten soll - nicht, welche
|
|
* Funktion aufgerufen wird. Keine Datenbank: alles hier ist reine Logik.
|
|
*/
|
|
|
|
// =============================================================================
|
|
describe('Genehmigungskette', () => {
|
|
it('läuft in der vorgeschriebenen Reihenfolge vom Plan bis zum Vollzug', () => {
|
|
expect(GENEHMIGUNGSKETTE).toEqual([
|
|
'GEPLANT',
|
|
'MITGETEILT',
|
|
'BEANTRAGT',
|
|
'ANGEHOERT',
|
|
'ERTEILT',
|
|
'RECHTSKRAEFTIG',
|
|
'VOLLZOGEN',
|
|
])
|
|
})
|
|
|
|
it('lässt jeweils genau eine Stufe vorwärts zu', () => {
|
|
for (let i = 0; i < GENEHMIGUNGSKETTE.length - 1; i++) {
|
|
const von = GENEHMIGUNGSKETTE[i]!
|
|
const nach = GENEHMIGUNGSKETTE[i + 1]!
|
|
// Der letzte Schritt braucht den Beschluss - der wird unten geprüft.
|
|
const beschluss = nach === 'VOLLZOGEN' ? 'dok-1' : null
|
|
expect(darfStatusWechseln({ status: von, beschlussDokumentId: beschluss }, nach).erlaubt).toBe(
|
|
true,
|
|
)
|
|
expect(naechsterStatus(von)).toBe(nach)
|
|
}
|
|
})
|
|
|
|
it('verweigert das Überspringen von Stufen und nennt die übersprungenen', () => {
|
|
const pruefung = darfStatusWechseln(
|
|
{ status: 'BEANTRAGT', beschlussDokumentId: 'dok-1' },
|
|
'VOLLZOGEN',
|
|
)
|
|
expect(pruefung.erlaubt).toBe(false)
|
|
expect(pruefung.grund).toContain('Anhörung erfolgt')
|
|
expect(pruefung.grund).toContain('§ 1858 BGB')
|
|
})
|
|
|
|
it('erlaubt eine Stufe zurück als Korrektur, aber nicht zwei', () => {
|
|
expect(darfStatusWechseln({ status: 'ERTEILT' }, 'ANGEHOERT').erlaubt).toBe(true)
|
|
expect(darfStatusWechseln({ status: 'ERTEILT' }, 'BEANTRAGT').erlaubt).toBe(false)
|
|
})
|
|
|
|
// --- die abnahmerelevante Regel -------------------------------------------
|
|
it('sperrt den Vollzug, solange kein Beschlussdokument hinterlegt ist', () => {
|
|
const ohneBeschluss = darfStatusWechseln(
|
|
{ status: 'RECHTSKRAEFTIG', beschlussDokumentId: null },
|
|
'VOLLZOGEN',
|
|
)
|
|
expect(ohneBeschluss.erlaubt).toBe(false)
|
|
expect(ohneBeschluss.grund).toContain('Beschluss')
|
|
|
|
const mitBeschluss = darfStatusWechseln(
|
|
{ status: 'RECHTSKRAEFTIG', beschlussDokumentId: 'dok-42' },
|
|
'VOLLZOGEN',
|
|
)
|
|
expect(mitBeschluss.erlaubt).toBe(true)
|
|
})
|
|
|
|
it('bietet den Vollzug ohne Beschluss gar nicht erst zur Auswahl an', () => {
|
|
expect(moeglicheStatusWechsel({ status: 'RECHTSKRAEFTIG', beschlussDokumentId: null })).not.toContain(
|
|
'VOLLZOGEN',
|
|
)
|
|
expect(moeglicheStatusWechsel({ status: 'RECHTSKRAEFTIG', beschlussDokumentId: 'dok-42' })).toContain(
|
|
'VOLLZOGEN',
|
|
)
|
|
})
|
|
|
|
it('behandelt den Vollzug als endgültig', () => {
|
|
for (const status of [...GENEHMIGUNGSKETTE, 'VERSAGT'] as const) {
|
|
if (status === 'VOLLZOGEN') continue
|
|
expect(
|
|
darfStatusWechseln({ status: 'VOLLZOGEN', beschlussDokumentId: 'dok-1' }, status).erlaubt,
|
|
).toBe(false)
|
|
}
|
|
})
|
|
|
|
it('lässt die Versagung nur zu, solange etwas anhängig und nichts rechtskräftig ist', () => {
|
|
for (const status of ['MITGETEILT', 'BEANTRAGT', 'ANGEHOERT', 'ERTEILT'] as const) {
|
|
expect(darfStatusWechseln({ status }, 'VERSAGT').erlaubt).toBe(true)
|
|
}
|
|
for (const status of ['GEPLANT', 'RECHTSKRAEFTIG'] as const) {
|
|
expect(darfStatusWechseln({ status }, 'VERSAGT').erlaubt).toBe(false)
|
|
}
|
|
})
|
|
|
|
it('führt nach einer Versagung zurück auf den Anfang - und nur dorthin', () => {
|
|
expect(darfStatusWechseln({ status: 'VERSAGT' }, 'GEPLANT').erlaubt).toBe(true)
|
|
expect(darfStatusWechseln({ status: 'VERSAGT' }, 'BEANTRAGT').erlaubt).toBe(false)
|
|
expect(stufeVon('VERSAGT')).toBe(-1)
|
|
})
|
|
|
|
it('meldet einen Wechsel auf den bereits gesetzten Status als unnötig', () => {
|
|
const pruefung = darfStatusWechseln({ status: 'BEANTRAGT' }, 'BEANTRAGT')
|
|
expect(pruefung.erlaubt).toBe(false)
|
|
expect(pruefung.grund).toContain('bereits')
|
|
})
|
|
|
|
it('erklärt jede wählbare Rechtsgrundlage im Klartext', () => {
|
|
const werte = RECHTSGRUNDLAGEN.map((r) => r.wert)
|
|
for (const paragraph of [
|
|
'§ 1850 BGB',
|
|
'§ 1833 BGB',
|
|
'§ 1854 BGB',
|
|
'§ 1851 BGB',
|
|
'§ 1849 BGB',
|
|
'§ 1859 BGB',
|
|
]) {
|
|
expect(werte).toContain(paragraph)
|
|
}
|
|
for (const grundlage of RECHTSGRUNDLAGEN) {
|
|
expect(grundlage.erklaerung.length).toBeGreaterThan(40)
|
|
expect(grundlage.beispiele.length).toBeGreaterThan(0)
|
|
}
|
|
})
|
|
})
|
|
|
|
// =============================================================================
|
|
describe('Vorgangs-Vorlagen', () => {
|
|
it('bringt die neun Vorlagen mit, auf die sich die anderen Module verlassen', () => {
|
|
const schluessel = VORLAGEN.map((v) => v.schluessel)
|
|
expect(schluessel).toEqual(
|
|
expect.arrayContaining([
|
|
'heimeinzug',
|
|
'antrag-hilfe-zur-pflege',
|
|
'wohnungsaufloesung',
|
|
'hausverkauf',
|
|
'darlehen-91-sgb-xii',
|
|
'versicherungsverwertung',
|
|
'pflegegrad-hoeherstufung',
|
|
'steuererklaerung',
|
|
'widerspruch-bescheid',
|
|
]),
|
|
)
|
|
expect(new Set(schluessel).size).toBe(schluessel.length)
|
|
})
|
|
|
|
it('gibt jeder Vorlage eine vorbefüllte Aufgabenliste', () => {
|
|
for (const vorlage of VORLAGEN) {
|
|
expect(vorlage.aufgaben.length).toBeGreaterThanOrEqual(4)
|
|
expect(vorlage.titel.length).toBeGreaterThan(3)
|
|
expect(vorlage.beschreibung.length).toBeGreaterThan(20)
|
|
}
|
|
})
|
|
|
|
it('nennt bei jeder genehmigungspflichtigen Vorlage die Vorschrift', () => {
|
|
for (const vorlage of VORLAGEN.filter((v) => v.genehmigungspflichtig)) {
|
|
expect(vorlage.rechtsgrundlage).toBeTruthy()
|
|
}
|
|
expect(vorlageFinden('wohnungsaufloesung')?.rechtsgrundlage).toBe('§ 1833 BGB')
|
|
expect(vorlageFinden('hausverkauf')?.rechtsgrundlage).toBe('§ 1850 Nr. 1 BGB')
|
|
expect(vorlageFinden('darlehen-91-sgb-xii')?.genehmigungspflichtig).toBe(true)
|
|
})
|
|
|
|
it('stellt bei der Wohnungsauflösung die Mitteilung ans Gericht vor die Kündigung', () => {
|
|
const aufgaben = vorlageFinden('wohnungsaufloesung')!.aufgaben.map((a) => a.titel)
|
|
const mitteilung = aufgaben.findIndex((t) => t.includes('Mitteilung an das Betreuungsgericht'))
|
|
const genehmigung = aufgaben.findIndex((t) => t.includes('Genehmigung des Gerichts abwarten'))
|
|
const kuendigung = aufgaben.findIndex((t) => t.includes('Mietverhältnis kündigen'))
|
|
|
|
expect(mitteilung).toBeGreaterThanOrEqual(0)
|
|
expect(mitteilung).toBeLessThan(genehmigung)
|
|
expect(genehmigung).toBeLessThan(kuendigung)
|
|
})
|
|
|
|
it('holt beim Hausverkauf die Genehmigung vor die Beurkundung', () => {
|
|
const aufgaben = vorlageFinden('hausverkauf')!.aufgaben.map((a) => a.titel)
|
|
const einreichen = aufgaben.findIndex((t) => t.includes('Kaufvertragsentwurf beim'))
|
|
const rechtskraft = aufgaben.findIndex((t) => t.includes('Rechtskraft prüfen'))
|
|
const beurkundung = aufgaben.findIndex((t) => t.includes('Beurkundung'))
|
|
|
|
expect(einreichen).toBeLessThan(rechtskraft)
|
|
expect(rechtskraft).toBeLessThan(beurkundung)
|
|
})
|
|
|
|
it('setzt den Widerspruch fristwahrend an den Anfang und legt die Monatsfrist an', () => {
|
|
const vorlage = vorlageFinden('widerspruch-bescheid')!
|
|
expect(vorlage.aufgaben[0]?.titel).toBe(
|
|
'Widerspruch fristwahrend einlegen, Begründung nachreichen',
|
|
)
|
|
const frist = vorlage.fristen?.find((f) => f.rechtsgrundlage === '§ 84 SGG')
|
|
expect(frist?.tageBisFaellig).toBe(30)
|
|
})
|
|
|
|
it('rechnet die Fälligkeiten vom Anlegedatum aus, ohne Uhrzeit', () => {
|
|
const ergebnis = vorlageAnwenden('heimeinzug', new Date(2026, 0, 15, 17, 42))
|
|
|
|
expect(ergebnis.aufgaben).toHaveLength(8)
|
|
expect(ergebnis.aufgaben[0]?.titel).toBe('Heimvertrag prüfen und gegenzeichnen')
|
|
// 15.01.2026 + 7 Tage = 22.01.2026, Mitternacht UTC (@db.Date).
|
|
expect(ergebnis.aufgaben[0]?.faelligAm?.toISOString()).toBe('2026-01-22T00:00:00.000Z')
|
|
expect(ergebnis.aufgaben[1]?.faelligAm?.toISOString()).toBe('2026-01-29T00:00:00.000Z')
|
|
|
|
// Die Reihenfolge der Vorlage wird festgeschrieben.
|
|
expect(ergebnis.aufgaben.map((a) => a.reihenfolge)).toEqual([0, 1, 2, 3, 4, 5, 6, 7])
|
|
|
|
expect(ergebnis.fristen).toHaveLength(1)
|
|
expect(ergebnis.fristen[0]?.datum.toISOString()).toBe('2026-03-16T00:00:00.000Z')
|
|
})
|
|
|
|
it('rechnet über einen Monatswechsel hinweg richtig', () => {
|
|
const ergebnis = vorlageAnwenden('widerspruch-bescheid', new Date(2026, 1, 20))
|
|
// 20.02.2026 + 30 Tage = 22.03.2026
|
|
expect(ergebnis.fristen[0]?.datum.toISOString()).toBe('2026-03-22T00:00:00.000Z')
|
|
})
|
|
|
|
it('weist einen erfundenen Vorlagenschlüssel zurück', () => {
|
|
expect(() => vorlageAnwenden('gibt-es-nicht')).toThrowError(/Vorlage/)
|
|
})
|
|
})
|
|
|
|
// =============================================================================
|
|
describe('Zeitstrahl der Fallakte', () => {
|
|
const grundlage = {
|
|
vorgang: {
|
|
titel: 'Hausverkauf',
|
|
erstelltAm: new Date('2026-01-10T09:00:00.000Z'),
|
|
erledigtAm: null,
|
|
},
|
|
}
|
|
|
|
it('sortiert alle Quellen zusammen, neueste zuerst', () => {
|
|
const eintraege = zeitstrahlBauen({
|
|
...grundlage,
|
|
dokumente: [
|
|
{
|
|
id: 'd1',
|
|
titel: 'Kaufvertragsentwurf',
|
|
eingangAm: new Date('2026-03-01T00:00:00.000Z'),
|
|
versandAm: null,
|
|
erstelltAm: new Date('2026-03-05T00:00:00.000Z'),
|
|
absender: 'Notariat Bayreuth',
|
|
empfaenger: null,
|
|
},
|
|
],
|
|
kontaktprotokolle: [
|
|
{
|
|
id: 'k1',
|
|
datum: new Date('2026-02-01T10:00:00.000Z'),
|
|
art: 'TELEFONAT',
|
|
gespraechspartner: 'Rechtspfleger Meier',
|
|
mitBetreuter: false,
|
|
inhalt: 'Ablauf der Genehmigung besprochen.',
|
|
},
|
|
],
|
|
fristen: [
|
|
{
|
|
id: 'f1',
|
|
titel: 'Wertgutachten anfordern',
|
|
datum: new Date('2026-04-01T00:00:00.000Z'),
|
|
erledigtAm: null,
|
|
ausschlussfrist: false,
|
|
rechtsgrundlage: null,
|
|
},
|
|
],
|
|
buchungen: [
|
|
{
|
|
id: 'b1',
|
|
datum: new Date('2026-05-01T00:00:00.000Z'),
|
|
betragCent: 150_000,
|
|
richtung: 'AUSGABE',
|
|
gegenstelle: 'Gutachterbüro',
|
|
verwendungszweck: 'Verkehrswertgutachten',
|
|
},
|
|
],
|
|
})
|
|
|
|
expect(eintraege.map((e) => e.id)).toEqual([
|
|
'BUCHUNG:b1',
|
|
'FRIST:f1',
|
|
'DOKUMENT:d1',
|
|
'KONTAKT:k1',
|
|
'ANGELEGT:vorgang',
|
|
])
|
|
})
|
|
|
|
it('kann auch von hinten gelesen werden', () => {
|
|
const eintraege = zeitstrahlBauen(
|
|
{
|
|
...grundlage,
|
|
fristen: [
|
|
{
|
|
id: 'f1',
|
|
titel: 'Frist A',
|
|
datum: new Date('2026-04-01T00:00:00.000Z'),
|
|
erledigtAm: null,
|
|
ausschlussfrist: true,
|
|
rechtsgrundlage: '§ 1878 BGB',
|
|
},
|
|
],
|
|
},
|
|
{ reihenfolge: 'aelteste-zuerst' },
|
|
)
|
|
|
|
expect(eintraege[0]?.id).toBe('ANGELEGT:vorgang')
|
|
expect(eintraege[1]?.titel).toBe('Ausschlussfrist: Frist A')
|
|
})
|
|
|
|
it('nimmt beim Dokument den Eingang, sonst den Versand', () => {
|
|
const eintraege = zeitstrahlBauen({
|
|
...grundlage,
|
|
dokumente: [
|
|
{
|
|
id: 'd1',
|
|
titel: 'Antrag',
|
|
eingangAm: null,
|
|
versandAm: new Date('2026-02-10T00:00:00.000Z'),
|
|
erstelltAm: new Date('2026-02-20T00:00:00.000Z'),
|
|
absender: null,
|
|
empfaenger: 'Bezirk Oberfranken',
|
|
},
|
|
],
|
|
})
|
|
|
|
const dokument = eintraege.find((e) => e.id === 'DOKUMENT:d1')
|
|
expect(dokument?.datum.toISOString()).toBe('2026-02-10T00:00:00.000Z')
|
|
expect(dokument?.detail).toBe('Versand an Bezirk Oberfranken')
|
|
})
|
|
|
|
it('macht aus den Datumsfeldern einer Genehmigung die Chronik des Verfahrens', () => {
|
|
const eintraege = zeitstrahlBauen({
|
|
...grundlage,
|
|
genehmigungen: [
|
|
{
|
|
id: 'g1',
|
|
titel: 'Verkauf Hausgrundstück',
|
|
rechtsgrundlage: '§ 1850 BGB',
|
|
status: 'RECHTSKRAEFTIG',
|
|
mitteilungAm: new Date('2026-02-01T00:00:00.000Z'),
|
|
antragAm: new Date('2026-02-15T00:00:00.000Z'),
|
|
anhoerungAm: null,
|
|
beschlussAm: new Date('2026-03-20T00:00:00.000Z'),
|
|
rechtskraftAm: new Date('2026-04-05T00:00:00.000Z'),
|
|
vollzugAm: null,
|
|
},
|
|
],
|
|
})
|
|
|
|
const genehmigung = eintraege.filter((e) => e.art === 'GENEHMIGUNG')
|
|
expect(genehmigung).toHaveLength(4)
|
|
expect(genehmigung[0]?.titel).toBe('Genehmigung: Rechtskräftig')
|
|
expect(genehmigung.at(-1)?.titel).toBe('Genehmigung: Dem Gericht mitgeteilt')
|
|
})
|
|
|
|
it('zeigt Ausgaben mit negativem Vorzeichen', () => {
|
|
const eintraege = zeitstrahlBauen({
|
|
...grundlage,
|
|
buchungen: [
|
|
{
|
|
id: 'b1',
|
|
datum: new Date('2026-05-01T00:00:00.000Z'),
|
|
betragCent: 4200,
|
|
richtung: 'AUSGABE',
|
|
gegenstelle: null,
|
|
verwendungszweck: null,
|
|
},
|
|
{
|
|
id: 'b2',
|
|
datum: new Date('2026-05-02T00:00:00.000Z'),
|
|
betragCent: 9900,
|
|
richtung: 'EINNAHME',
|
|
gegenstelle: null,
|
|
verwendungszweck: null,
|
|
},
|
|
],
|
|
})
|
|
|
|
expect(eintraege.find((e) => e.id === 'BUCHUNG:b1')?.betragCent).toBe(-4200)
|
|
expect(eintraege.find((e) => e.id === 'BUCHUNG:b2')?.betragCent).toBe(9900)
|
|
})
|
|
|
|
it('hält die Reihenfolge bei gleichem Datum stabil', () => {
|
|
const gleich = new Date('2026-06-01T00:00:00.000Z')
|
|
const einmal = zeitstrahlBauen({
|
|
...grundlage,
|
|
fristen: [
|
|
{
|
|
id: 'f1',
|
|
titel: 'A',
|
|
datum: gleich,
|
|
erledigtAm: null,
|
|
ausschlussfrist: false,
|
|
rechtsgrundlage: null,
|
|
},
|
|
],
|
|
dokumente: [
|
|
{
|
|
id: 'd1',
|
|
titel: 'B',
|
|
eingangAm: gleich,
|
|
versandAm: null,
|
|
erstelltAm: gleich,
|
|
absender: null,
|
|
empfaenger: null,
|
|
},
|
|
],
|
|
})
|
|
|
|
// Dokument vor Frist: was passiert ist, steht über dem, was ansteht.
|
|
expect(einmal.map((e) => e.id).slice(0, 2)).toEqual(['DOKUMENT:d1', 'FRIST:f1'])
|
|
})
|
|
})
|
|
|
|
// =============================================================================
|
|
describe('Sachstandsanfrage', () => {
|
|
const eingabe = {
|
|
vorgangTitel: 'Antrag auf Hilfe zur Pflege',
|
|
gegenstelle: 'Bezirk Oberfranken',
|
|
aktenzeichen: 'HzP 2026/4711',
|
|
letzterKontaktAm: new Date(2026, 4, 12),
|
|
betreute: {
|
|
vorname: 'Erika',
|
|
nachname: 'Mustermann',
|
|
geburtsdatum: new Date(1948, 2, 3),
|
|
},
|
|
betreuer: {
|
|
name: 'Florian Wilde',
|
|
aktenzeichenGericht: 'XVII 123/25',
|
|
betreuungsgericht: 'Amtsgericht Bayreuth',
|
|
},
|
|
heute: new Date(2026, 5, 30),
|
|
}
|
|
|
|
it('nennt Aktenzeichen, Gegenstelle und das Datum des letzten Kontakts', () => {
|
|
const anfrage = sachstandsanfrageErzeugen(eingabe)
|
|
|
|
expect(anfrage.text).toContain('Bezirk Oberfranken')
|
|
expect(anfrage.text).toContain('HzP 2026/4711')
|
|
expect(anfrage.text).toContain('12.05.2026')
|
|
expect(anfrage.text).toContain('30.06.2026')
|
|
expect(anfrage.text).toContain('Erika Mustermann')
|
|
expect(anfrage.text).toContain('XVII 123/25')
|
|
})
|
|
|
|
it('bittet ausdrücklich um den Sachstand und schließt mit dem Namen des Betreuers', () => {
|
|
const anfrage = sachstandsanfrageErzeugen(eingabe)
|
|
|
|
expect(anfrage.text).toContain('Sachstand')
|
|
expect(anfrage.text).toContain('Mit freundlichen Grüßen')
|
|
expect(anfrage.text.trimEnd().endsWith('Rechtlicher Betreuer')).toBe(true)
|
|
})
|
|
|
|
it('rechnet die Tage seit dem letzten Kontakt aus', () => {
|
|
// 12.05.2026 bis 30.06.2026 sind 49 Tage.
|
|
const anfrage = sachstandsanfrageErzeugen(eingabe)
|
|
expect(anfrage.tageSeitKontakt).toBe(49)
|
|
expect(anfrage.text).toContain('49 Tage')
|
|
})
|
|
|
|
it('kommt ohne erfassten letzten Kontakt aus', () => {
|
|
const anfrage = sachstandsanfrageErzeugen({ ...eingabe, letzterKontaktAm: null })
|
|
expect(anfrage.tageSeitKontakt).toBeNull()
|
|
expect(anfrage.text).toContain('bisher nicht eingegangen')
|
|
})
|
|
|
|
it('baut einen Betreff, der die Sache eindeutig macht', () => {
|
|
const anfrage = sachstandsanfrageErzeugen(eingabe)
|
|
expect(anfrage.betreff).toBe(
|
|
'Sachstandsanfrage: Antrag auf Hilfe zur Pflege · Erika Mustermann, geb. 03.03.1948 · Az. HzP 2026/4711',
|
|
)
|
|
})
|
|
|
|
it('spricht einen bekannten Ansprechpartner direkt an', () => {
|
|
const anfrage = sachstandsanfrageErzeugen({ ...eingabe, ansprechpartner: 'Frau Schmidt' })
|
|
expect(anfrage.text).toContain('Sehr geehrte(r) Frau Schmidt,')
|
|
})
|
|
|
|
it('hält Nachfassen erst nach sechs Wochen für angebracht', () => {
|
|
const heute = new Date(2026, 5, 30)
|
|
expect(nachfassenFaellig(new Date(2026, 5, 20), heute)).toBe(false)
|
|
expect(nachfassenFaellig(new Date(2026, 4, 12), heute)).toBe(true)
|
|
expect(nachfassenFaellig(null, heute)).toBe(true)
|
|
})
|
|
})
|