Some checks failed
Build & Sign Wraith / Build Windows + Sign (push) Has been cancelled
Go + Wails v3 + Vue 3 + SQLite + FreeRDP3 (purego) 183 tests, 76 source files, 9,910 lines of code Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
109 lines
4.6 KiB
Markdown
109 lines
4.6 KiB
Markdown
# Wraith Remote — Test Suite Build-Out Spec
|
|
|
|
**Date:** 2026-03-14
|
|
**Scope:** Level B — Full service layer coverage (~80-100 tests)
|
|
**Status:** Pinned — awaiting green light to execute
|
|
|
|
---
|
|
|
|
## Backend (Jest)
|
|
|
|
Jest is already configured in `backend/package.json`. Zero spec files exist today.
|
|
|
|
### Infrastructure
|
|
|
|
- Tests co-located with source: `*.spec.ts` next to `*.ts`
|
|
- Shared mock factories in `backend/src/__mocks__/` for Prisma, JwtService, EncryptionService
|
|
- `beforeEach` resets all mocks to prevent test bleed
|
|
|
|
### Test Files
|
|
|
|
| File | Tests | Priority |
|
|
|------|-------|----------|
|
|
| `auth.service.spec.ts` | Login (valid, invalid, non-existent user timing), bcrypt→argon2 migration, TOTP setup/verify/disable, TOTP secret encryption/decryption, password hashing, profile update, admin CRUD | ~20 |
|
|
| `encryption.service.spec.ts` | v2 encrypt/decrypt round-trip, v1 backwards compat decrypt, v1→v2 upgrade, isV1 detection, invalid version handling, key derivation warmup | ~8 |
|
|
| `credentials.service.spec.ts` | findAll excludes encryptedValue, findOne with ownership check, create with encryption, update with password change, remove, decryptForConnection (password, SSH key, orphaned key, no auth) | ~10 |
|
|
| `ssh-keys.service.spec.ts` | Create with encryption, findAll (no private key leak), findOne ownership, update passphrase, remove, key type detection, fingerprint generation | ~8 |
|
|
| `jwt-auth.guard.spec.ts` | Passes valid JWT, rejects missing/expired/invalid JWT | ~3 |
|
|
| `admin.guard.spec.ts` | Allows admin role, blocks non-admin, blocks missing user | ~3 |
|
|
| `ws-auth.guard.spec.ts` | Cookie-based auth, WS ticket auth (valid, expired, reused), legacy URL token fallback, no token rejection | ~6 |
|
|
| `auth.controller.spec.ts` | Login sets cookie, logout clears cookie, ws-ticket issuance and consumption, TOTP endpoints wired correctly | ~8 |
|
|
|
|
**Backend total: ~66 tests**
|
|
|
|
### Mocking Strategy
|
|
|
|
- **PrismaService:** Jest manual mock returning controlled data per test
|
|
- **EncryptionService:** Mock encrypt returns `v2:mock:...`, mock decrypt returns plaintext
|
|
- **JwtService:** Mock sign returns `mock-jwt-token`, mock verify returns payload
|
|
- **Argon2:** Real library (fast enough for unit tests, tests actual hashing behavior)
|
|
- **bcrypt:** Real library (needed to test migration path)
|
|
|
|
---
|
|
|
|
## Frontend (Vitest)
|
|
|
|
No test infrastructure exists today. Needs full setup.
|
|
|
|
### Infrastructure
|
|
|
|
- Install: `vitest`, `@vue/test-utils`, `@pinia/testing`, `happy-dom`
|
|
- Config: `frontend/vitest.config.ts` with happy-dom environment
|
|
- Global mock for `$fetch` (Nuxt auto-import) via setup file
|
|
- Global mock for `navigateTo` (Nuxt auto-import)
|
|
|
|
### Test Files
|
|
|
|
| File | Tests | Priority |
|
|
|------|-------|----------|
|
|
| `stores/auth.store.spec.ts` | Login success (stores user, no token in state), login TOTP flow, logout clears state + calls API, fetchProfile success/failure, getWsTicket, isAuthenticated/isAdmin getters | ~10 |
|
|
| `stores/connection.store.spec.ts` | fetchHosts, fetchTree, createHost, updateHost, deleteHost, group CRUD, no Authorization headers in requests | ~8 |
|
|
| `composables/useVault.spec.ts` | listKeys, importKey, deleteKey, listCredentials, createCredential, updateCredential, deleteCredential — all without Authorization headers | ~7 |
|
|
| `middleware/admin.spec.ts` | Redirects non-admin to /, allows admin through | ~3 |
|
|
| `plugins/auth.client.spec.ts` | Calls fetchProfile on init when user is null, skips when user exists | ~2 |
|
|
|
|
**Frontend total: ~30 tests**
|
|
|
|
---
|
|
|
|
## NPM Scripts
|
|
|
|
```json
|
|
// backend/package.json
|
|
"test": "jest",
|
|
"test:watch": "jest --watch",
|
|
"test:cov": "jest --coverage"
|
|
|
|
// frontend/package.json
|
|
"test": "vitest run",
|
|
"test:watch": "vitest",
|
|
"test:cov": "vitest run --coverage"
|
|
```
|
|
|
|
---
|
|
|
|
## Pre-commit Hook (Husky)
|
|
|
|
- Install `husky` + `lint-staged` at repo root
|
|
- Pre-commit runs: backend Jest (changed files) + frontend Vitest (changed files)
|
|
- Fast feedback — only tests related to changed files run on commit
|
|
|
|
---
|
|
|
|
## Execution Plan
|
|
|
|
1. **Agent 1:** Backend test infra (mock factories) + auth service tests + auth controller tests + guard tests (~37 tests)
|
|
2. **Agent 2:** Backend vault tests — encryption, credentials, SSH keys (~26 tests)
|
|
3. **Agent 3:** Frontend test infra (Vitest setup) + store tests + middleware + plugin tests (~30 tests)
|
|
4. **XO (me):** Wire npm scripts, verify all pass, add Husky pre-commit hook, final integration check
|
|
|
|
---
|
|
|
|
## Future (Level C — when ready)
|
|
|
|
- Component tests with Vue Test Utils (render + interaction)
|
|
- Integration tests against a real test PostgreSQL (Docker test container)
|
|
- Gateway tests (WebSocket mocking for terminal, SFTP, RDP)
|
|
- E2E with Playwright
|
|
- CI pipeline (Gitea Actions)
|