Lightweight replacement for the upstream La Suite Numérique drive (Django/Celery/Next.js) built as a single Deno binary. Server (Deno + Hono): - S3 file operations via AWS SigV4 (no SDK) with pre-signed URLs - WOPI host for Collabora Online (CheckFileInfo, GetFile, PutFile, locks) - Ory Kratos session auth + CSRF protection - Ory Keto permission model (OPL namespaces, not yet wired to routes) - PostgreSQL metadata with recursive folder sizes - S3 backfill API for registering files uploaded outside the UI - OpenTelemetry tracing + metrics (opt-in via OTEL_ENABLED) Frontend (React 19 + Cunningham v4 + react-aria): - File browser with GridList, keyboard nav, multi-select - Collabora editor iframe (full-screen, form POST, postMessage) - Profile menu, waffle menu, drag-drop upload, asset type badges - La Suite integration service theming (runtime CSS) Testing (549 tests): - 235 server unit tests (Deno) — 90%+ coverage - 278 UI unit tests (Vitest) — 90%+ coverage - 11 E2E tests (Playwright) - 12 integration service tests (Playwright) - 13 WOPI integration tests (Playwright + Docker Compose + Collabora) MIT licensed.
6.1 KiB
Testing
Five test suites, 90%+ coverage on both layers, and a Docker Compose stack for full WOPI integration tests.
Overview
| Suite | Runner | Count | What it tests |
|---|---|---|---|
| Server unit tests | Deno | 93 | API handlers, S3 signing, WOPI tokens, locks, auth, CSRF, Keto, permissions, backfill |
| UI unit tests | Vitest | 278 | Components, pages, hooks, stores, API client |
| E2E tests | Playwright | 11 | Full browser flows against a running server |
| Integration service tests | Playwright | 12 | Theme tokens, CSS injection, waffle menu from production integration service |
| WOPI integration tests | Playwright | 13 | End-to-end Collabora editing via Docker Compose |
Server Unit Tests (Deno)
deno task test
Which runs:
deno test -A tests/server/
10 test files, one per server module:
| File | What it covers |
|---|---|
auth_test.ts |
Kratos session validation, cookie extraction, AAL2 handling, test mode |
csrf_test.ts |
HMAC double-submit token generation, verification, timing-safe comparison |
files_test.ts |
File CRUD handlers, presigned URL generation, sort/search/pagination |
s3_test.ts |
AWS SigV4 signing, canonical request building, presign URL generation |
keto_test.ts |
Keto HTTP client: check, write, delete, batch, list, expand |
permissions_test.ts |
Permission middleware, tuple lifecycle, filterByPermission |
backfill_test.ts |
Key parsing, folder chain creation, dry run, mimetype inference |
wopi_token_test.ts |
JWT generation, verification, expiry, payload validation |
wopi_lock_test.ts |
Lock acquire, release, refresh, conflict, unlock-and-relock, TTL |
wopi_discovery_test.ts |
Discovery XML parsing, caching, retry logic |
All use Deno's built-in test runner and assertions — no test framework dependency. WOPI lock tests inject an InMemoryLockStore so you don't need Valkey running.
Running with coverage
deno test -A --coverage tests/server/
deno coverage coverage/
UI Unit Tests (Vitest)
cd ui && npx vitest run
Or from the project root:
deno task test:ui
278 tests across 27 files:
| Area | Files | What they test |
|---|---|---|
| Components | FileBrowser, FileUpload, CollaboraEditor, ProfileMenu, FileActions, FilePreview, AssetTypeBadge, BreadcrumbNav, WaffleButton, ShareDialog |
Rendering, user interaction, keyboard navigation, aria attributes |
| Pages | Explorer, Recent, Favorites, Trash, Editor |
Route-level rendering, data loading, empty states |
| API | client, files, session, wopi |
Fetch mocking, error handling, request formatting |
| Stores | selection, upload |
Zustand state management, multi-select, upload queue |
| Hooks | useAssetType, usePreview, useThreeDPreview |
File type detection, preview capability determination |
| Layouts | AppLayout |
Header, sidebar, main content area rendering |
| Cunningham | useCunninghamTheme |
Theme integration, CSS variable injection |
| Root | App |
CunninghamProvider + Router mounting |
Running with coverage
cd ui && npx vitest run --coverage
E2E Tests (Playwright)
cd ui && npx playwright test e2e/driver.spec.ts
Or:
deno task test:e2e
Needs a running server with:
DRIVER_TEST_MODE=1(bypasses Kratos auth, injects a fake identity)- PostgreSQL with migrations applied
- SeaweedFS (
weed miniworks fine)
11 tests covering browser-level flows:
- File browser navigation
- Folder creation and navigation
- File upload (single and multi-part)
- File rename and move
- File deletion and restore from trash
- Sort and search
- Favorites toggle
- Download via presigned URL
Integration Service Tests (Playwright)
cd ui && INTEGRATION_URL=https://integration.sunbeam.pt npx playwright test e2e/integration-service.spec.ts
12 tests validating La Suite integration service theming:
- CSS variable injection from the integration service
- Theme token validation
- Waffle menu rendering
- Dark mode support
- Custom font loading
- Runtime theme switching
These hit the production integration service at integration.sunbeam.pt. No local Drive server needed — they test the theme integration layer in isolation.
WOPI Integration Tests (Playwright)
# Start the test stack
docker compose up -d
# Wait for services to be healthy (Collabora takes ~30s)
docker compose ps
# Start the server pointed at compose services
DATABASE_URL="postgres://driver:driver@localhost:5433/driver_db" \
SEAWEEDFS_S3_URL="http://localhost:8334" \
COLLABORA_URL="http://localhost:9980" \
PUBLIC_URL="http://host.docker.internal:3200" \
PORT=3200 \
DRIVER_TEST_MODE=1 \
deno run -A main.ts
# Run the tests
cd ui && DRIVER_URL=http://localhost:3200 npx playwright test e2e/wopi.spec.ts
13 tests covering the full WOPI editing flow:
- Token generation for various file types
- Editor URL construction with WOPISrc
- Collabora iframe loading
- CheckFileInfo response validation
- GetFile content retrieval
- PutFile content writing
- Lock/unlock lifecycle
- Lock conflict handling
- Token expiry and refresh
- Concurrent editing detection
The Docker Compose Stack
compose.yaml spins up three services:
| Service | Image | Port | Purpose |
|---|---|---|---|
postgres |
postgres:16-alpine |
5433 | Test database (5433 to avoid conflict with host PostgreSQL) |
seaweedfs |
chrislusf/seaweedfs:latest |
8334 | S3 storage (8334 to avoid conflict with host weed mini) |
collabora |
collabora/code:latest |
9980 | Document editor |
Drive runs on the host (not in Docker) so Playwright can reach it. Collabora needs to call back to the host for WOPI — aliasgroup1 points to host.docker.internal:3200.
Tear down after testing:
docker compose down -v
Running Everything
# All automated tests (server + UI + E2E)
deno task test:all
Which runs:
deno task test && deno task test:ui && deno task test:e2e
WOPI integration tests aren't in test:all — they need the Docker Compose stack. Run them separately when touching WOPI code.