Compare commits
2
Commits
v0.6.0
...
d1b9dfe535
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1b9dfe535 | ||
|
|
ebea3786b1 |
@@ -0,0 +1,78 @@
|
|||||||
|
# Prueft jeden Push und jeden Pull Request.
|
||||||
|
#
|
||||||
|
# Die Datei liegt unter .gitea/workflows und wird von Gitea Actions gelesen.
|
||||||
|
# Die Syntax ist mit GitHub Actions kompatibel – wer das Repo dorthin
|
||||||
|
# spiegelt, kopiert sie nach .github/workflows.
|
||||||
|
#
|
||||||
|
# Voraussetzung: In der Gitea-Instanz muessen Actions aktiviert sein
|
||||||
|
# (app.ini: [actions] ENABLED = true) und mindestens ein Runner registriert.
|
||||||
|
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pruefen:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:17-alpine
|
||||||
|
env:
|
||||||
|
POSTGRES_USER: nebula
|
||||||
|
POSTGRES_PASSWORD: nebula
|
||||||
|
# Der Name muss "test" enthalten – global-setup.ts leert die
|
||||||
|
# Datenbank und weigert sich bei allem anderen.
|
||||||
|
POSTGRES_DB: nebula_e2e_test
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
options: >-
|
||||||
|
--health-cmd "pg_isready -U nebula"
|
||||||
|
--health-interval 5s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 20
|
||||||
|
|
||||||
|
env:
|
||||||
|
DATABASE_URL: postgresql://nebula:nebula@localhost:5432/nebula_e2e_test?schema=public
|
||||||
|
E2E_DATABASE_URL: postgresql://nebula:nebula@localhost:5432/nebula_e2e_test?schema=public
|
||||||
|
# Nur fuer den Lauf – keine echten Daten im Spiel.
|
||||||
|
APP_SECRET: ci-lauf-schluessel-nur-fuer-die-pipeline-0123456789
|
||||||
|
NEXT_TELEMETRY_DISABLED: "1"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Abhaengigkeiten
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Typen pruefen
|
||||||
|
run: npx tsc --noEmit
|
||||||
|
|
||||||
|
- name: Unit-Tests
|
||||||
|
run: npm test
|
||||||
|
|
||||||
|
- name: Browser fuer die Oberflaechentests
|
||||||
|
run: npx playwright install --with-deps chromium
|
||||||
|
|
||||||
|
# Baut zuerst und startet den Server dann selbst (siehe
|
||||||
|
# playwright.config.ts, webServer).
|
||||||
|
- name: Ende-zu-Ende-Tests
|
||||||
|
run: npm run test:e2e
|
||||||
|
|
||||||
|
- name: Bericht bei Fehlschlag sichern
|
||||||
|
if: failure()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: playwright-bericht
|
||||||
|
path: |
|
||||||
|
playwright-report/
|
||||||
|
test-results/
|
||||||
|
retention-days: 7
|
||||||
+38
-5
@@ -402,8 +402,10 @@ nicht verloren gehen. Indizes auf Status, Verbindung und Änderungsdatum.
|
|||||||
|
|
||||||
### 6.4 Tests
|
### 6.4 Tests
|
||||||
|
|
||||||
`npm test` führt die Unit-Tests aus — reine Logik, kein DOM, keine Datenbank, unter einer
|
Zwei Ebenen. `npm run test:all` führt beide aus.
|
||||||
Sekunde:
|
|
||||||
|
**`npm test` — Unit-Tests** (Vitest, 56 Stück, unter einer Sekunde, ohne DOM und ohne
|
||||||
|
Datenbank):
|
||||||
|
|
||||||
| Bereich | Was geprüft wird |
|
| Bereich | Was geprüft wird |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
@@ -411,11 +413,42 @@ Sekunde:
|
|||||||
| `git/parse` | URL-Zerlegung für https, SSH, verschachtelte GitLab-Gruppen und Oberflächenpfade; Provider-Erkennung; Bildung der Aktivitätskurve |
|
| `git/parse` | URL-Zerlegung für https, SSH, verschachtelte GitLab-Gruppen und Oberflächenpfade; Provider-Erkennung; Bildung der Aktivitätskurve |
|
||||||
| `security/ssrf` | Sperrlisten für Loopback, Link-Local, Metadaten-Endpunkt, CGNAT und Multicast; Formprüfung; die drei Umgebungsschalter |
|
| `security/ssrf` | Sperrlisten für Loopback, Link-Local, Metadaten-Endpunkt, CGNAT und Multicast; Formprüfung; die drei Umgebungsschalter |
|
||||||
| `auth/password` | scrypt-Rundlauf, unterschiedliches Salz, Ablageformat, Verhalten bei kaputten Hashes, Passwortregeln |
|
| `auth/password` | scrypt-Rundlauf, unterschiedliches Salz, Ablageformat, Verhalten bei kaputten Hashes, Passwortregeln |
|
||||||
|
| `tasks` | Berechnung des abgeleiteten Fortschritts, Spaltenreihenfolge |
|
||||||
|
|
||||||
Bewusst ohne Datenbank- und Browsertests: die brauchen Infrastruktur und gehören in eine
|
**`npm run test:e2e` — Ende-zu-Ende** (Playwright, 13 Stück, rund 20 Sekunden). Läuft
|
||||||
CI-Pipeline. Das steht in der [ROADMAP](ROADMAP.md).
|
gegen die gebaute Anwendung mit eigener Datenbank auf Port 3111 — also durch Middleware,
|
||||||
|
Authentifizierung, Validierung und Datenbank hindurch:
|
||||||
|
|
||||||
### 6.5 API
|
| Datei | Was geprüft wird |
|
||||||
|
| --- | --- |
|
||||||
|
| `e2e/api.spec.ts` | Einrichtung sperrt sich nach dem ersten Konto · kein Zugriff ohne Anmeldung · fremdes Origin und falscher Content-Type abgewiesen · SSRF geblockt · **Datentrennung zwischen zwei Konten** · Aufgaben-Reihenfolge, abgeleiteter Fortschritt und untergeschobene IDs · Export ohne Geheimnisse, Import je Strategie |
|
||||||
|
| `e2e/ui.spec.ts` | Anmelden · Projekt anlegen · Aufgaben anlegen und **per Ziehen verschieben** (inklusive Prüfung nach dem Neuladen) · Volltextsuche · Abmelden sperrt geschützte Seiten wieder |
|
||||||
|
|
||||||
|
Zwei Dinge sind bewusst so gebaut:
|
||||||
|
|
||||||
|
- **Die Testdatenbank kann nicht die echte sein.** `e2e/global-setup.ts` bricht ab, wenn
|
||||||
|
der Datenbankname nicht `test` enthält — vor dem `TRUNCATE`. Der teuerste denkbare
|
||||||
|
Fehler wäre eine Testreihe, die die Produktivdaten leert.
|
||||||
|
- **Playwright startet den Server selbst** (`webServer` in `playwright.config.ts`) mit
|
||||||
|
eigener `DATABASE_URL` und eigenem Port. Eine laufende Instanz auf 3000 stört nicht.
|
||||||
|
|
||||||
|
Einmalig vorbereiten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec nebula-db psql -U nebula -d postgres -c "CREATE DATABASE nebula_e2e_test"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.5 Fortlaufende Prüfung
|
||||||
|
|
||||||
|
`.gitea/workflows/ci.yml` prüft jeden Push und jeden Pull Request: Typen, Unit-Tests,
|
||||||
|
Bau und Ende-zu-Ende-Tests gegen einen frischen PostgreSQL-Dienst. Schlägt etwas fehl,
|
||||||
|
wird der Playwright-Bericht als Artefakt abgelegt.
|
||||||
|
|
||||||
|
Dafür müssen in der Gitea-Instanz Actions aktiviert sein (`app.ini`: `[actions] ENABLED
|
||||||
|
= true`) und ein Runner registriert. Die Syntax ist GitHub-kompatibel — für GitHub die
|
||||||
|
Datei nach `.github/workflows/` kopieren.
|
||||||
|
|
||||||
|
### 6.6 API
|
||||||
|
|
||||||
Zehn REST-Endpunkte für Projekte, Notizen, Verbindungen, Sync, Repo-Listen und Health.
|
Zehn REST-Endpunkte für Projekte, Notizen, Verbindungen, Sync, Repo-Listen und Health.
|
||||||
Alles, was die Oberfläche kann, ist damit auch scriptbar. Übersicht in der
|
Alles, was die Oberfläche kann, ist damit auch scriptbar. Übersicht in der
|
||||||
|
|||||||
@@ -301,6 +301,9 @@ nebula/
|
|||||||
| `npm test` | Unit-Tests (Vitest), unter einer Sekunde |
|
| `npm test` | Unit-Tests (Vitest), unter einer Sekunde |
|
||||||
| `npm run test:watch` | Tests im Beobachtungsmodus |
|
| `npm run test:watch` | Tests im Beobachtungsmodus |
|
||||||
| `npm run typecheck` | TypeScript prüfen |
|
| `npm run typecheck` | TypeScript prüfen |
|
||||||
|
| `npm test` | Unit-Tests (Vitest, ohne Datenbank) |
|
||||||
|
| `npm run test:e2e` | Ende-zu-Ende-Tests (Playwright, baut vorher) |
|
||||||
|
| `npm run test:all` | Beides nacheinander |
|
||||||
| `npm run docker:db` | Nur die Datenbank starten |
|
| `npm run docker:db` | Nur die Datenbank starten |
|
||||||
| `npm run docker:up` / `docker:down` | Kompletten Stack starten / stoppen |
|
| `npm run docker:up` / `docker:down` | Kompletten Stack starten / stoppen |
|
||||||
| `npm run docker:tools` | Adminer auf `http://localhost:8080` |
|
| `npm run docker:tools` | Adminer auf `http://localhost:8080` |
|
||||||
|
|||||||
+2
-14
@@ -11,20 +11,7 @@ Was bereits steht, listet [FEATURES.md](FEATURES.md).
|
|||||||
|
|
||||||
## 1 · Als Nächstes empfohlen
|
## 1 · Als Nächstes empfohlen
|
||||||
|
|
||||||
### 1.1 Tests ausbauen: Datenbank und Browser `L`
|
### 1.1 Benachrichtigungen `M`
|
||||||
|
|
||||||
Das Fundament steht — 51 Unit-Tests der reinen Logik laufen in unter einer
|
|
||||||
Sekunde. Was fehlt, ist die Schicht darüber:
|
|
||||||
|
|
||||||
- **Integrationstests** gegen eine Wegwerf-Datenbank: Datentrennung zwischen
|
|
||||||
Konten, Import-Strategien, Backoff des Abgleichs
|
|
||||||
- **Playwright** für die Wege durch die App: Einrichtung, Anmeldung, Kanban
|
|
||||||
- **CI-Pipeline** bei GitHub oder Gitea Actions
|
|
||||||
|
|
||||||
Ich prüfe bislang alles von Hand, inklusive Screenshots. Das trägt nicht
|
|
||||||
dauerhaft und macht jede weitere Änderung teurer als nötig.
|
|
||||||
|
|
||||||
### 1.2 Benachrichtigungen `M`
|
|
||||||
|
|
||||||
Bei Sync-Fehlern, roter CI, neuen Releases oder Projekten, die lange
|
Bei Sync-Fehlern, roter CI, neuen Releases oder Projekten, die lange
|
||||||
stillstehen. Kanäle: E-Mail (SMTP), ntfy, generischer Webhook. Zusammen mit
|
stillstehen. Kanäle: E-Mail (SMTP), ntfy, generischer Webhook. Zusammen mit
|
||||||
@@ -129,6 +116,7 @@ Damit klar ist, was **nicht** kommt und warum:
|
|||||||
| **v0.3.0** Markdown, Volltextsuche über Notizen, PR- und Issue-Listen, Testfundament | ✓ |
|
| **v0.3.0** Markdown, Volltextsuche über Notizen, PR- und Issue-Listen, Testfundament | ✓ |
|
||||||
| **v0.4.0** Kanban mit Drag & Drop, CI-Status je Branch, Commit-Aktivität | ✓ |
|
| **v0.4.0** Kanban mit Drag & Drop, CI-Status je Branch, Commit-Aktivität | ✓ |
|
||||||
| **v0.5.0** Aufgabenbrett je Projekt mit sortierbaren Spalten, Fortschritt aus Aufgaben | ✓ |
|
| **v0.5.0** Aufgabenbrett je Projekt mit sortierbaren Spalten, Fortschritt aus Aufgaben | ✓ |
|
||||||
|
| **v0.6.0** Ende-zu-Ende-Tests mit Playwright, CI-Pipeline für Gitea Actions | ✓ |
|
||||||
|
|
||||||
Zur Entscheidung beim Export: Git-Tokens gehen **nicht** mit. Die Verbindung wird nur
|
Zur Entscheidung beim Export: Git-Tokens gehen **nicht** mit. Die Verbindung wird nur
|
||||||
beschrieben, das Token ist nach dem Import neu zu hinterlegen. Snapshots bleiben
|
beschrieben, das Token ist nach dem Import neu zu hinterlegen. Snapshots bleiben
|
||||||
|
|||||||
@@ -108,6 +108,9 @@ function UserMenu({ user }: { user: SessionUser }) {
|
|||||||
className="flex items-center gap-2 rounded-xl border border-white/10 bg-white/4 py-1.5 pl-1.5 pr-3 text-sm text-slate-200 transition-colors hover:bg-white/8"
|
className="flex items-center gap-2 rounded-xl border border-white/10 bg-white/4 py-1.5 pl-1.5 pr-3 text-sm text-slate-200 transition-colors hover:bg-white/8"
|
||||||
aria-haspopup="menu"
|
aria-haspopup="menu"
|
||||||
aria-expanded={open}
|
aria-expanded={open}
|
||||||
|
// Auf schmalen Anzeigen bleibt nur das Kuerzel sichtbar – ohne
|
||||||
|
// Beschriftung liest ein Screenreader dann nur zwei Buchstaben vor.
|
||||||
|
aria-label={`Benutzermenue fuer ${label}`}
|
||||||
>
|
>
|
||||||
<span className="grid h-7 w-7 place-items-center rounded-lg bg-gradient-to-br from-violet-500/80 to-cyan-400/70 text-[11px] font-semibold text-white">
|
<span className="grid h-7 w-7 place-items-center rounded-lg bg-gradient-to-br from-violet-500/80 to-cyan-400/70 text-[11px] font-semibold text-white">
|
||||||
{initials}
|
{initials}
|
||||||
|
|||||||
Reference in New Issue
Block a user