Neue Admin-Funktion fuer angehaltene Abo-Bestellungen, die der Kunde ausserhalb des Systems geliefert und verrechnet hat. Aktion (AboExternalCompletionService): - Punkte gutschreiben wie bei eingegangener Zahlung (SalesPointsVolume, idempotent gegen Doppelbuchung) - UserAboOrder auf neuen gruenen Status 8 "extern erledigt"; paid bleibt false - Bestellung: shipped=2 (Lieferung bestaetigt), keine Rechnung/kein Lieferschein - Blockade aufheben: Abo zurueck auf status=2 (okay), aktiv, next_date neu, damit der naechste Termin regulaer laeuft - wie bei regulaerer Ausfuehrung: IncentiveTracker + AboOneTimeService-Purge Einstiegspunkte: Button + Bestaetigungs-Modal auf der Kunden-Bestelldetailseite (SalesController) und auf der Abo-Detailseite (Admin\AboController@externDone, Route admin_abos_extern_done). Status 8 (gruen) in UserAbo/UserAboOrder, Labels de/en. Tests: tests/Feature/AboExternalCompletionTest (Happy Path, Idempotenz, bezahlt-/Nicht-Abo-Guards, Abo-Detail-Einstieg) - 5 gruen. Zusaetzlich: docs/2026-06-11-test-suite-vorbestehende-fehler.md - Diagnose der 93 vorbestehenden (von master geerbten) Test-Suite-Fehler. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
80 lines
4.1 KiB
Markdown
80 lines
4.1 KiB
Markdown
# Vorbestehende Test-Suite-Fehler (Diagnose)
|
|
|
|
**Datum:** 2026-06-11
|
|
**Branch bei Aufnahme:** `payment/phase-r-payone-refactoring`
|
|
**Status:** Nur dokumentiert — keine Codeänderung vorgenommen.
|
|
|
|
## Ausgangslage
|
|
|
|
`php artisan test --compact` meldet aktuell **93 failed, 1 skipped, 448 passed**.
|
|
Diese Fehler sind **nicht** durch die Abo-„Extern erledigt"-Funktion oder durch
|
|
diesen Branch verursacht.
|
|
|
|
### Beweis, dass die Fehler von `master` geerbt sind
|
|
|
|
- Der einzige test-relevante Commit dieses Branches (`8593dbe`, Payment Phase R)
|
|
ändert an `phpunit.xml` nur **eine** Zeile: `PAYONE_KEY_HASH` (DB-Config
|
|
unberührt).
|
|
- `DB_DATABASE=":memory:"` mit `force="true"` steht bereits auf `master`.
|
|
- Legacy-Factory `database/factories/UserFactory.php` (`$factory->define`) und alle
|
|
betroffenen Testdateien existieren unverändert bereits auf `master`.
|
|
- Gegenprobe per `git stash`: dasselbe Test-Subset scheitert mit und ohne die
|
|
Änderungen dieses Branches identisch.
|
|
|
|
## Vier unabhängige Ursachen
|
|
|
|
### 1. Legacy-Factories + fehlendes `HasFactory` (~20 Tests)
|
|
- **Symptom:** `Call to undefined method App\User::factory()`
|
|
- **Ursache:** `App\User` nutzt das `HasFactory`-Trait nicht; `UserFactory.php` ist
|
|
im alten `$factory->define()`-Stil (Laravel ≤6) statt klassenbasiert
|
|
(`extends Factory`). Die Tests rufen die neue API `User::factory()`.
|
|
- **Betroffen:** `Unit/BusinessPlan/BusinessUserItemOptimizedTest`,
|
|
`Unit/BusinessPlan/BusinessUserRepositoryTest`, Teile von
|
|
`Unit/Incentive/IncentiveTrackerTest`.
|
|
- **Fix (sicher, hoher Hebel):** `App\User` → `use HasFactory` + `newFactory()`
|
|
(nötig, weil das Model unter `App\` statt `App\Models\` liegt);
|
|
`UserFactory` auf `class UserFactory extends Factory { protected $model = \App\User::class; … }`
|
|
umstellen.
|
|
|
|
### 2. `DatabaseTransactions` auf `:memory:`-SQLite (~32 Tests)
|
|
- **Symptom:** `SQLSTATE … no such table: settings` (o. ä.)
|
|
- **Ursache:** Das Trait `DatabaseTransactions` führt **keine** Migrationen aus,
|
|
sondern setzt ein bereits migriertes Schema voraus. Bei `:memory:` startet jede
|
|
Connection leer → Tabellen fehlen. (`RefreshDatabase`-Tests migrieren und laufen
|
|
daher grün.)
|
|
- **Betroffen:** `Unit/Services/InvoiceServiceTest`,
|
|
`Feature/Payment/ConcurrentPaymentTest`, `Feature/Payment/PayoneRaceConditionTest`.
|
|
- **Fix (Entscheidung nötig):** entweder Trait auf `RefreshDatabase` umstellen,
|
|
**oder** Test-DB-Strategie ändern (persistente, vorab migrierte SQLite-Datei
|
|
statt `:memory:`). Architekturentscheidung — Race-Condition-/Concurrency-Tests
|
|
können bewusst eine persistente DB erwarten.
|
|
|
|
### 3. Domain-aware Routen in Unit-Tests nicht geladen (~10 Tests)
|
|
- **Symptom:** `Route [modal_load] not defined.`
|
|
- **Ursache:** Die Anwendung lädt Routen host-abhängig (siehe CLAUDE.md,
|
|
Multi-Tenant Routing). In Unit-Tests ohne Host sind die `routes/domains/*`-Routen
|
|
nicht registriert; `TreeHtmlRenderer` erzeugt aber HTML mit `route('modal_load')`.
|
|
- **Betroffen:** `Unit/BusinessPlan/TreeHtmlRendererTest`.
|
|
- **Fix (mittel):** Routen im Test-Setup laden bzw. den Renderer von der
|
|
Route-Generierung entkoppeln (URL injizieren).
|
|
|
|
### 4. Tests veraltet ggü. refaktoriertem Konstruktor (~19 Tests)
|
|
- **Symptom:**
|
|
`TreeCalcBotOptimized::__construct(): Argument #4 ($forceLiveCalculation) must be of type bool, …BusinessUserRepository given`
|
|
- **Ursache:** Die Konstruktor-Signatur von
|
|
`App\Services\BusinessPlan\TreeCalcBotOptimized` wurde geändert; der Test
|
|
(`TreeCalcBotOptimizedTest`) übergibt die Argumente noch in alter Reihenfolge.
|
|
- **Betroffen:** `Unit/BusinessPlan/TreeCalcBotOptimizedTest`.
|
|
- **Fix (mittel, reine Teständerung):** Konstruktor-Aufrufe im Test an die aktuelle
|
|
Signatur anpassen.
|
|
|
|
### Rest
|
|
Einzelne Folgefehler/Sonderfälle: `Feature/ExampleTest`,
|
|
`Feature/FrenchLocalizationTest`, `Feature/AboOneTimeWindowTest`,
|
|
`Feature/Incentive/IncentiveTeaserPageTest`.
|
|
|
|
## Empfehlung
|
|
|
|
Eigenständige Aufräum-Aufgabe in separatem Branch, **nicht** in den Payment-Branch
|
|
mischen. Sinnvolle Reihenfolge nach Risiko/Nutzen: **1 → 4 → 3 → 2**
|
|
(Ursache 2 zuletzt, da Architekturentscheidung zur Test-DB nötig).
|