# 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)
