52 lines
3.5 KiB
Markdown
52 lines
3.5 KiB
Markdown
---
|
|
name: project_test_infra
|
|
description: Test-Coverage-Stand + wie man Test-Targets für bisher test-lose Projekte aufsetzt
|
|
metadata:
|
|
node_type: memory
|
|
type: project
|
|
originSessionId: c4e04d11-9b40-4c6a-9333-ce3bbf949ba2
|
|
---
|
|
|
|
**Stand 2026-06-03 (Branch development): 8 Test-Projekte, 232 Tests grün.**
|
|
`nx run-many -t test`: plato-customer-be (74), frontend-common (71), customer-fe (30),
|
|
plato-customer-fe (25), shared (13), command-be (8), customer-be (6), ui-common (5).
|
|
|
|
**Bug-Jagd (3 parallele Review-Agenten, von mir am Code gegengeprüft) → 7 echte Bugs gefixt:**
|
|
- `b8e3355` xlImport2Customer: `customer_number='undefined'` (`String(x)??''` greift nie).
|
|
- `f0c4e48` outbox.peek: Command-Verlust, wenn Crash zwischen Outbox-Remove und Inflight-Write
|
|
(Reihenfolge gedreht: erst Inflight, recoverInflight dedupt per id).
|
|
- `7dd3dc0` dedupeByCustomerNumber: doppelte Importnummer lautlos verloren (jetzt erster gewinnt + warn).
|
|
- `fc9cc22` setSort (Vergleich nach Zuweisung), NumberInput (v-model.number), setEditing (Karten-Wechsel).
|
|
- `042b9b3` connectivity: Heartbeat re-armte trotz stop() (Race), Generation-Token.
|
|
- `012a243` reconcile gehärtet: Form per `Array.isArray` statt `.length` (leeres Array galt als
|
|
Einzelobjekt; null/undefined Payload/forcedState crashte nicht mehr), delete.list rollt ganze
|
|
Liste zurück, reconcile-Fehler wird über den Notifier gemeldet statt still geloggt.
|
|
Verworfen als kein-Live-Bug: QUEUED→badBox (by design), selectedId-Highlight (visuell).
|
|
**NICHT als Bug melden:** `CustomerCoreService.deleteAll` löscht bewusst die GLOBALE customer-Tabelle
|
|
ohne Länderfilter — reine Test-/Reset-Funktion, fliegt vor Prod raus (Marcus, 2026-06-03).
|
|
DEV-SAP-Mock (`.get()` auf Kreuzprodukt-Join wählt willkürlichen Kontakt/Adresse): **bewusst nicht
|
|
gefixt** — SAP-OData-Schema trägt eh nur EINEN Partner/Adresse, und eine Query-Änderung würde die
|
|
26 gepinnten E2E-Fixtures riskieren.
|
|
|
|
**Diese Session per TDD abgedeckt** (vorher Lücken): Sync-Kern (outbox, background-sync,
|
|
backoff, **reconcile**=Offline-first-Konvergenz inkl. Rollback, **connectivity**=Heartbeat),
|
|
customer-fe Store + FE-`sap-adapter` (live SAP-Parsing), und die SW-Routing-Policy.
|
|
|
|
**Muster: Test-Target für ein Projekt ohne Tests nachrüsten** (war bei customer-fe und der
|
|
App plato-customer-fe nötig — `nx run-many` ließ sie sonst aus):
|
|
- **Lib** (z. B. customer-fe): `test`-Block in die vorhandene `vite.config.ts`
|
|
(`{ watch:false, globals:true, environment:'node', include:['src/**/*.{test,spec}.{ts,tsx}'], passWithNoTests:true }`)
|
|
+ `"test": { "executor": "@nx/vite:test" }` ins `project.json`.
|
|
- **App mit VitePWA/vue** (plato-customer-fe): NICHT die Haupt-`vite.config.ts` nehmen (PWA/vue-
|
|
Plugins stören den Testlauf). Eigene `vitest.config.ts` ohne diese Plugins (nur `nxViteTsPaths()`),
|
|
und im Test-Target `"options": { "configFile": "apps/plato-customer-fe/vitest.config.ts" }`.
|
|
- jsdom je Datei via `// @vitest-environment jsdom` (z. B. DOMParser im sap-adapter, window/fetch
|
|
in connectivity). Cross-Lib-Wertimporte (`@plato/...`) im Vitest-Modus mocken, sonst lädt das Modul nicht.
|
|
|
|
**SW-Login-Loop festgenagelt:** Routing-Regeln aus `sw.ts` in pures `sw-routing.ts` ausgelagert
|
|
(`isNetworkOnly`/`isOidcCallback`/`NAV_DENYLIST`) und getestet. Siehe [[project_pwa_sw_auth_bypass]].
|
|
|
|
**Test-lose Projekte:** alle relevanten haben jetzt ein Test-Target. `libs/shared` per eigener
|
|
`vitest.config.ts` + `configFile`-Option (gleiches Muster wie die App). Keine bewusst offene
|
|
Coverage-Lücke mehr in den verzweigten/kritischen Pfaden.
|