erp-core/docs/06-test-plans/TEST-PLAN-MGN-001-fundamentos.md

1013 lines
27 KiB
Markdown

# TEST PLAN - MGN-001: Fundamentos
**Módulo:** MGN-001 - Fundamentos
**Sprint:** Sprint 1-5 (Semanas 1-10)
**Story Points:** 68 SP
**User Stories:** 16 US
**Fecha:** 2025-11-24
**QA Owner:** TBD
**Estado:** Draft
---
## 1. RESUMEN DEL MÓDULO
### 1.1 Descripción
El módulo MGN-001 Fundamentos es la base crítica del ERP Genérico. Provee los servicios core de autenticación, autorización, gestión de usuarios, roles, permisos y multi-tenancy con aislamiento a nivel de schema.
Este es el módulo más crítico (P0) ya que todos los demás módulos dependen de él. Sin autenticación funcional, el sistema no puede operar.
### 1.2 Funcionalidades Principales
1. **Autenticación:** Login con email/contraseña, JWT tokens, refresh tokens, logout
2. **Autorización:** RBAC (Role-Based Access Control) con permisos granulares por modelo
3. **Gestión de Usuarios:** CRUD usuarios, perfiles, cambio de contraseña, reset password
4. **Multi-Tenancy:** Schema-level isolation, tenant context switching
5. **Gestión de Sesiones:** Sesiones activas, logout, expiración automática
6. **Row Level Security:** RLS policies en PostgreSQL, field-level security
7. **Registro de Usuarios:** Signup/auto-registro con validación de email
8. **Gestión de Roles:** CRUD roles, asignación de permisos CRUD por modelo
### 1.3 Dependencias
**Módulos requeridos:** Ninguno (es el primer módulo)
**Datos maestros necesarios:**
- Al menos 1 tenant seed con subdomain configurado
- Al menos 1 usuario administrador seed
- Roles base: admin, user, viewer
- Permisos base definidos en código
**Servicios externos:**
- PostgreSQL 16 con extensión pgcrypto
- Redis (para session storage y rate limiting)
- SMTP server (para reset password emails)
---
## 2. ALCANCE DEL TESTING
### 2.1 En Alcance
**Funcionalidades a testear:**
- ✅ Login con email y contraseña (happy path + error paths)
- ✅ Refresh token para renovar JWT
- ✅ Logout y cierre de sesión
- ✅ CRUD de roles y permisos
- ✅ Validación de permisos en runtime (guards/middleware)
- ✅ CRUD de usuarios
- ✅ Gestión de perfil propio y cambio de contraseña
- ✅ Reset de contraseña (forgot password flow)
- ✅ Signup/auto-registro de usuarios
- ✅ Creación y configuración de tenants
- ✅ Schema-level isolation (tenant no ve datos de otro tenant)
- ✅ Tenant context switching (multi-empresa)
- ✅ Gestión de sesiones activas
- ✅ RLS policies (Row Level Security)
- ✅ Field-level security (campos sensibles)
- ✅ Bloqueo de cuenta por intentos fallidos
- ✅ Rate limiting de endpoints de auth
**Testing no funcional:**
- ✅ Performance de login (<300ms p95)
- Security (OWASP Top 10, JWT validation, bcrypt)
- Tenant isolation (crítico)
- Concurrencia (múltiples logins simultáneos)
- Rate limiting (protección contra brute force)
### 2.2 Fuera de Alcance
**Exclusiones explícitas:**
- OAuth2/SAML (Fase 2 - no MVP)
- 2FA/MFA (Fase 2 - no MVP)
- CAPTCHA (Fase 2)
- Biometric authentication
- Login con redes sociales (Google, Facebook)
- LDAP/Active Directory integration
### 2.3 Assumptions
- PostgreSQL 16 está instalado y configurado correctamente
- Redis está disponible para session storage
- SMTP server está configurado para envío de emails
- Subdomain routing funciona correctamente (nginx/traefik)
- Environment variables están configuradas (JWT_SECRET, DATABASE_URL, etc.)
---
## 3. ESTRATEGIA DE TESTING
### 3.1 Tipos de Tests
#### Unit Tests
**Coverage objetivo:** >80% por archivo
**Herramientas:**
- Jest (backend)
- Vitest (frontend)
**Total estimado:** 96 unit tests
**Backend (60 tests):**
- AuthService: 20 tests
- login method (8 tests: success, invalid email, wrong password, user inactive, tenant inactive, locked account, rate limit, tenant isolation)
- validateUser method (5 tests)
- generateTokens method (3 tests)
- refreshToken method (4 tests)
- UsersService: 15 tests
- create, update, delete, findByEmail, changePassword
- RolesService: 10 tests
- CRUD roles, assign permissions
- PermissionsGuard: 8 tests
- @RequirePermissions decorator validation
- Utils/Helpers: 7 tests
- Password hashing, JWT signing/verification
**Frontend (36 tests):**
- LoginForm component: 8 tests
- Render form, submit with valid data, show errors, loading state
- useAuthStore (Zustand): 6 tests
- setUser, setTokens, logout, persist to localStorage
- authApi client: 8 tests
- login, refresh, logout API calls
- UserList component: 6 tests
- RoleList component: 6 tests
- ProtectedRoute component: 2 tests
#### Integration Tests
**Coverage:** Todos los endpoints API + componentes con API
**Herramientas:**
- Supertest (API testing)
- React Testing Library (component + API)
- TestContainers (PostgreSQL real instance)
**Total estimado:** 48 integration tests
**Test suites:**
1. **Auth API (16 tests):**
- POST /api/v1/auth/login (6 tests)
- POST /api/v1/auth/refresh (3 tests)
- POST /api/v1/auth/logout (2 tests)
- POST /api/v1/auth/forgot-password (3 tests)
- POST /api/v1/auth/reset-password (2 tests)
2. **Users API (12 tests):**
- GET /api/v1/users (2 tests)
- POST /api/v1/users (3 tests)
- PUT /api/v1/users/:id (3 tests)
- DELETE /api/v1/users/:id (2 tests)
- PATCH /api/v1/users/me/password (2 tests)
3. **Roles API (8 tests):**
- GET /api/v1/roles (2 tests)
- POST /api/v1/roles (3 tests)
- PUT /api/v1/roles/:id (2 tests)
- DELETE /api/v1/roles/:id (1 test)
4. **Tenants API (6 tests):**
- POST /api/v1/tenants (3 tests)
- PUT /api/v1/tenants/:id (2 tests)
- GET /api/v1/tenants/me (1 test)
5. **Database + RLS (6 tests):**
- Tenant isolation queries
- RLS policies enforcement
- Field-level security
#### E2E Tests
**Coverage:** Flujos críticos de usuario
**Herramienta:** Playwright
**Total estimado:** 16 E2E tests
**User journeys:**
1. **Authentication Flow (6 tests):**
- Login exitoso y redirect a dashboard
- Login con credenciales inválidas
- Logout y redirect a login page
- Reset password flow completo
- Cuenta bloqueada por intentos fallidos
- Tenant isolation (user de tenant A no accede a tenant B)
2. **User Management Flow (4 tests):**
- Admin crea usuario, asigna rol, usuario puede login
- Usuario cambia su propia contraseña
- Admin desactiva usuario, usuario no puede login
- Admin elimina usuario
3. **Role Management Flow (3 tests):**
- Admin crea rol con permisos, asigna a usuario, usuario accede solo a recursos permitidos
- Admin revoca permiso, usuario pierde acceso
- Usuario sin permiso recibe 403
4. **Multi-Tenancy Flow (3 tests):**
- Usuario accede a tenant A, crea registro, cambia a tenant B, no ve registro de tenant A
- Signup crea usuario en tenant correcto según subdomain
- Tenant context switch funciona correctamente
---
## 4. TEST CASES
### 4.1 Casos de Prueba Funcionales
#### TC-MGN-001-001: Login Exitoso con Credenciales Válidas
**US:** US-MGN-001-001-001
**Prioridad:** P0
**Tipo:** Functional
**Nivel:** E2E
**Precondiciones:**
- Tenant "acme-corp" existe y está activo
- Usuario "admin@acme.com" existe con password "Admin123!" y está activo
**Pasos:**
1. Navegar a https://acme-corp.erp.local/login
2. Ingresar email: "admin@acme.com"
3. Ingresar password: "Admin123!"
4. Click en botón "Iniciar Sesión"
**Resultado Esperado:**
- JWT token es retornado y almacenado en localStorage
- Usuario es redirigido a /dashboard
- failed_login_attempts se resetea a 0
- Registro se crea en auth.login_history con success=true
**Criterios de Aceptación Validados:**
- AC-001: Usuario con credenciales válidas puede autenticarse
- AC-002: JWT token contiene user_id, tenant_id, roles, permissions
---
#### TC-MGN-001-002: Login Fallido por Contraseña Incorrecta
**US:** US-MGN-001-001-001
**Prioridad:** P0
**Tipo:** Functional
**Nivel:** Integration
**Precondiciones:**
- Usuario "admin@acme.com" existe
**Pasos:**
1. POST /api/v1/auth/login con body: { email: "admin@acme.com", password: "WrongPassword" }
**Resultado Esperado:**
- Status code: 401 Unauthorized
- Error message: "Credenciales inválidas"
- failed_login_attempts incrementa en 1
- Registro en auth.login_history con success=false
**Criterios de Aceptación Validados:**
- AC-003: Sistema incrementa contador de intentos fallidos
---
#### TC-MGN-001-003: Cuenta Bloqueada por Intentos Fallidos
**US:** US-MGN-001-001-001
**Prioridad:** P0
**Tipo:** Functional
**Nivel:** Integration
**Precondiciones:**
- Usuario "admin@acme.com" tiene failed_login_attempts=5 y last_failed_login < 30 minutos
**Pasos:**
1. POST /api/v1/auth/login con credenciales correctas
**Resultado Esperado:**
- Status code: 429 Too Many Requests
- Error message: "Cuenta bloqueada temporalmente. Intente en X minutos"
- No valida contraseña (retorna inmediatamente)
**Criterios de Aceptación Validados:**
- AC-004: Sistema bloquea cuenta después de 5 intentos fallidos por 30 minutos
---
#### TC-MGN-001-004: Tenant Isolation (Usuario no Accede a Otro Tenant)
**US:** US-MGN-001-004-002
**Prioridad:** P0
**Tipo:** Security
**Nivel:** Integration
**Precondiciones:**
- Tenant A tiene usuario "user@tenant-a.com"
- Tenant B tiene 10 registros en tabla products
**Pasos:**
1. Login como "user@tenant-a.com" desde subdomain tenant-a
2. GET /api/v1/products (debería retornar productos de tenant A solamente)
3. Intentar GET /api/v1/products con header X-Tenant-ID: tenant-b
**Resultado Esperado:**
- GET /api/v1/products retorna solo productos de tenant A
- Intentar acceder con otro tenant_id resulta en 403 Forbidden o ignora el header
- Queries SQL automáticamente filtran por tenant_id
**Criterios de Aceptación Validados:**
- AC-005: Usuarios de diferentes tenants están completamente aislados
- AC-006: RLS policies previenen acceso cross-tenant
---
#### TC-MGN-001-005: Usuario Inactivo No Puede Login
**US:** US-MGN-001-001-001
**Prioridad:** P0
**Tipo:** Functional
**Nivel:** Integration
**Precondiciones:**
- Usuario "inactive@acme.com" tiene status='inactive'
**Pasos:**
1. POST /api/v1/auth/login con credenciales correctas de usuario inactivo
**Resultado Esperado:**
- Status code: 403 Forbidden
- Error message: "Cuenta inactiva. Contacte al administrador"
- No se genera JWT token
**Criterios de Aceptación Validados:**
- AC-007: Usuario inactivo no puede autenticarse
---
#### TC-MGN-001-006: Refresh Token Renueva JWT
**US:** US-MGN-001-001-002
**Prioridad:** P0
**Tipo:** Functional
**Nivel:** Integration
**Precondiciones:**
- Usuario autenticado con refresh token válido
**Pasos:**
1. POST /api/v1/auth/refresh con body: { refreshToken: "valid_refresh_token" }
**Resultado Esperado:**
- Status code: 200 OK
- Nuevo accessToken es retornado
- Nuevo refreshToken es retornado (rotation)
- Refresh token anterior es invalidado
**Criterios de Aceptación Validados:**
- AC-008: Refresh token permite renovar JWT sin re-autenticación
---
#### TC-MGN-001-007: Admin Crea Rol con Permisos
**US:** US-MGN-001-002-001
**Prioridad:** P0
**Tipo:** Functional
**Nivel:** E2E
**Precondiciones:**
- Usuario admin autenticado
**Pasos:**
1. Navegar a /roles
2. Click en "Crear Rol"
3. Ingresar nombre: "Vendedor"
4. Seleccionar permisos: products:read, sales:create, sales:read, sales:update
5. Click en "Guardar"
**Resultado Esperado:**
- Rol "Vendedor" se crea en auth.roles
- Permisos se guardan en auth.role_permissions
- Rol aparece en lista de roles
- Notificación de éxito se muestra
**Criterios de Aceptación Validados:**
- AC-009: Admin puede crear roles personalizados
- AC-010: Permisos CRUD se asignan por modelo
---
#### TC-MGN-001-008: Usuario Sin Permiso Recibe 403
**US:** US-MGN-001-002-003
**Prioridad:** P0
**Tipo:** Functional
**Nivel:** Integration
**Precondiciones:**
- Usuario "viewer@acme.com" tiene rol "Viewer" con solo permisos de lectura
**Pasos:**
1. Login como "viewer@acme.com"
2. POST /api/v1/products (intentar crear producto)
**Resultado Esperado:**
- Status code: 403 Forbidden
- Error message: "No tiene permiso para realizar esta acción"
- Producto no se crea
**Criterios de Aceptación Validados:**
- AC-011: Usuarios solo acceden a recursos según sus permisos
- AC-012: Guards validan permisos en runtime
---
#### TC-MGN-001-009: Reset Password Flow Completo
**US:** US-MGN-001-005-001
**Prioridad:** P0
**Tipo:** Functional
**Nivel:** E2E
**Precondiciones:**
- Usuario "user@acme.com" existe
- SMTP server configurado
**Pasos:**
1. Navegar a /login
2. Click en "¿Olvidaste tu contraseña?"
3. Ingresar email: "user@acme.com"
4. Click en "Enviar"
5. Abrir email recibido
6. Click en link de reset password
7. Ingresar nueva contraseña: "NewPass123!"
8. Confirmar contraseña: "NewPass123!"
9. Click en "Cambiar Contraseña"
10. Login con nueva contraseña
**Resultado Esperado:**
- Email se envía a user@acme.com con token de reset
- Link de reset es válido por 1 hora
- Password se actualiza en BD (hasheado)
- Login con nueva contraseña es exitoso
- Token de reset se invalida después de uso
**Criterios de Aceptación Validados:**
- AC-013: Usuario puede resetear contraseña olvidada vía email
- AC-014: Token de reset expira en 1 hora
- AC-015: Token solo puede usarse una vez
---
#### TC-MGN-001-010: Signup Crea Usuario en Tenant Correcto
**US:** US-MGN-001-006-001
**Prioridad:** P1
**Tipo:** Functional
**Nivel:** E2E
**Precondiciones:**
- Tenant "acme-corp" permite signup (allow_signup=true)
**Pasos:**
1. Navegar a https://acme-corp.erp.local/signup
2. Ingresar email: "newuser@example.com"
3. Ingresar password: "Secure123!"
4. Ingresar nombre: "Juan Pérez"
5. Click en "Registrarse"
**Resultado Esperado:**
- Usuario se crea en tenant "acme-corp"
- Email de verificación se envía
- Usuario puede login después de verificar email
- Usuario se crea con rol "User" por defecto
**Criterios de Aceptación Validados:**
- AC-016: Signup crea usuario en tenant correcto según subdomain
- AC-017: Email de verificación se envía
- AC-018: Usuario tiene rol "User" por defecto
---
### 4.2 Casos de Prueba No Funcionales
#### TC-MGN-001-PERF-001: Performance del Endpoint POST /auth/login
**Tipo:** Performance
**Herramienta:** k6
**Objetivo:** Response time <300ms (p95)
**Escenario:**
- 100 usuarios concurrentes
- 1000 login requests/min
- Duración: 5 minutos
- Mix: 90% credenciales válidas, 10% inválidas
**Script k6:**
```javascript
import http from 'k6/http';
import { check } from 'k6';
export let options = {
vus: 100,
duration: '5m',
thresholds: {
http_req_duration: ['p(95)<300'],
http_req_failed: ['rate<0.01'],
},
};
export default function () {
const payload = JSON.stringify({
email: 'admin@acme.com',
password: 'Admin123!',
});
const res = http.post('https://api.erp.local/v1/auth/login', payload, {
headers: { 'Content-Type': 'application/json' },
});
check(res, {
'status is 200': (r) => r.status === 200,
'has token': (r) => JSON.parse(r.body).accessToken !== undefined,
});
}
```
**Criterios de Éxito:**
- p50: <100ms
- p95: <300ms
- p99: <500ms
- Error rate: <1%
- Throughput: >1000 req/min
---
#### TC-MGN-001-SEC-001: JWT Token Security Validation
**Tipo:** Security
**Herramienta:** Manual + Jest
**Objetivo:** Validar seguridad de JWT tokens
**Test cases:**
1. JWT firmado con algoritmo seguro (RS256 o HS256)
2. JWT secret tiene mínimo 256 bits de entropía
3. JWT tiene claim exp (expiration) configurado
4. JWT no contiene información sensible (password, etc.)
5. JWT no puede ser alterado sin invalidar firma
6. Refresh token es diferente de access token
7. Refresh token se almacena hasheado en BD
8. Refresh token rotation implementado
**Resultado Esperado:**
- Todos los test cases pasan
- Security scan (Snyk, OWASP ZAP) no reporta vulnerabilidades críticas en auth
---
#### TC-MGN-001-SEC-002: Protection Against Brute Force Attacks
**Tipo:** Security
**Herramienta:** Manual + k6
**Objetivo:** Validar rate limiting y bloqueo de cuenta
**Test cases:**
1. Más de 10 login attempts en 1 minuto desde misma IP resulta en 429 (rate limit)
2. 5 failed login attempts bloquea cuenta por 30 minutos
3. CAPTCHA aparece después de 3 failed attempts (Fase 2)
4. Logs de failed attempts se registran para detección de ataques
**Resultado Esperado:**
- Rate limiting funciona correctamente
- Cuenta se bloquea después de 5 intentos
- Logs permiten identificar patrones de ataque
---
#### TC-MGN-001-SEC-003: RLS Policy Enforcement
**Tipo:** Security
**Herramienta:** Integration test + Manual DB queries
**Objetivo:** Validar que RLS policies previenen acceso cross-tenant
**Test cases:**
1. SELECT sin filtro tenant_id retorna solo datos del tenant actual
2. INSERT sin tenant_id falla o usa tenant_id del contexto
3. UPDATE de registro de otro tenant falla
4. DELETE de registro de otro tenant falla
5. RLS bypass solo funciona con service role
**Script SQL:**
```sql
-- Como usuario de tenant A
SET app.tenant_id = 'tenant-a';
SELECT * FROM products; -- Solo productos de tenant A
-- Intentar acceder a tenant B
SET app.tenant_id = 'tenant-b';
SELECT * FROM products; -- Debería fallar o retornar vacío
```
**Resultado Esperado:**
- RLS policies previenen acceso cross-tenant en 100% de casos
- Service role puede bypass RLS para migraciones/backups
- Performance de queries con RLS es aceptable (<10% overhead)
---
## 5. DATOS DE PRUEBA
### 5.1 Test Data Requirements
**Tenants (3):**
```json
{
"tenant-a": {
"subdomain": "tenant-a",
"name": "Acme Corp",
"status": "active",
"plan": "enterprise",
"allow_signup": true
},
"tenant-b": {
"subdomain": "tenant-b",
"name": "Beta Inc",
"status": "active",
"plan": "pro",
"allow_signup": false
},
"tenant-c": {
"subdomain": "tenant-c",
"name": "Gamma LLC",
"status": "inactive",
"plan": "trial",
"allow_signup": false
}
}
```
**Usuarios por Tenant (10):**
```json
{
"admin@tenant-a.com": {
"password": "Admin123!",
"role": "admin",
"status": "active",
"tenant_id": "tenant-a"
},
"contador@tenant-a.com": {
"password": "Contador123!",
"role": "accountant",
"status": "active",
"tenant_id": "tenant-a"
},
"vendedor@tenant-a.com": {
"password": "Vendedor123!",
"role": "sales",
"status": "active",
"tenant_id": "tenant-a"
},
"viewer@tenant-a.com": {
"password": "Viewer123!",
"role": "viewer",
"status": "active",
"tenant_id": "tenant-a"
},
"inactive@tenant-a.com": {
"password": "Inactive123!",
"role": "user",
"status": "inactive",
"tenant_id": "tenant-a"
}
}
```
**Roles Base (5):**
- admin: Todos los permisos
- accountant: Permisos de módulo financiero
- sales: Permisos de ventas, productos, clientes
- user: Permisos básicos de lectura
- viewer: Solo lectura, sin escritura
**Permisos (ejemplos):**
- users:create, users:read, users:update, users:delete
- roles:create, roles:read, roles:update, roles:delete
- products:create, products:read, products:update, products:delete
### 5.2 Data Setup
**Script de seed:**
```bash
npm run seed:test
```
**Contenido de seed script:**
```typescript
// test/seeds/auth.seed.ts
export async function seedAuthData(prisma: PrismaClient) {
// 1. Crear tenants
const tenants = await createTenants(prisma);
// 2. Crear roles
const roles = await createRoles(prisma, tenants);
// 3. Crear permisos
const permissions = await createPermissions(prisma);
// 4. Asignar permisos a roles
await assignPermissionsToRoles(prisma, roles, permissions);
// 5. Crear usuarios
await createUsers(prisma, tenants, roles);
console.log('✅ Auth test data seeded successfully');
}
```
---
## 6. AMBIENTE DE TESTING
### 6.1 Configuración
**Base de datos:** PostgreSQL 16 (test DB)
- Database: `erp_test`
- Schema: `auth`, `public`
- Extensions: `pgcrypto`, `uuid-ossp`
- RLS enabled en todas las tablas
**Backend:** NestJS
- Port: 3000
- Mode: test
- JWT_SECRET: test_secret_key_256bits
- DATABASE_URL: postgresql://test:test@localhost:5432/erp_test
**Frontend:** React + Vite
- Port: 5173
- API_URL: http://localhost:3000/api/v1
- Mode: test
**Redis:** Session storage
- Port: 6379
- DB: 1 (test database)
**SMTP:** Mailhog (test email server)
- Port: 1025 (SMTP)
- Port: 8025 (Web UI)
### 6.2 URLs
- **API:** http://localhost:3000/api/v1
- **Frontend:** http://localhost:5173
- **Swagger:** http://localhost:3000/api/docs
- **Mailhog UI:** http://localhost:8025
### 6.3 Environment Variables
```env
# Database
DATABASE_URL=postgresql://test:test@localhost:5432/erp_test
# JWT
JWT_SECRET=test_secret_key_must_be_at_least_256_bits_long
JWT_EXPIRES_IN=8h
REFRESH_TOKEN_EXPIRES_IN=30d
# Redis
REDIS_URL=redis://localhost:6379/1
# Email
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_USER=test
SMTP_PASSWORD=test
# App
APP_ENV=test
APP_URL=http://localhost:5173
```
---
## 7. SCHEDULE
### 7.1 Timeline
| Sprint | Actividad | Duración | Responsable | Fecha Estimada |
|--------|-----------|----------|-------------|----------------|
| Sprint 1 | RF-001, RF-002 (Login, RBAC) | 2 sem | Dev + QA | Semana 2 |
| Sprint 2 | RF-003, RF-005, RF-007 (Users, Reset, Sessions) | 2 sem | Dev + QA | Semana 4 |
| Sprint 3 | RF-004 (Multi-tenancy) | 2 sem | Dev + QA | Semana 6 |
| Sprint 4 | RF-006 (Signup) | 2 sem | Dev + QA | Semana 8 |
| Sprint 5 | RF-008 (RLS) | 2 sem | Dev + QA | Semana 10 |
### 7.2 Actividades por Sprint
**Sprint 1 (Login + RBAC):**
- Día 1-3: Desarrollo de US-001-001-001, US-001-001-002, US-001-002-001, US-001-002-002
- Día 4-5: Code review + Integration tests
- Día 6-7: QA testing + E2E tests (TC-001 a TC-003)
- Día 8: Bug fixing
- Día 9: Regression testing
- Día 10: Sprint review + retrospective
**Sprint 2 (Users + Sessions):**
- Similar estructura, enfocado en US-001-003-001, US-001-003-002, US-001-005-001, etc.
---
## 8. ENTRY/EXIT CRITERIA
### Entry Criteria
- [ ] User Stories del sprint escritas y aprobadas (DoR)
- [ ] Test cases escritos en este Test Plan
- [ ] Ambiente de QA configurado (DB, Redis, SMTP)
- [ ] Test data seed scripts creados
- [ ] Código implementado y mergeado a develop
- [ ] Unit tests escritos y pasando (>80%)
- [ ] Integration tests escritos y pasando
- [ ] Code review completado
### Exit Criteria
- [ ] Todos los test cases ejecutados (160 tests)
- [ ] Unit test coverage >80% en módulo MGN-001
- [ ] Integration tests 100% pasando (48 tests)
- [ ] E2E tests críticos 100% pasando (16 tests)
- [ ] Bugs P0/P1 resueltos (100%)
- [ ] Bugs P2 documentados en backlog
- [ ] Performance tests pasando (p95 <300ms)
- [ ] Security tests pasando (JWT, RLS, rate limiting)
- [ ] Tenant isolation verificado (100% casos)
- [ ] Criterios de aceptación validados por PO
- [ ] Documentación Swagger actualizada
- [ ] Sprint review completado
---
## 9. DEFECT MANAGEMENT
### 9.1 Severidad de Bugs
**P0 - Blocker:**
- Sistema de autenticación no funciona (nadie puede login)
- Tenant isolation roto (usuarios ven datos de otros tenants)
- JWT tokens no se generan o son inválidos
- RLS policies no funcionan
- **SLA:** Fix en 24 horas
**P1 - Critical:**
- Refresh token no funciona (usuarios deben re-autenticarse cada 8h)
- Reset password no envía email
- Bloqueo de cuenta no funciona (vulnerability)
- Rate limiting no funciona
- **SLA:** Fix en 3 días
**P2 - Major:**
- UI de login tiene issues (pero login funciona)
- Mensajes de error no son claros
- Performance de login es lenta (>500ms)
- **SLA:** Fix en 1 sprint
**P3 - Minor:**
- Typos en mensajes
- Estilos CSS incorrectos
- Logs no tienen suficiente detalle
- **SLA:** Backlog (no bloqueante)
### 9.2 Bug Report Template
```markdown
**Bug ID:** BUG-MGN-001-001
**Title:** Login falla con credenciales válidas en tenant-b
**Severity:** P0
**Found in:** Sprint 1
**Environment:** QA
**Module:** MGN-001 - Fundamentos
**Steps to Reproduce:**
1. Navegar a https://tenant-b.erp.local/login
2. Ingresar email: "admin@tenant-b.com"
3. Ingresar password: "Admin123!"
4. Click en "Iniciar Sesión"
**Expected Result:**
- JWT token retornado
- Redirect a /dashboard
**Actual Result:**
- Error 500 Internal Server Error
- Log: "tenant_id not found in context"
**Screenshots/Logs:**
[Attach screenshot + server logs]
**Root Cause:**
Tenant context middleware no se ejecuta antes de AuthController
**Assigned to:** Developer 1
**Status:** In Progress
**Fixed in:** PR #123
**Verified by:** QA Engineer
**Closed date:** 2025-11-25
```
---
## 10. RIESGOS ESPECÍFICOS DEL MÓDULO
| Riesgo | Probabilidad | Impacto | Mitigación |
|--------|--------------|---------|------------|
| **Tenant isolation roto** | Media | Crítico | Test suite dedicada con 10+ test cases. Manual audit de RLS policies. Penetration testing. |
| **JWT secret expuesto en logs** | Baja | Crítico | Code review strict. Secrets en env vars, nunca en código. Logging sanitizado. |
| **Bcrypt cost factor muy alto** | Alta | Alto | Benchmarking de login performance. Cost factor 12 es óptimo (300-500ms). |
| **Refresh token leakage** | Media | Alto | Almacenar hasheado en BD. Rotation implementado. HttpOnly cookies. |
| **Rate limiting bypass** | Media | Alto | Rate limit por IP + por user_id. Redis cluster para HA. Monitoring de spikes. |
| **RLS policies tienen bugs** | Media | Crítico | Extensive testing con queries adversariales. DBA review. PostgreSQL audit logs. |
| **Password reset tokens no expiran** | Baja | Alto | Expiration en 1 hora implementado. Test case específico (TC-009). |
| **Session hijacking** | Media | Alto | JWT con short expiry (8h). Refresh token rotation. Device fingerprinting (Fase 2). |
---
## 11. MÉTRICAS
### 11.1 Test Execution Metrics
**Total test cases:** 160
- Unit: 96
- Integration: 48
- E2E: 16
**Executed:** 0/160 (0%)
**Passed:** 0/160 (0%)
**Failed:** 0/160 (0%)
**Blocked:** 0/160 (0%)
**Pass rate:** 0% (objetivo: >95%)
### 11.2 Defect Metrics
**Total bugs found:** 0
- P0: 0
- P1: 0
- P2: 0
- P3: 0
**Defect density:** 0 bugs/100 LOC (objetivo: <1)
### 11.3 Coverage Metrics
**Unit test coverage:** 0% (objetivo: >80%)
- Backend: 0%
- Frontend: 0%
**API coverage:** 0/20 endpoints (objetivo: 100%)
**E2E coverage:** 0/16 journeys (objetivo: 100%)
---
## 12. SIGN-OFF
### 12.1 Test Completion
- [ ] All planned tests executed (160/160)
- [ ] Exit criteria met
- [ ] Test report generated
- [ ] Defects documented
- [ ] Lessons learned captured
### 12.2 Approvals
**QA Engineer:**
Nombre: _______________
Firma: _______________
Fecha: _______________
**Tech Lead:**
Nombre: _______________
Firma: _______________
Fecha: _______________
**Product Owner:**
Nombre: _______________
Firma: _______________
Fecha: _______________
---
## 13. REFERENCIAS
**User Stories:**
- [US-MGN-001-001-001: Login con Email y Contraseña](../../03-user-stories/mgn-001/US-MGN-001-001-001-login-con-email-password.md)
- [US-MGN-001-001-002: Renovar Token JWT](../../03-user-stories/mgn-001/US-MGN-001-001-002-renovar-token-jwt.md)
- [US-MGN-001-002-001: Crear y Gestionar Roles](../../03-user-stories/mgn-001/US-MGN-001-002-001-crear-y-gestionar-roles.md)
- [Ver todas las US de MGN-001](../../03-user-stories/mgn-001/)
**Especificaciones Técnicas:**
- [ET Backend MGN-001](../../02-modelado/especificaciones-tecnicas/backend/mgn-001/)
- [ET Frontend MGN-001](../../02-modelado/especificaciones-tecnicas/frontend/mgn-001/)
**Referencias:**
- [RF MGN-001](../../02-modelado/requerimientos-funcionales/mgn-001/)
- [Traceability MGN-001](../../02-modelado/trazabilidad/TRACEABILITY-MGN-001.yaml)
- [Master Test Plan](./MASTER-TEST-PLAN.md)
---
**Versión:** 1.0
**Última actualización:** 2025-11-24
**Estado:** Draft - Pendiente de aprobación
**Próxima revisión:** Sprint 1 Kickoff