155 lines
6.0 KiB
JavaScript
155 lines
6.0 KiB
JavaScript
import http from 'http';
|
|
import { spawn } from 'child_process';
|
|
|
|
const PORT = 3055;
|
|
const BASE_URL = `http://127.0.0.1:${PORT}`;
|
|
|
|
async function sleep(ms) {
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
}
|
|
|
|
async function request(path, options = {}) {
|
|
const url = `${BASE_URL}${path}`;
|
|
const headers = { 'Content-Type': 'application/json', ...(options.headers || {}) };
|
|
const res = await fetch(url, {
|
|
method: options.method || 'GET',
|
|
headers,
|
|
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
});
|
|
const data = await res.json().catch(() => ({ text: '' }));
|
|
return { status: res.status, ok: res.ok, data };
|
|
}
|
|
|
|
async function runTests() {
|
|
console.log('🧪 Iniciando pruebas automáticas de funcionalidad en vivo...');
|
|
|
|
// 1. Levantar servidor en puerto dedicado 3055
|
|
const serverProcess = spawn('node', ['dist-server/index.js'], {
|
|
env: { ...process.env, PORT: String(PORT), NODE_ENV: 'production' },
|
|
stdio: 'pipe',
|
|
shell: true,
|
|
});
|
|
|
|
serverProcess.stdout.on('data', (d) => process.stdout.write(`[SERVER] ${d}`));
|
|
serverProcess.stderr.on('data', (d) => process.stderr.write(`[SERVER ERR] ${d}`));
|
|
serverProcess.on('error', (err) => console.error('[SERVER SPAWN ERROR]', err));
|
|
|
|
await sleep(3500);
|
|
|
|
try {
|
|
// 2. Health check
|
|
console.log('\n1. Test Health Check:');
|
|
const health = await request('/api/health');
|
|
console.log(' Status:', health.status, 'Response:', JSON.stringify(health.data));
|
|
if (!health.ok || health.data.status !== 'ok') throw new Error('Health check failed');
|
|
console.log(' ✅ Health check OK');
|
|
|
|
// 3. Obtener votos iniciales
|
|
console.log('\n2. Test GET /api/votes:');
|
|
const initialVotes = await request('/api/votes');
|
|
console.log(' Initial votes count:', initialVotes.data.total);
|
|
console.log(' ✅ GET /api/votes OK');
|
|
|
|
// 4. Conectar al stream Server-Sent Events (SSE)
|
|
console.log('\n3. Test Live SSE Stream (/api/stream):');
|
|
let sseReceivedCount = 0;
|
|
const sseReq = http.get(`${BASE_URL}/api/stream`, (res) => {
|
|
res.on('data', (chunk) => {
|
|
const text = chunk.toString();
|
|
if (text.includes('event: votes') || text.includes('event: initial')) {
|
|
sseReceivedCount++;
|
|
console.log(` ⚡ Evento SSE recibido en tiempo real! (total eventos: ${sseReceivedCount})`);
|
|
}
|
|
});
|
|
});
|
|
|
|
await sleep(500);
|
|
|
|
// 5. Emitir Voto Válido 1 (SERVANDO vota por ANNA)
|
|
console.log('\n4. Test Emitir Voto (SERVANDO -> ANNA):');
|
|
const vote1 = await request('/api/vote', {
|
|
method: 'POST',
|
|
body: { voter: 'SERVANDO PEREZ', candidate: 'ANNA' },
|
|
});
|
|
console.log(' Vote 1 status:', vote1.status, 'Data:', vote1.data);
|
|
if (!vote1.ok || !vote1.data.success) throw new Error('Vote 1 failed');
|
|
console.log(' ✅ Voto 1 registrado');
|
|
|
|
await sleep(400);
|
|
|
|
// 6. Emitir Voto Válido 2 (MELINA vota por URIEL)
|
|
console.log('\n5. Test Emitir Voto (MELINA -> URIEL):');
|
|
const vote2 = await request('/api/vote', {
|
|
method: 'POST',
|
|
body: { voter: 'MELINA GOMEZ', candidate: 'URIEL' },
|
|
});
|
|
console.log(' Vote 2 status:', vote2.status, 'Data:', vote2.data);
|
|
if (!vote2.ok || !vote2.data.success) throw new Error('Vote 2 failed');
|
|
console.log(' ✅ Voto 2 registrado');
|
|
|
|
await sleep(400);
|
|
|
|
// 7. Test Anti-Autovoto (URIEL intenta votar por URIEL)
|
|
console.log('\n6. Test Bloqueo de Autovoto (URIEL -> URIEL):');
|
|
const selfVote = await request('/api/vote', {
|
|
method: 'POST',
|
|
body: { voter: 'URIEL JARETH', candidate: 'URIEL' },
|
|
});
|
|
console.log(' Self-vote status:', selfVote.status, 'Data:', selfVote.data);
|
|
if (selfVote.status !== 400) throw new Error('Anti-autovoto no bloqueó la petición');
|
|
console.log(' ✅ Autovoto bloqueado correctamente con 400 Bad Request');
|
|
|
|
// 8. Test Protección por Contraseña Incorrecta
|
|
console.log('\n7. Test Protección de Contraseña (Rechazo con clave errónea):');
|
|
const badPassRes = await request('/api/vote/SERVANDO%20PEREZ', {
|
|
method: 'DELETE',
|
|
headers: { 'x-admin-key': 'CLAVE_INCORRECTA' },
|
|
});
|
|
console.log(' Bad pass status:', badPassRes.status, 'Data:', badPassRes.data);
|
|
if (badPassRes.status !== 401) throw new Error('Contraseña incorrecta no fue rechazada');
|
|
console.log(' ✅ Clave incorrecta rechazada con 401 Unauthorized');
|
|
|
|
// 9. Test Remover Voto Individual con Clave "REMOVERVOTOE3"
|
|
console.log('\n8. Test Remover Voto Individual con REMOVERVOTOE3:');
|
|
const deleteRes = await request('/api/vote/SERVANDO%20PEREZ', {
|
|
method: 'DELETE',
|
|
headers: { 'x-admin-key': 'REMOVERVOTOE3' },
|
|
});
|
|
console.log(' Delete status:', deleteRes.status, 'Data:', deleteRes.data);
|
|
if (!deleteRes.ok) throw new Error('Delete vote failed');
|
|
console.log(' ✅ Voto de SERVANDO removido exitosamente con REMOVERVOTOE3');
|
|
|
|
await sleep(400);
|
|
|
|
// 10. Test Vaciar Todo con "REMOVERVOTOE3"
|
|
console.log('\n9. Test Vaciar Todos los Votos (Reset General) con REMOVERVOTOE3:');
|
|
const deleteAllRes = await request('/api/votes', {
|
|
method: 'DELETE',
|
|
headers: { 'x-admin-key': 'REMOVERVOTOE3' },
|
|
});
|
|
console.log(' Delete all status:', deleteAllRes.status, 'Data:', deleteAllRes.data);
|
|
if (!deleteAllRes.ok) throw new Error('Delete all votes failed');
|
|
console.log(' ✅ Todos los votos vaciados correctamente');
|
|
|
|
await sleep(400);
|
|
|
|
// 11. Confirmar estado final vacío
|
|
const finalVotes = await request('/api/votes');
|
|
console.log('\n10. Estado final de votos en base de datos:', finalVotes.data.votes);
|
|
if (finalVotes.data.total !== 0) throw new Error('Los votos no se vaciaron completamente');
|
|
|
|
sseReq.destroy();
|
|
|
|
console.log('\n=========================================');
|
|
console.log('🎉 TODAS LAS PRUEBAS DE REMOCIÓN EN VIVO PASARON CON ÉXITO (100% FUNCIONAL)');
|
|
console.log('=========================================\n');
|
|
} finally {
|
|
serverProcess.kill();
|
|
}
|
|
}
|
|
|
|
runTests().catch((err) => {
|
|
console.error('❌ Error en pruebas:', err);
|
|
process.exit(1);
|
|
});
|