# ED-02-004 Tests

**Status:** Ready for Implementation  
**Parent:** ED-02 Context Persistence

## Ziel

Dieses Dokument beschreibt die Verifikation der Context-Persistenz aus ED-02.

Die Tests prüfen:

- persistente Speicherung von `ContextItem`
- vollständige Rehydration
- Aggregate-Konsistenz
- Löschverhalten
- Rückwärtskompatibilität

Die Tests werden im bestehenden Reconcilix-Stil als direkt ausführbare PHP-Skripte umgesetzt.
Es wird kein zusätzliches Testframework eingeführt.

## Scope

ED-02-004 umfasst:

- Persistenztests
- Rehydrationstests
- Integrationsprüfungen
- Regressionstests für bestehende Persistenzpfade

Nicht Bestandteil:

- neue Testinfrastruktur
- PHPUnit-Einführung
- Performance- oder Lasttests
- Tests für Transport Mapping aus ED-01
- Tests für SourceDelivery oder SourceSystem

## Testvoraussetzungen

Die Tests verwenden:

- die bestehende Testkonfiguration
- die bestehende Datenbankverbindung
- die vorhandenen Migrationen
- die bestehenden Repository-Implementierungen

Vor Beginn der Tests muss die Tabelle `context_item` dem in ED-02 beschriebenen Schema
entsprechen:

```text
context_item
-------------
id
source_value_id
context_type_uri
value
```

Die Spalte `source_uri` ist nicht Bestandteil von ED-02.

## Teststil

Jeder Test wird als direkt ausführbares PHP-Skript umgesetzt:

```bash
php tests/Persistence/ContextPersistenceTest.php
```

Bei erfolgreicher Ausführung endet das Skript mit einer eindeutigen Ausgabe:

```text
ED-02 Context Persistence: OK
```

Bei einem Fehler:

- wird eine Exception ausgelöst oder
- das Skript mit einem von null abweichenden Exit-Code beendet.

## Testfälle

### T001 – SourceValue ohne ContextItems

**Ziel**

Ein `SourceValue` ohne ContextItems kann gespeichert und vollständig geladen werden.

**Ablauf**

1. `SourceValue` ohne ContextItems erzeugen.
2. Aggregate speichern.
3. Aggregate erneut laden.
4. ContextItems auslesen.

**Erwartung**

- Speicherung ist erfolgreich.
- Rehydration ist erfolgreich.
- `contextItems()` liefert eine leere Liste.
- Bestehendes Verhalten vor ED-02 bleibt erhalten.

---

### T002 – Ein ContextItem

**Ziel**

Ein einzelnes `ContextItem` wird vollständig persistiert und rehydriert.

**Ablauf**

1. `SourceValue` erzeugen.
2. Ein `ContextItem` mit `contextTypeUri` und `value` hinzufügen.
3. Aggregate speichern.
4. Aggregate erneut laden.

**Erwartung**

- Genau ein Datensatz wird in `context_item` gespeichert.
- `source_value_id` verweist auf das gespeicherte Aggregate.
- `context_type_uri` entspricht dem Domain-Wert.
- `value` entspricht dem Domain-Wert.
- Das geladene Aggregate enthält genau ein `ContextItem`.

---

### T003 – Mehrere ContextItems

**Ziel**

Mehrere ContextItems eines `SourceValue` werden vollständig gespeichert und deterministisch
geladen.

**Ablauf**

1. `SourceValue` erzeugen.
2. Mehrere ContextItems in definierter Reihenfolge hinzufügen.
3. Aggregate speichern.
4. Aggregate erneut laden.

**Erwartung**

- Für jedes ContextItem existiert genau ein Datensatz.
- Alle Werte bleiben erhalten.
- Die Rehydration erfolgt über `id ASC`.
- Die geladene Reihenfolge entspricht der technischen Einfügereihenfolge.

---

### T004 – Aggregate Update

**Ziel**

Bei erneuter Speicherung entspricht der persistierte Context-Bestand dem aktuellen Zustand
des Aggregats.

**Ablauf**

1. `SourceValue` mit mehreren ContextItems speichern.
2. Aggregate laden.
3. Context-Bestand verändern.
4. Aggregate erneut speichern.
5. Aggregate erneut laden.

**Erwartung**

- Alte, nicht mehr zum Aggregate gehörende ContextItems bleiben nicht erhalten.
- Neue ContextItems werden gespeichert.
- Es entstehen keine unbeabsichtigten Dubletten.
- Der persistierte Bestand entspricht dem aktuellen Aggregate-Zustand.

**Hinweis**

Die konkrete Testausführung richtet sich nach der vorhandenen Änderungs-API des Domain-Modells.
Falls ED-01 nur Hinzufügen, aber kein Entfernen oder Ersetzen unterstützt, wird T004 auf die
tatsächlich vorhandene Aggregate-Operation begrenzt. Für ED-02 wird keine zusätzliche
Domain-API ausschließlich zu Testzwecken eingeführt.

---

### T005 – Cascade Delete

**Ziel**

Beim Löschen eines `SourceValue` werden alle zugehörigen ContextItems gelöscht.

**Ablauf**

1. `SourceValue` mit mindestens einem ContextItem speichern.
2. Existenz der Context-Datensätze prüfen.
3. `SourceValue` über den bestehenden Persistenzpfad löschen.
4. Context-Datensätze erneut abfragen.

