import { describe, expect, it } from 'vitest' import { SPERRFRIST_TAGE, bewerten, heuteSchonAngefragt, kandidatenBewerten, type SerienKandidat, } from '@/lib/vertraege/serienabfrage' import { RUECKKAUFSWERT_WIEDERVORLAGE_TAGE } from '@/lib/vertraege/rueckkaufswert' /** * Serienabfrage der Rückkaufswerte — die Auswahllogik. * * Der teuerste Fehler wäre hier ein Brief zu viel an der falschen Stelle * (die Gesellschaft antwortet auf die zweite Anfrage mit Verwirrung) oder * ein stumm fehlender Vertrag (der Wert fehlt dann im Vermögensverzeichnis). * Beides wird geprüft. */ const HEUTE = new Date('2026-08-23T00:00:00.000Z') function vertrag(teile: Partial = {}): SerienKandidat { return { id: 'v1', bezeichnung: 'Lebensversicherung', gesellschaft: 'Allianz', art: 'LEBENSVERSICHERUNG', status: 'AKTIV', rueckkaufswertAngefragtAm: null, ...teile, } } function vorTagen(tage: number): Date { const d = new Date(HEUTE) d.setUTCDate(d.getUTCDate() - tage) return d } describe('Bewertung eines Vertrags', () => { it('wählt eine unbefragte Lebensversicherung vor', () => { const b = bewerten(vertrag(), HEUTE) expect(b.moeglich).toBe(true) expect(b.vorausgewaehlt).toBe(true) expect(b.hindernis).toBeNull() }) it('schließt Vertragsarten ohne Rückkaufswert aus — mit Begründung', () => { const b = bewerten(vertrag({ art: 'HAFTPFLICHT' }), HEUTE) expect(b.moeglich).toBe(false) expect(b.hindernis).toContain('keinen Rückkaufswert') }) it('schließt verwertete und abgelaufene Verträge aus', () => { expect(bewerten(vertrag({ status: 'VERWERTET' }), HEUTE).moeglich).toBe(false) expect(bewerten(vertrag({ status: 'ABGELAUFEN' }), HEUTE).moeglich).toBe(false) }) it('lässt einen gekündigten Vertrag zu', () => { // Bis zum Wirksamwerden besteht der Vertrag - und genau dann will der // Sozialhilfeträger den Wert sehen. const b = bewerten(vertrag({ status: 'GEKUENDIGT' }), HEUTE) expect(b.moeglich).toBe(true) }) it('verlangt eine Gesellschaft und sagt, was zu tun ist', () => { const b = bewerten(vertrag({ gesellschaft: null }), HEUTE) expect(b.moeglich).toBe(false) expect(b.hindernis).toContain('nachtragen') }) it('wählt einen frisch angefragten Vertrag NICHT vor, lässt ihn aber wählbar', () => { // Der Brief könnte verloren gegangen sein - dann wählt man von Hand an. const b = bewerten(vertrag({ rueckkaufswertAngefragtAm: vorTagen(10) }), HEUTE) expect(b.moeglich).toBe(true) expect(b.vorausgewaehlt).toBe(false) expect(b.hindernis).toContain('bereits angefragt') expect(b.tageSeitAnfrage).toBe(10) }) it('wählt nach Ablauf der Sperrfrist wieder vor', () => { const b = bewerten(vertrag({ rueckkaufswertAngefragtAm: vorTagen(SPERRFRIST_TAGE) }), HEUTE) expect(b.vorausgewaehlt).toBe(true) }) it('hält die Sperrfrist mit der Wiedervorlage im Gleichschritt', () => { // Beide 28 Tage: Solange die Wiedervorlage läuft, ist die Antwort // unterwegs - eine zweite Anfrage davor wäre nur Verwirrung. expect(SPERRFRIST_TAGE).toBe(RUECKKAUFSWERT_WIEDERVORLAGE_TAGE) }) }) describe('Sortierung der Kandidaten', () => { it('stellt Vorausgewählte nach oben, Unmögliche ans Ende', () => { const bewertet = kandidatenBewerten( [ vertrag({ id: 'a', bezeichnung: 'Zulassung', art: 'HAFTPFLICHT' }), vertrag({ id: 'b', bezeichnung: 'Beitragsfrei' }), vertrag({ id: 'c', bezeichnung: 'Angefragt', rueckkaufswertAngefragtAm: vorTagen(5) }), ], HEUTE, ) expect(bewertet[0]!.vertrag.id).toBe('b') expect(bewertet[1]!.vertrag.id).toBe('c') expect(bewertet[2]!.vertrag.id).toBe('a') }) }) describe('Dublettenschutz', () => { it('erkennt die Anfrage vom selben Tag', () => { expect(heuteSchonAngefragt(HEUTE, HEUTE)).toBe(true) }) it('lässt eine bewusste zweite Anfrage nach einer Woche zu', () => { // Tagesgenau, nicht sperrfristgenau: Der Doppelklick soll abgefangen // werden, die bewusste Wiederholung (Brief verloren) nicht. expect(heuteSchonAngefragt(vorTagen(7), HEUTE)).toBe(false) }) it('meldet ohne Anfrage nichts', () => { expect(heuteSchonAngefragt(null, HEUTE)).toBe(false) }) })