Files
cataRio/postgres/tests/test_functions.sql
josedario87 cc3cf0da81 Refactorizar y mejorar suite de tests con validaciones robustas
Problemas resueltos:
- Eliminada dependencia de UUIDs hardcodeados en tests
- Agregadas validaciones específicas de valores esperados
- Implementado cleanup automático de datos de test

Cambios principales:

Tests organizados por categoría (7 archivos nuevos):
- test_structure.sql: 8 tests de estructura de BD
- test_constraints.sql: 6 tests de validaciones
- test_triggers.sql: 3 tests de triggers automáticos
- test_queries.sql: 5 tests de queries típicas
- test_functions.sql: 3 tests de funciones auxiliares
- test_edge_cases.sql: 7 tests de casos límite
- test_indexes.sql: 6 tests de uso de índices

Mejoras implementadas:
- Cada test genera sus propios datos dinámicamente
- Tests usan bloques DO $$ con UUIDs generados
- Validaciones específicas con valores esperados
- Cleanup automático al finalizar cada test
- Tests de casos edge (arrays vacíos, NULL, límites)
- Verificación de uso de índices con EXPLAIN

test_all.sql actualizado:
- Ahora ejecuta todos los archivos organizados
- Total: ~38 tests independientes y robustos
- Progreso visual por categoría
- ASCII art y mejor presentación

Todos los tests verificados y funcionando correctamente
2025-10-17 17:35:34 -06:00

257 lines
9.3 KiB
SQL