**Erwartung**

- Vor dem Löschen sind Context-Datensätze vorhanden.
- Nach dem Löschen existieren keine Context-Datensätze mehr.
- Das Verhalten wird durch `ON DELETE CASCADE` gewährleistet.

**Hinweis**

Falls das bestehende Repository noch keinen fachlichen Löschpfad bereitstellt, kann der Test
die bestehende Datenbank-Testinfrastruktur verwenden. ED-02 führt kein neues
Repository-Löschverfahren ein.

---

### T006 – Rehydration

**Ziel**

Ein persistiertes `SourceValue` wird einschließlich aller ContextItems vollständig als
Domain-Objektgraph wiederhergestellt.

**Ablauf**

1. Testdaten in `source_value` und `context_item` persistieren.
2. Aggregate über das Repository laden.
3. Domain-Objekte und Werte prüfen.

**Erwartung**

- Das geladene Objekt ist ein `SourceValue`.
- Alle Context-Datensätze werden zu `ContextItem`-Objekten.
- `contextTypeUri` und `value` sind vollständig erhalten.
- Technische Datenbank-IDs werden nicht in das Domain-Modell übernommen.
- Es wird kein teilweise rehydriertes Aggregate zurückgegeben.

---

### T007 – Ungültige persistierte Daten

**Ziel**

Fehlerhafte persistierte Daten werden nicht stillschweigend korrigiert oder ignoriert.

**Ablauf**

1. Einen strukturell ungültigen Context-Datensatz vorbereiten, soweit das Datenbankschema dies
   zulässt.
2. Zugehöriges `SourceValue` über das Repository laden.

**Erwartung**

- Die Domain-Invarianten bleiben wirksam.
- Die Rehydration schlägt nachvollziehbar fehl.
- Der Fehler wird nicht in ein leeres oder verändertes `ContextItem` umgewandelt.

**Praktische Begrenzung**

Da `context_type_uri` und `value` als `NOT NULL` definiert sind, betrifft der Test insbesondere
leere Strings, sofern diese durch direkte Testdaten-Insertion erzeugt werden können.

---

### T008 – Transaktionsrollback

**Ziel**

Ein Fehler bei der Context-Persistenz hinterlässt kein teilweise gespeichertes Aggregate.

**Ablauf**

1. Speicherung eines `SourceValue` mit ContextItems beginnen.
2. Innerhalb des Persistenzpfades gezielt einen Fehler auslösen.
3. Transaktion abbrechen.
4. Tabellenbestand prüfen.

**Erwartung**

- Die Transaktion wird zurückgerollt.
- Es bleibt kein unvollständiger Context-Bestand zurück.
- `SourceValue` und ContextItems folgen derselben Transaktionsgrenze.

**Hinweis**

Dieser Test wird nur ergänzt, wenn die vorhandene Testinfrastruktur einen kontrollierten
Fehler innerhalb der Transaktion ohne unverhältnismäßige Test-Sonderlogik ermöglicht.

---

### T009 – Rückwärtskompatibilität

**Ziel**

Bestehende Persistenz- und Rehydrationspfade funktionieren weiterhin.

**Auszuführende bestehende Tests**

Mindestens:

```bash
php tests/Persistence/PersistenceFoundationTest.php
php tests/Persistence/RelationalRepositoriesTest.php
php tests/Persistence/RehydrationTest.php
php tests/Persistence/TransactionBoundaryTest.php
php tests/Migration/SchemaAndMigrationsTest.php
```

Zusätzlich sollen die bereits abgeschlossenen ED-01-Tests weiterhin erfolgreich sein.

**Erwartung**

Alle bestehenden Tests enden ohne Fehler und mit ihrer jeweiligen `OK`-Ausgabe.

## Vorgesehene Testdatei

Die neuen ED-02-Testfälle können gebündelt werden in:

```text
tests/Persistence/ContextPersistenceTest.php
```

Eine Aufteilung in mehrere Dateien ist nur erforderlich, wenn der Testumfang oder die
bestehende Teststruktur dies klar nahelegt.

## Testdaten und Bereinigung

Jeder Test muss:

- eigene, eindeutig erkennbare Testdaten verwenden,
- unabhängig von vorherigen Testläufen ausführbar sein,
- angelegte Daten nach Möglichkeit bereinigen,
- keine vorhandenen fachlichen Daten verändern,
- in wiederholten Testläufen dasselbe Ergebnis liefern.

## Akzeptanzkriterien

ED-02-004 ist abgeschlossen, wenn:

- T001 bis T006 erfolgreich umgesetzt und ausgeführt wurden,
- T007 und T008 umgesetzt wurden, soweit dies mit der bestehenden Infrastruktur ohne
  Test-Sonderarchitektur sinnvoll möglich ist,
- die Context-Persistenz vollständig verifiziert ist,
- die Rehydration vollständig verifiziert ist,
- keine partielle Aggregate-Persistenz beobachtbar ist,
- die Cascade-Delete-Beziehung geprüft ist,
- bestehende Persistenztests weiterhin erfolgreich sind,
- das neue Testskript mit einer eindeutigen `OK`-Ausgabe endet,
- kein neues Testframework eingeführt wurde.
