feat(api): implement javascript-first architecture for cache compatibility
- Add REST endpoint GET /roi-theme/v1/adsense-placement/visibility - Add Domain layer: UserContext, VisibilityDecision, AdsenseSettings VOs - Add Application layer: CheckAdsenseVisibilityUseCase - Add Infrastructure: AdsenseVisibilityChecker, Controller, Enqueuer - Add JavaScript controller with localStorage caching - Add test plan for production validation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
545
openspec/specs/adsense-javascript-first/test-plan.md
Normal file
545
openspec/specs/adsense-javascript-first/test-plan.md
Normal file
@@ -0,0 +1,545 @@
|
||||
# Plan de Pruebas: AdSense JavaScript-First Architecture
|
||||
|
||||
> **NOTA IMPORTANTE - PROTOCOLO DE PRUEBAS**
|
||||
>
|
||||
> Las pruebas se ejecutan en el servidor de PRODUCCION.
|
||||
> Si hay algo que corregir, se modifica en LOCAL y luego se despliega.
|
||||
>
|
||||
> **PROHIBIDO**: Modificar codigo directamente en produccion.
|
||||
> **PERMITIDO**: Solo ejecutar pruebas y verificaciones en produccion.
|
||||
>
|
||||
> Flujo correcto:
|
||||
> 1. Ejecutar prueba en produccion
|
||||
> 2. Si falla, corregir en local
|
||||
> 3. Desplegar cambios a produccion
|
||||
> 4. Re-ejecutar prueba
|
||||
|
||||
---
|
||||
|
||||
## Resumen de Pruebas
|
||||
|
||||
| ID | Categoria | Descripcion | Criterio de Aceptacion |
|
||||
|----|-----------|-------------|------------------------|
|
||||
| T01 | Endpoint REST | Endpoint registrado y accesible | HTTP 200 con JSON valido |
|
||||
| T02 | Endpoint REST | Headers anti-cache presentes | Cache-Control, Pragma, Expires |
|
||||
| T03 | Endpoint REST | Parametro post_id requerido | HTTP 400 sin post_id |
|
||||
| T04 | Endpoint REST | post_id=0 valido (archivos/home) | HTTP 200 con post_id=0 |
|
||||
| T05 | Visibilidad | Componente deshabilitado | show_ads=false, reason=component_disabled |
|
||||
| T06 | Visibilidad | Usuario anonimo sin exclusiones | show_ads=true, reasons=[] |
|
||||
| T07 | Visibilidad | Usuario logueado excluido | show_ads=false, reason=logged_in_excluded |
|
||||
| T08 | Visibilidad | Rol excluido | show_ads=false, reason=role_excluded |
|
||||
| T09 | Visibilidad | Post excluido | show_ads=false, reason=post_excluded |
|
||||
| T10 | JavaScript | Script cargado en frontend | roiAdsenseConfig definido |
|
||||
| T11 | JavaScript | Cache localStorage funciona | Datos guardados correctamente |
|
||||
| T12 | JavaScript | Fallback cuando error | Ads se muestran en error |
|
||||
| T13 | Feature Flag | Modo deshabilitado = legacy | No llama endpoint |
|
||||
| T14 | Feature Flag | Modo habilitado = JS-First | Llama endpoint |
|
||||
| T15 | Clean Arch | Value Objects inmutables | No WordPress en Domain |
|
||||
| T16 | Clean Arch | Interface en Domain | AdsenseVisibilityCheckerInterface existe |
|
||||
|
||||
---
|
||||
|
||||
## Pruebas Detalladas
|
||||
|
||||
### T01: Endpoint REST Registrado y Accesible
|
||||
|
||||
**Categoria**: Endpoint REST
|
||||
**Prioridad**: CRITICA
|
||||
**Spec Reference**: Requirement: Endpoint REST Visibility
|
||||
|
||||
**Pasos**:
|
||||
1. Abrir navegador o usar curl
|
||||
2. Acceder a: `https://analisisdepreciosunitarios.com/wp-json/roi-theme/v1/adsense-placement/visibility?post_id=1`
|
||||
|
||||
**Resultado Esperado**:
|
||||
- HTTP Status: 200
|
||||
- Content-Type: application/json
|
||||
- Body contiene: `show_ads`, `reasons`, `cache_seconds`, `timestamp`
|
||||
|
||||
**Comando de Prueba**:
|
||||
```bash
|
||||
curl -i "https://analisisdepreciosunitarios.com/wp-json/roi-theme/v1/adsense-placement/visibility?post_id=1"
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T02: Headers Anti-Cache Presentes
|
||||
|
||||
**Categoria**: Endpoint REST
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Headers anti-cache obligatorios
|
||||
|
||||
**Pasos**:
|
||||
1. Hacer request al endpoint
|
||||
2. Verificar headers de respuesta
|
||||
|
||||
**Resultado Esperado**:
|
||||
- `Cache-Control: no-store, no-cache, must-revalidate, max-age=0`
|
||||
- `Pragma: no-cache`
|
||||
- `Expires: Thu, 01 Jan 1970 00:00:00 GMT` o `0`
|
||||
- `Vary: Cookie`
|
||||
|
||||
**Comando de Prueba**:
|
||||
```bash
|
||||
curl -I "https://analisisdepreciosunitarios.com/wp-json/roi-theme/v1/adsense-placement/visibility?post_id=1"
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T03: Parametro post_id Requerido
|
||||
|
||||
**Categoria**: Endpoint REST
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Parametros del endpoint
|
||||
|
||||
**Pasos**:
|
||||
1. Hacer request SIN post_id
|
||||
2. Verificar respuesta de error
|
||||
|
||||
**Resultado Esperado**:
|
||||
- HTTP Status: 400 (Bad Request)
|
||||
- Body contiene mensaje de error indicando que post_id es requerido
|
||||
|
||||
**Comando de Prueba**:
|
||||
```bash
|
||||
curl -i "https://analisisdepreciosunitarios.com/wp-json/roi-theme/v1/adsense-placement/visibility"
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T04: post_id=0 Valido para Paginas de Archivo
|
||||
|
||||
**Categoria**: Endpoint REST
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Parametros del endpoint (validate_callback >= 0)
|
||||
|
||||
**Pasos**:
|
||||
1. Hacer request con post_id=0
|
||||
2. Verificar que responde correctamente
|
||||
|
||||
**Resultado Esperado**:
|
||||
- HTTP Status: 200
|
||||
- Body contiene decision de visibilidad valida
|
||||
|
||||
**Comando de Prueba**:
|
||||
```bash
|
||||
curl -i "https://analisisdepreciosunitarios.com/wp-json/roi-theme/v1/adsense-placement/visibility?post_id=0"
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T05: Componente Deshabilitado Retorna False
|
||||
|
||||
**Categoria**: Visibilidad
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Componente deshabilitado
|
||||
|
||||
**Pre-condicion**:
|
||||
- Deshabilitar componente en admin (is_enabled = false)
|
||||
|
||||
**Pasos**:
|
||||
1. Deshabilitar adsense-placement en admin
|
||||
2. Hacer request al endpoint
|
||||
3. Verificar respuesta
|
||||
|
||||
**Resultado Esperado**:
|
||||
```json
|
||||
{
|
||||
"show_ads": false,
|
||||
"reasons": ["component_disabled"],
|
||||
"cache_seconds": 3600
|
||||
}
|
||||
```
|
||||
|
||||
**Comando de Prueba**:
|
||||
```bash
|
||||
curl "https://analisisdepreciosunitarios.com/wp-json/roi-theme/v1/adsense-placement/visibility?post_id=1"
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T06: Usuario Anonimo Sin Exclusiones Ve Ads
|
||||
|
||||
**Categoria**: Visibilidad
|
||||
**Prioridad**: CRITICA
|
||||
**Spec Reference**: Scenario: Usuario anonimo sin exclusiones
|
||||
|
||||
**Pre-condicion**:
|
||||
- Componente habilitado
|
||||
- javascript_first_mode habilitado
|
||||
- Sin exclusiones configuradas
|
||||
- No estar logueado
|
||||
|
||||
**Pasos**:
|
||||
1. Abrir navegador en modo incognito
|
||||
2. Acceder a un post del sitio
|
||||
3. Verificar respuesta del endpoint
|
||||
|
||||
**Resultado Esperado**:
|
||||
```json
|
||||
{
|
||||
"show_ads": true,
|
||||
"reasons": [],
|
||||
"cache_seconds": 60
|
||||
}
|
||||
```
|
||||
|
||||
**Comando de Prueba**:
|
||||
```bash
|
||||
curl "https://analisisdepreciosunitarios.com/wp-json/roi-theme/v1/adsense-placement/visibility?post_id=1"
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T07: Usuario Logueado Excluido
|
||||
|
||||
**Categoria**: Visibilidad
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Usuario logueado excluido
|
||||
|
||||
**Pre-condicion**:
|
||||
- Activar "Ocultar para usuarios logueados" en admin
|
||||
|
||||
**Pasos**:
|
||||
1. Loguearse en WordPress
|
||||
2. Copiar cookies de sesion
|
||||
3. Hacer request con cookies
|
||||
|
||||
**Resultado Esperado**:
|
||||
```json
|
||||
{
|
||||
"show_ads": false,
|
||||
"reasons": ["logged_in_excluded"],
|
||||
"cache_seconds": 300
|
||||
}
|
||||
```
|
||||
|
||||
**Verificacion Manual**:
|
||||
1. Loguearse en wp-admin
|
||||
2. Visitar un post en el frontend
|
||||
3. Abrir DevTools > Network
|
||||
4. Buscar request a `/visibility`
|
||||
5. Verificar respuesta
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T08: Rol Excluido
|
||||
|
||||
**Categoria**: Visibilidad
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Rol de usuario excluido
|
||||
|
||||
**Pre-condicion**:
|
||||
- Agregar "administrator" a roles excluidos en admin
|
||||
|
||||
**Pasos**:
|
||||
1. Loguearse como administrator
|
||||
2. Visitar un post
|
||||
3. Verificar respuesta del endpoint
|
||||
|
||||
**Resultado Esperado**:
|
||||
```json
|
||||
{
|
||||
"show_ads": false,
|
||||
"reasons": ["role_excluded"],
|
||||
"cache_seconds": 300
|
||||
}
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T09: Post Excluido por ID
|
||||
|
||||
**Categoria**: Visibilidad
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Post excluido por ID
|
||||
|
||||
**Pre-condicion**:
|
||||
- Agregar un ID de post a "IDs de posts excluidos" en admin
|
||||
|
||||
**Pasos**:
|
||||
1. Anotar el ID del post excluido (ej: 123)
|
||||
2. Hacer request con ese post_id
|
||||
3. Verificar respuesta
|
||||
|
||||
**Resultado Esperado**:
|
||||
```json
|
||||
{
|
||||
"show_ads": false,
|
||||
"reasons": ["post_excluded"],
|
||||
"cache_seconds": 60
|
||||
}
|
||||
```
|
||||
|
||||
**Comando de Prueba**:
|
||||
```bash
|
||||
curl "https://analisisdepreciosunitarios.com/wp-json/roi-theme/v1/adsense-placement/visibility?post_id=123"
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T10: Script JavaScript Cargado
|
||||
|
||||
**Categoria**: JavaScript
|
||||
**Prioridad**: CRITICA
|
||||
**Spec Reference**: Scenario: Configuracion via wp_localize_script
|
||||
|
||||
**Pre-condicion**:
|
||||
- javascript_first_mode habilitado
|
||||
|
||||
**Pasos**:
|
||||
1. Visitar un post en el frontend
|
||||
2. Abrir DevTools > Console
|
||||
3. Escribir: `window.roiAdsenseConfig`
|
||||
|
||||
**Resultado Esperado**:
|
||||
- Objeto definido con propiedades:
|
||||
- `endpoint`: URL del endpoint REST
|
||||
- `postId`: ID del post actual
|
||||
- `nonce`: String no vacio
|
||||
- `featureEnabled`: true
|
||||
- `debug`: boolean
|
||||
|
||||
**Verificacion Alternativa**:
|
||||
```javascript
|
||||
// En consola del navegador
|
||||
console.log(window.roiAdsenseConfig);
|
||||
console.log(typeof window.roiAdsenseVisibility);
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T11: Cache localStorage Funciona
|
||||
|
||||
**Categoria**: JavaScript
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Cache en localStorage
|
||||
|
||||
**Pasos**:
|
||||
1. Visitar un post (primera vez)
|
||||
2. Abrir DevTools > Application > Local Storage
|
||||
3. Buscar key `roi_adsense_visibility`
|
||||
4. Recargar pagina
|
||||
5. Verificar en Network que NO hay nueva llamada al endpoint
|
||||
|
||||
**Resultado Esperado**:
|
||||
- localStorage contiene:
|
||||
```json
|
||||
{
|
||||
"show_ads": true,
|
||||
"reasons": [],
|
||||
"timestamp": 1733900000,
|
||||
"cache_seconds": 60
|
||||
}
|
||||
```
|
||||
- Segunda carga NO hace request al endpoint (usa cache)
|
||||
|
||||
**Verificacion en Consola**:
|
||||
```javascript
|
||||
localStorage.getItem('roi_adsense_visibility');
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T12: Fallback en Error de Red
|
||||
|
||||
**Categoria**: JavaScript
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Fallback strategy cached-or-show
|
||||
|
||||
**Pasos**:
|
||||
1. Limpiar localStorage
|
||||
2. Abrir DevTools > Network
|
||||
3. Habilitar "Offline" mode
|
||||
4. Visitar un post
|
||||
5. Verificar comportamiento
|
||||
|
||||
**Resultado Esperado**:
|
||||
- Los ads se muestran (fallback = show)
|
||||
- No hay error en consola (error manejado gracefully)
|
||||
|
||||
**Verificacion Alternativa**:
|
||||
```javascript
|
||||
// Limpiar cache
|
||||
window.roiAdsenseVisibility.clearCache();
|
||||
// Recargar con network offline
|
||||
```
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T13: Feature Flag Deshabilitado = Modo Legacy
|
||||
|
||||
**Categoria**: Feature Flag
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Feature flag deshabilitado
|
||||
|
||||
**Pre-condicion**:
|
||||
- Deshabilitar javascript_first_mode en admin
|
||||
|
||||
**Pasos**:
|
||||
1. Deshabilitar javascript_first_mode
|
||||
2. Visitar un post
|
||||
3. Verificar en Network que NO hay llamada al endpoint
|
||||
|
||||
**Resultado Esperado**:
|
||||
- `roiAdsenseConfig.featureEnabled` = false
|
||||
- No hay request a `/visibility` endpoint
|
||||
- Ads se muestran inmediatamente (modo legacy)
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T14: Feature Flag Habilitado = JS-First
|
||||
|
||||
**Categoria**: Feature Flag
|
||||
**Prioridad**: ALTA
|
||||
**Spec Reference**: Scenario: Feature flag habilitado
|
||||
|
||||
**Pre-condicion**:
|
||||
- Habilitar javascript_first_mode en admin
|
||||
|
||||
**Pasos**:
|
||||
1. Habilitar javascript_first_mode
|
||||
2. Limpiar cache (localStorage y pagina)
|
||||
3. Visitar un post
|
||||
4. Verificar en Network que SI hay llamada al endpoint
|
||||
|
||||
**Resultado Esperado**:
|
||||
- `roiAdsenseConfig.featureEnabled` = true
|
||||
- Request a `/visibility` endpoint presente
|
||||
- Ads se muestran/ocultan segun respuesta
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T15: Value Objects Sin Dependencias WordPress
|
||||
|
||||
**Categoria**: Clean Architecture
|
||||
**Prioridad**: MEDIA
|
||||
**Spec Reference**: Scenario: Value Object VisibilityDecision en Domain
|
||||
|
||||
**Verificacion**:
|
||||
Revisar que los archivos NO contengan funciones de WordPress:
|
||||
|
||||
**Archivos a verificar**:
|
||||
- `Domain/ValueObjects/UserContext.php`
|
||||
- `Domain/ValueObjects/VisibilityDecision.php`
|
||||
- `Domain/ValueObjects/AdsenseSettings.php`
|
||||
- `Domain/Contracts/AdsenseVisibilityCheckerInterface.php`
|
||||
- `Application/UseCases/CheckAdsenseVisibilityUseCase.php`
|
||||
|
||||
**Resultado Esperado**:
|
||||
- Sin `get_`, `wp_`, `is_user_logged_in`, `WP_*` classes
|
||||
- Solo PHP puro y tipos del proyecto
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
### T16: Interface en Domain
|
||||
|
||||
**Categoria**: Clean Architecture
|
||||
**Prioridad**: MEDIA
|
||||
**Spec Reference**: Scenario: Interface en Domain
|
||||
|
||||
**Verificacion**:
|
||||
El archivo `Domain/Contracts/AdsenseVisibilityCheckerInterface.php` debe:
|
||||
- Existir en la ruta correcta
|
||||
- Definir metodo `check(int $postId, UserContext $userContext): VisibilityDecision`
|
||||
- NO referenciar WordPress
|
||||
|
||||
**Estado**: [ ] Pendiente
|
||||
**Resultado**:
|
||||
**Notas**:
|
||||
|
||||
---
|
||||
|
||||
## Checklist de Despliegue Pre-Pruebas
|
||||
|
||||
Antes de ejecutar las pruebas, verificar:
|
||||
|
||||
- [ ] Codigo desplegado a produccion via FTP/SSH
|
||||
- [ ] Cache de pagina limpiado
|
||||
- [ ] javascript_first_mode habilitado en admin
|
||||
- [ ] Componente adsense-placement habilitado
|
||||
- [ ] Schema sincronizado en BD (campo javascript_first_mode existe)
|
||||
|
||||
---
|
||||
|
||||
## Registro de Ejecucion
|
||||
|
||||
| Fecha | Tester | Pruebas Ejecutadas | Pasadas | Fallidas | Notas |
|
||||
|-------|--------|-------------------|---------|----------|-------|
|
||||
| | | | | | |
|
||||
|
||||
---
|
||||
|
||||
## Defectos Encontrados
|
||||
|
||||
| ID | Prueba | Descripcion | Severidad | Estado | Correccion |
|
||||
|----|--------|-------------|-----------|--------|------------|
|
||||
| | | | | | |
|
||||
|
||||
---
|
||||
|
||||
## Historial de Versiones
|
||||
|
||||
| Version | Fecha | Cambios |
|
||||
|---------|-------|---------|
|
||||
| 1.0 | 2025-12-11 | Plan inicial basado en spec v1.5 |
|
||||
Reference in New Issue
Block a user