-- ============================================
-- rioCata - Tests de Funciones Auxiliares
-- ============================================
-- Tests que verifican las funciones auxiliares
-- con datos generados dinámicamente
-- ============================================
\echo '=========================================='
\echo 'Tests de Funciones Auxiliares'
\echo '=========================================='
\echo ''
-- ============================================
-- TEST: Función get_promedio_parametro_afectivo
-- ============================================
\echo '[FUNCTION 1] Probando función: get_promedio_parametro_afectivo...'
DO $$
DECLARE
test_sesion_id uuid := gen_random_uuid();
test_user1_id uuid := gen_random_uuid();
test_user2_id uuid := gen_random_uuid();
test_user3_id uuid := gen_random_uuid();
test_part1_id uuid := gen_random_uuid();
test_part2_id uuid := gen_random_uuid();
test_part3_id uuid := gen_random_uuid();
test_muestra_id uuid := gen_random_uuid();
avg_acidez numeric;
avg_dulzor numeric;
avg_sabor numeric;
expected_acidez numeric := 7.0; -- (6 + 8 + 7) / 3
expected_dulzor numeric := 5.0; -- (3 + 7 + 5) / 3
expected_sabor numeric := 8.0; -- (8 + 8 + 8) / 3
BEGIN
-- Crear datos de prueba
INSERT INTO auth.users (id, email, nombre) VALUES
(test_user1_id, 'test_func1_u1@test.com', 'User 1'),
(test_user2_id, 'test_func1_u2@test.com', 'User 2'),
(test_user3_id, 'test_func1_u3@test.com', 'User 3');
INSERT INTO sesion (id, codigo, fecha)
VALUES (test_sesion_id, 'TEST-FUNC-1', CURRENT_DATE);
INSERT INTO sesion_participante (id, sesion_id, catador_id) VALUES
(test_part1_id, test_sesion_id, test_user1_id),
(test_part2_id, test_sesion_id, test_user2_id),
(test_part3_id, test_sesion_id, test_user3_id);
INSERT INTO muestra (id, sesion_id, codigo)
VALUES (test_muestra_id, test_sesion_id, 'TEST-M1');
-- Crear 3 evaluaciones con diferentes valores
INSERT INTO evaluacion (muestra_id, sesion_participante_id, intensidades) VALUES
(test_muestra_id, test_part1_id,
'{"acidez":{"descriptiva":5,"afectiva":6},"dulzor":{"descriptiva":5,"afectiva":3},"sabor":{"descriptiva":8,"afectiva":8}}'::jsonb),
(test_muestra_id, test_part2_id,
'{"acidez":{"descriptiva":10,"afectiva":8},"dulzor":{"descriptiva":10,"afectiva":7},"sabor":{"descriptiva":8,"afectiva":8}}'::jsonb),
(test_muestra_id, test_part3_id,
'{"acidez":{"descriptiva":7,"afectiva":7},"dulzor":{"descriptiva":6,"afectiva":5},"sabor":{"descriptiva":8,"afectiva":8}}'::jsonb);
-- Test función para acidez
SELECT get_promedio_parametro_afectivo(test_sesion_id, 'acidez')
INTO avg_acidez;
IF avg_acidez = expected_acidez THEN
RAISE NOTICE ' ✓ Promedio acidez correcto: % (esperado: %)',
avg_acidez, expected_acidez;
ELSE
RAISE EXCEPTION ' ✗ Promedio acidez incorrecto: % (esperado: %)',
avg_acidez, expected_acidez;
END IF;
-- Test función para dulzor
SELECT get_promedio_parametro_afectivo(test_sesion_id, 'dulzor')
INTO avg_dulzor;
IF avg_dulzor = expected_dulzor THEN
RAISE NOTICE ' ✓ Promedio dulzor correcto: % (esperado: %)',
avg_dulzor, expected_dulzor;
ELSE
RAISE EXCEPTION ' ✗ Promedio dulzor incorrecto: % (esperado: %)',
avg_dulzor, expected_dulzor;
END IF;
-- Test función para sabor
SELECT get_promedio_parametro_afectivo(test_sesion_id, 'sabor')
INTO avg_sabor;
IF avg_sabor = expected_sabor THEN
RAISE NOTICE ' ✓ Promedio sabor correcto: % (esperado: %)',
avg_sabor, expected_sabor;
ELSE
RAISE EXCEPTION ' ✗ Promedio sabor incorrecto: % (esperado: %)',
avg_sabor, expected_sabor;
END IF;
-- Cleanup
DELETE FROM sesion WHERE id = test_sesion_id;
DELETE FROM auth.users WHERE id IN (test_user1_id, test_user2_id, test_user3_id);
RAISE NOTICE '✓ Función get_promedio_parametro_afectivo funciona correctamente';
END $$;
\echo ''
-- ============================================
-- TEST: Función get_top_muestras
-- ============================================
\echo '[FUNCTION 2] Probando función: get_top_muestras...'
DO $$
DECLARE
test_sesion_id uuid := gen_random_uuid();
test_user_id uuid := gen_random_uuid();
test_part_id uuid := gen_random_uuid();
test_muestra1_id uuid := gen_random_uuid();
test_muestra2_id uuid := gen_random_uuid();
test_muestra3_id uuid := gen_random_uuid();
test_muestra4_id uuid := gen_random_uuid();
result record;
result_count int := 0;
first_muestra text;
first_puntaje int;
BEGIN
-- Crear datos de prueba
INSERT INTO auth.users (id, email, nombre)
VALUES (test_user_id, 'test_func2@test.com', 'Test User');
INSERT INTO sesion (id, codigo, fecha)
VALUES (test_sesion_id, 'TEST-FUNC-2', CURRENT_DATE);
INSERT INTO sesion_participante (id, sesion_id, catador_id)
VALUES (test_part_id, test_sesion_id, test_user_id);
-- Crear 4 muestras con puntajes 25, 50, 75, 100 (ordenadas al revés)
INSERT INTO muestra (id, sesion_id, codigo) VALUES
(test_muestra1_id, test_sesion_id, 'PUNTAJE-25'),
(test_muestra2_id, test_sesion_id, 'PUNTAJE-50'),
(test_muestra3_id, test_sesion_id, 'PUNTAJE-75'),
(test_muestra4_id, test_sesion_id, 'PUNTAJE-100');
INSERT INTO evaluacion (muestra_id, sesion_participante_id, intensidades) VALUES
(test_muestra1_id, test_part_id,
'{"fragancia":{"afectiva":3},"aroma":{"afectiva":3},"sabor":{"afectiva":3},"saborResidual":{"afectiva":3},"acidez":{"afectiva":3},"dulzor":{"afectiva":4},"sensacionBoca":{"afectiva":3},"impresionGlobal":{"afectiva":3}}'::jsonb),
(test_muestra2_id, test_part_id,
'{"fragancia":{"afectiva":6},"aroma":{"afectiva":6},"sabor":{"afectiva":6},"saborResidual":{"afectiva":6},"acidez":{"afectiva":7},"dulzor":{"afectiva":7},"sensacionBoca":{"afectiva":6},"impresionGlobal":{"afectiva":6}}'::jsonb),
(test_muestra3_id, test_part_id,
'{"fragancia":{"afectiva":9},"aroma":{"afectiva":9},"sabor":{"afectiva":9},"saborResidual":{"afectiva":10},"acidez":{"afectiva":10},"dulzor":{"afectiva":10},"sensacionBoca":{"afectiva":9},"impresionGlobal":{"afectiva":9}}'::jsonb),
(test_muestra4_id, test_part_id,
'{"fragancia":{"afectiva":10},"aroma":{"afectiva":10},"sabor":{"afectiva":10},"saborResidual":{"afectiva":10},"acidez":{"afectiva":10},"dulzor":{"afectiva":10},"sensacionBoca":{"afectiva":10},"impresionGlobal":{"afectiva":10}}'::jsonb);
-- Test: obtener top 3
FOR result IN
SELECT * FROM get_top_muestras(test_sesion_id, 3)
LOOP
result_count := result_count + 1;
IF result_count = 1 THEN
first_muestra := result.muestra_codigo;
first_puntaje := result.puntaje_final;
END IF;
RAISE NOTICE ' - Posición %: % (% puntos)',
result_count, result.muestra_codigo, result.puntaje_final;
END LOOP;
-- Validar que devolvió 3 resultados
IF result_count != 3 THEN
RAISE EXCEPTION ' ✗ Devolvió % resultados (esperado: 3)', result_count;
END IF;
-- Validar que el primero es PUNTAJE-100 con 80 puntos
IF first_muestra != 'PUNTAJE-100' THEN
RAISE EXCEPTION ' ✗ Primera muestra incorrecta: % (esperado: PUNTAJE-100)',
first_muestra;
END IF;
IF first_puntaje != 80 THEN
RAISE EXCEPTION ' ✗ Primer puntaje incorrecto: % (esperado: 80)',
first_puntaje;
END IF;
RAISE NOTICE ' ✓ Función devuelve top 3 correctamente';
-- Test: obtener top 10 (debería devolver solo 4)
result_count := 0;
FOR result IN
SELECT * FROM get_top_muestras(test_sesion_id, 10)
LOOP
result_count := result_count + 1;
END LOOP;
IF result_count = 4 THEN
RAISE NOTICE ' ✓ Función limita correctamente cuando hay menos resultados que el límite';
ELSE
RAISE EXCEPTION ' ✗ Con limit=10 devolvió % resultados (esperado: 4)',
result_count;
END IF;
-- Cleanup
DELETE FROM sesion WHERE id = test_sesion_id;
DELETE FROM auth.users WHERE id = test_user_id;
RAISE NOTICE '✓ Función get_top_muestras funciona correctamente';
END $$;
\echo ''
-- ============================================
-- TEST: Funciones con sesión vacía
-- ============================================
\echo '[FUNCTION 3] Probando funciones con sesión sin evaluaciones...'
DO $$
DECLARE
test_sesion_id uuid := gen_random_uuid();
avg_result numeric;
top_count int := 0;
result record;
BEGIN
-- Crear sesión vacía
INSERT INTO sesion (id, codigo, fecha)
VALUES (test_sesion_id, 'TEST-FUNC-EMPTY', CURRENT_DATE);
-- Test get_promedio_parametro_afectivo con sesión vacía
SELECT get_promedio_parametro_afectivo(test_sesion_id, 'acidez')
INTO avg_result;
IF avg_result IS NULL THEN
RAISE NOTICE ' ✓ get_promedio_parametro_afectivo devuelve NULL con sesión vacía';
ELSE
RAISE EXCEPTION ' ✗ Devolvió % en lugar de NULL', avg_result;
END IF;
-- Test get_top_muestras con sesión vacía
FOR result IN
SELECT * FROM get_top_muestras(test_sesion_id, 3)
LOOP
top_count := top_count + 1;
END LOOP;
IF top_count = 0 THEN
RAISE NOTICE ' ✓ get_top_muestras devuelve conjunto vacío con sesión vacía';
ELSE
RAISE EXCEPTION ' ✗ Devolvió % resultados en lugar de 0', top_count;
END IF;
-- Cleanup
DELETE FROM sesion WHERE id = test_sesion_id;
RAISE NOTICE '✓ Funciones manejan correctamente sesiones vacías';
END $$;
\echo ''
\echo '=========================================='
\echo 'Tests de Funciones completados'
\echo '=========================================='