Backend (Go): - Expanded integration_test.go: health, auth middleware (expired/invalid/wrong-secret JWT), tenant CRUD, case CRUD (create/list/get/update/delete + filters + validation), deadline CRUD (create/list/update/complete/delete), appointment CRUD, dashboard (verifies all sections), deadline calculator (valid/invalid/unknown type), proceeding types & rules, document endpoints, AI extraction (no-key path), and full critical path E2E (auth -> case -> deadline -> appointment -> dashboard -> complete) - New handler unit tests: case (10), appointment (11), dashboard (1), calculate (5), document (10), AI (4) — all testing validation, auth guards, and error paths without DB - Total: ~80 backend tests (unit + integration) Frontend (TypeScript/Vitest): - Installed vitest 2.x, @testing-library/react, @testing-library/jest-dom, jsdom 24, msw - vitest.config.ts with jsdom env, esbuild JSX automatic, path aliases - API client tests (13): URL construction, no double /api/, auth header, tenant header, POST/PUT/PATCH/DELETE methods, error handling, 204 responses - DeadlineTrafficLights tests (5): renders cards, correct counts, zero state, onFilter callback - CaseOverviewGrid tests (4): renders categories, counts, header, zero state - LoginPage tests (8): form rendering, mode toggle, password login, redirect, error display, magic link, registration link - Total: 30 frontend tests Makefile: test-frontend target now runs vitest instead of placeholder echo.
167 lines
3.9 KiB
Go
167 lines
3.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"mgit.msbls.de/m/KanzlAI-mGMT/internal/auth"
|
|
)
|
|
|
|
func TestDocumentListByCase_NoTenant(t *testing.T) {
|
|
h := &DocumentHandler{}
|
|
r := httptest.NewRequest("GET", "/api/cases/"+uuid.New().String()+"/documents", nil)
|
|
r.SetPathValue("id", uuid.New().String())
|
|
w := httptest.NewRecorder()
|
|
|
|
h.ListByCase(w, r)
|
|
|
|
if w.Code != http.StatusForbidden {
|
|
t.Errorf("expected 403, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDocumentListByCase_InvalidCaseID(t *testing.T) {
|
|
h := &DocumentHandler{}
|
|
r := httptest.NewRequest("GET", "/api/cases/bad-id/documents", nil)
|
|
r.SetPathValue("id", "bad-id")
|
|
ctx := auth.ContextWithTenantID(
|
|
auth.ContextWithUserID(r.Context(), uuid.New()),
|
|
uuid.New(),
|
|
)
|
|
r = r.WithContext(ctx)
|
|
w := httptest.NewRecorder()
|
|
|
|
h.ListByCase(w, r)
|
|
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Errorf("expected 400, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDocumentUpload_NoTenant(t *testing.T) {
|
|
h := &DocumentHandler{}
|
|
r := httptest.NewRequest("POST", "/api/cases/"+uuid.New().String()+"/documents", nil)
|
|
r.SetPathValue("id", uuid.New().String())
|
|
w := httptest.NewRecorder()
|
|
|
|
h.Upload(w, r)
|
|
|
|
if w.Code != http.StatusForbidden {
|
|
t.Errorf("expected 403, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDocumentUpload_InvalidCaseID(t *testing.T) {
|
|
h := &DocumentHandler{}
|
|
r := httptest.NewRequest("POST", "/api/cases/bad-id/documents", nil)
|
|
r.SetPathValue("id", "bad-id")
|
|
ctx := auth.ContextWithTenantID(
|
|
auth.ContextWithUserID(r.Context(), uuid.New()),
|
|
uuid.New(),
|
|
)
|
|
r = r.WithContext(ctx)
|
|
w := httptest.NewRecorder()
|
|
|
|
h.Upload(w, r)
|
|
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Errorf("expected 400, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDocumentDownload_NoTenant(t *testing.T) {
|
|
h := &DocumentHandler{}
|
|
r := httptest.NewRequest("GET", "/api/documents/"+uuid.New().String(), nil)
|
|
r.SetPathValue("docId", uuid.New().String())
|
|
w := httptest.NewRecorder()
|
|
|
|
h.Download(w, r)
|
|
|
|
if w.Code != http.StatusForbidden {
|
|
t.Errorf("expected 403, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDocumentDownload_InvalidID(t *testing.T) {
|
|
h := &DocumentHandler{}
|
|
r := httptest.NewRequest("GET", "/api/documents/bad-id", nil)
|
|
r.SetPathValue("docId", "bad-id")
|
|
ctx := auth.ContextWithTenantID(
|
|
auth.ContextWithUserID(r.Context(), uuid.New()),
|
|
uuid.New(),
|
|
)
|
|
r = r.WithContext(ctx)
|
|
w := httptest.NewRecorder()
|
|
|
|
h.Download(w, r)
|
|
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Errorf("expected 400, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDocumentGetMeta_NoTenant(t *testing.T) {
|
|
h := &DocumentHandler{}
|
|
r := httptest.NewRequest("GET", "/api/documents/"+uuid.New().String()+"/meta", nil)
|
|
r.SetPathValue("docId", uuid.New().String())
|
|
w := httptest.NewRecorder()
|
|
|
|
h.GetMeta(w, r)
|
|
|
|
if w.Code != http.StatusForbidden {
|
|
t.Errorf("expected 403, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDocumentGetMeta_InvalidID(t *testing.T) {
|
|
h := &DocumentHandler{}
|
|
r := httptest.NewRequest("GET", "/api/documents/bad-id/meta", nil)
|
|
r.SetPathValue("docId", "bad-id")
|
|
ctx := auth.ContextWithTenantID(
|
|
auth.ContextWithUserID(r.Context(), uuid.New()),
|
|
uuid.New(),
|
|
)
|
|
r = r.WithContext(ctx)
|
|
w := httptest.NewRecorder()
|
|
|
|
h.GetMeta(w, r)
|
|
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Errorf("expected 400, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDocumentDelete_NoTenant(t *testing.T) {
|
|
h := &DocumentHandler{}
|
|
r := httptest.NewRequest("DELETE", "/api/documents/"+uuid.New().String(), nil)
|
|
r.SetPathValue("docId", uuid.New().String())
|
|
w := httptest.NewRecorder()
|
|
|
|
h.Delete(w, r)
|
|
|
|
if w.Code != http.StatusForbidden {
|
|
t.Errorf("expected 403, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDocumentDelete_InvalidID(t *testing.T) {
|
|
h := &DocumentHandler{}
|
|
r := httptest.NewRequest("DELETE", "/api/documents/bad-id", nil)
|
|
r.SetPathValue("docId", "bad-id")
|
|
ctx := auth.ContextWithTenantID(
|
|
auth.ContextWithUserID(r.Context(), uuid.New()),
|
|
uuid.New(),
|
|
)
|
|
r = r.WithContext(ctx)
|
|
w := httptest.NewRecorder()
|
|
|
|
h.Delete(w, r)
|
|
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Errorf("expected 400, got %d", w.Code)
|
|
}
|
|
}
|