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
433 lines
14 KiB
SQL
433 lines
14 KiB
SQL
-- ============================================
|
|
-- rioCata - Tests de Casos Límite (Edge Cases)
|
|
-- ============================================
|
|
-- Tests que verifican comportamiento en casos límite
|
|
-- y situaciones especiales
|
|
-- ============================================
|
|
|
|
\echo '=========================================='
|
|
\echo 'Tests de Casos Límite'
|
|
\echo '=========================================='
|
|
\echo ''
|
|
|
|
-- ============================================
|
|
-- TEST: Arrays vacíos son válidos
|
|
-- ============================================
|
|
\echo '[EDGE 1] Validando arrays vacíos...'
|
|
|
|
DO $$
|
|
DECLARE
|
|
test_sesion_id uuid := gen_random_uuid();
|
|
test_user_id uuid := gen_random_uuid();
|
|
test_part_id uuid := gen_random_uuid();
|
|
test_muestra_id uuid := gen_random_uuid();
|
|
BEGIN
|
|
-- Crear datos de prueba
|
|
INSERT INTO auth.users (id, email, nombre)
|
|
VALUES (test_user_id, 'test_edge1@test.com', 'Test User');
|
|
|
|
INSERT INTO sesion (id, codigo, fecha)
|
|
VALUES (test_sesion_id, 'TEST-EDGE-1', CURRENT_DATE);
|
|
|
|
INSERT INTO sesion_participante (id, sesion_id, catador_id)
|
|
VALUES (test_part_id, test_sesion_id, test_user_id);
|
|
|
|
INSERT INTO muestra (id, sesion_id, codigo)
|
|
VALUES (test_muestra_id, test_sesion_id, 'TEST-M1');
|
|
|
|
-- Test: evaluación con todos los arrays vacíos
|
|
BEGIN
|
|
INSERT INTO evaluacion (
|
|
muestra_id, sesion_participante_id, intensidades,
|
|
tazas_no_uniformes, tazas_defectuosas,
|
|
sensacion_en_boca, gustos_predominantes
|
|
) VALUES (
|
|
test_muestra_id, test_part_id,
|
|
'{"fragancia":{"descriptiva":5,"afectiva":5}}'::jsonb,
|
|
ARRAY[]::smallint[], ARRAY[]::smallint[],
|
|
ARRAY[]::text[], ARRAY[]::text[]
|
|
);
|
|
RAISE NOTICE ' ✓ Acepta arrays vacíos correctamente';
|
|
EXCEPTION WHEN OTHERS THEN
|
|
RAISE EXCEPTION ' ✗ Rechazó arrays vacíos: %', SQLERRM;
|
|
END;
|
|
|
|
-- Cleanup
|
|
DELETE FROM sesion WHERE id = test_sesion_id;
|
|
DELETE FROM auth.users WHERE id = test_user_id;
|
|
|
|
RAISE NOTICE '✓ Arrays vacíos funcionan correctamente';
|
|
END $$;
|
|
|
|
\echo ''
|
|
|
|
-- ============================================
|
|
-- TEST: Campos opcionales en NULL
|
|
-- ============================================
|
|
\echo '[EDGE 2] Validando campos opcionales en NULL...'
|
|
|
|
DO $$
|
|
DECLARE
|
|
test_sesion_id uuid := gen_random_uuid();
|
|
test_user_id uuid := gen_random_uuid();
|
|
test_part_id uuid := gen_random_uuid();
|
|
test_muestra_id uuid := gen_random_uuid();
|
|
BEGIN
|
|
-- Crear datos de prueba
|
|
INSERT INTO auth.users (id, email, nombre)
|
|
VALUES (test_user_id, 'test_edge2@test.com', 'Test User');
|
|
|
|
INSERT INTO sesion (id, codigo, fecha)
|
|
VALUES (test_sesion_id, 'TEST-EDGE-2', CURRENT_DATE);
|
|
|
|
INSERT INTO sesion_participante (id, sesion_id, catador_id)
|
|
VALUES (test_part_id, test_sesion_id, test_user_id);
|
|
|
|
INSERT INTO muestra (id, sesion_id, codigo)
|
|
VALUES (test_muestra_id, test_sesion_id, 'TEST-M2');
|
|
|
|
-- Test: evaluación con campos opcionales en NULL
|
|
BEGIN
|
|
INSERT INTO evaluacion (
|
|
muestra_id, sesion_participante_id, intensidades,
|
|
defecto, otras_notas
|
|
) VALUES (
|
|
test_muestra_id, test_part_id,
|
|
'{"fragancia":{"descriptiva":5,"afectiva":5}}'::jsonb,
|
|
NULL, NULL
|
|
);
|
|
RAISE NOTICE ' ✓ Acepta campos opcionales NULL';
|
|
EXCEPTION WHEN OTHERS THEN
|
|
RAISE EXCEPTION ' ✗ Rechazó campos NULL: %', SQLERRM;
|
|
END;
|
|
|
|
-- Cleanup
|
|
DELETE FROM sesion WHERE id = test_sesion_id;
|
|
DELETE FROM auth.users WHERE id = test_user_id;
|
|
|
|
RAISE NOTICE '✓ Campos opcionales NULL funcionan correctamente';
|
|
END $$;
|
|
|
|
\echo ''
|
|
|
|
-- ============================================
|
|
-- TEST: JSONB con solo un parámetro
|
|
-- ============================================
|
|
\echo '[EDGE 3] Validando intensidades con un solo parámetro...'
|
|
|
|
DO $$
|
|
DECLARE
|
|
test_sesion_id uuid := gen_random_uuid();
|
|
test_user_id uuid := gen_random_uuid();
|
|
test_part_id uuid := gen_random_uuid();
|
|
test_muestra_id uuid := gen_random_uuid();
|
|
puntaje int;
|
|
BEGIN
|
|
-- Crear datos de prueba
|
|
INSERT INTO auth.users (id, email, nombre)
|
|
VALUES (test_user_id, 'test_edge3@test.com', 'Test User');
|
|
|
|
INSERT INTO sesion (id, codigo, fecha)
|
|
VALUES (test_sesion_id, 'TEST-EDGE-3', CURRENT_DATE);
|
|
|
|
INSERT INTO sesion_participante (id, sesion_id, catador_id)
|
|
VALUES (test_part_id, test_sesion_id, test_user_id);
|
|
|
|
INSERT INTO muestra (id, sesion_id, codigo)
|
|
VALUES (test_muestra_id, test_sesion_id, 'TEST-M3');
|
|
|
|
-- Test: solo un parámetro en intensidades
|
|
BEGIN
|
|
INSERT INTO evaluacion (
|
|
muestra_id, sesion_participante_id, intensidades
|
|
) VALUES (
|
|
test_muestra_id, test_part_id,
|
|
'{"fragancia":{"descriptiva":5,"afectiva":7}}'::jsonb
|
|
) RETURNING puntaje_final INTO puntaje;
|
|
|
|
IF puntaje = 7 THEN
|
|
RAISE NOTICE ' ✓ Acepta un solo parámetro y calcula puntaje correcto: %', puntaje;
|
|
ELSE
|
|
RAISE EXCEPTION ' ✗ Puntaje incorrecto con un parámetro: % (esperado: 7)', puntaje;
|
|
END IF;
|
|
EXCEPTION WHEN check_violation THEN
|
|
RAISE EXCEPTION ' ✗ Rechazó un solo parámetro: %', SQLERRM;
|
|
END;
|
|
|
|
-- Cleanup
|
|
DELETE FROM sesion WHERE id = test_sesion_id;
|
|
DELETE FROM auth.users WHERE id = test_user_id;
|
|
|
|
RAISE NOTICE '✓ Un solo parámetro funciona correctamente';
|
|
END $$;
|
|
|
|
\echo ''
|
|
|
|
-- ============================================
|
|
-- TEST: Valores descriptivos NULL con afectivos presentes
|
|
-- ============================================
|
|
\echo '[EDGE 4] Validando descriptiva NULL con afectiva presente...'
|
|
|
|
DO $$
|
|
DECLARE
|
|
test_sesion_id uuid := gen_random_uuid();
|
|
test_user_id uuid := gen_random_uuid();
|
|
test_part_id uuid := gen_random_uuid();
|
|
test_muestra_id uuid := gen_random_uuid();
|
|
puntaje int;
|
|
BEGIN
|
|
-- Crear datos de prueba
|
|
INSERT INTO auth.users (id, email, nombre)
|
|
VALUES (test_user_id, 'test_edge4@test.com', 'Test User');
|
|
|
|
INSERT INTO sesion (id, codigo, fecha)
|
|
VALUES (test_sesion_id, 'TEST-EDGE-4', CURRENT_DATE);
|
|
|
|
INSERT INTO sesion_participante (id, sesion_id, catador_id)
|
|
VALUES (test_part_id, test_sesion_id, test_user_id);
|
|
|
|
INSERT INTO muestra (id, sesion_id, codigo)
|
|
VALUES (test_muestra_id, test_sesion_id, 'TEST-M4');
|
|
|
|
-- Test: impresionGlobal con descriptiva NULL (caso común)
|
|
BEGIN
|
|
INSERT INTO evaluacion (
|
|
muestra_id, sesion_participante_id, intensidades
|
|
) VALUES (
|
|
test_muestra_id, test_part_id,
|
|
'{"impresionGlobal":{"descriptiva":null,"afectiva":8}}'::jsonb
|
|
) RETURNING puntaje_final INTO puntaje;
|
|
|
|
IF puntaje = 8 THEN
|
|
RAISE NOTICE ' ✓ Acepta descriptiva NULL y calcula puntaje correcto: %', puntaje;
|
|
ELSE
|
|
RAISE EXCEPTION ' ✗ Puntaje incorrecto: % (esperado: 8)', puntaje;
|
|
END IF;
|
|
EXCEPTION WHEN OTHERS THEN
|
|
RAISE EXCEPTION ' ✗ Rechazó descriptiva NULL: %', SQLERRM;
|
|
END;
|
|
|
|
-- Cleanup
|
|
DELETE FROM sesion WHERE id = test_sesion_id;
|
|
DELETE FROM auth.users WHERE id = test_user_id;
|
|
|
|
RAISE NOTICE '✓ Descriptiva NULL funciona correctamente';
|
|
END $$;
|
|
|
|
\echo ''
|
|
|
|
-- ============================================
|
|
-- TEST: JSONB arrays con múltiples elementos
|
|
-- ============================================
|
|
\echo '[EDGE 5] Validando arrays JSONB con múltiples notas...'
|
|
|
|
DO $$
|
|
DECLARE
|
|
test_sesion_id uuid := gen_random_uuid();
|
|
test_user_id uuid := gen_random_uuid();
|
|
test_part_id uuid := gen_random_uuid();
|
|
test_muestra_id uuid := gen_random_uuid();
|
|
notas_count int;
|
|
BEGIN
|
|
-- Crear datos de prueba
|
|
INSERT INTO auth.users (id, email, nombre)
|
|
VALUES (test_user_id, 'test_edge5@test.com', 'Test User');
|
|
|
|
INSERT INTO sesion (id, codigo, fecha)
|
|
VALUES (test_sesion_id, 'TEST-EDGE-5', CURRENT_DATE);
|
|
|
|
INSERT INTO sesion_participante (id, sesion_id, catador_id)
|
|
VALUES (test_part_id, test_sesion_id, test_user_id);
|
|
|
|
INSERT INTO muestra (id, sesion_id, codigo)
|
|
VALUES (test_muestra_id, test_sesion_id, 'TEST-M5');
|
|
|
|
-- Test: múltiples notas de fragancia/aroma
|
|
BEGIN
|
|
INSERT INTO evaluacion (
|
|
muestra_id, sesion_participante_id, intensidades,
|
|
fragancia_aroma_notas, sabor_notas
|
|
) VALUES (
|
|
test_muestra_id, test_part_id,
|
|
'{"fragancia":{"descriptiva":5,"afectiva":5}}'::jsonb,
|
|
'[
|
|
{"categoria":"Afrutado","subcategoria":"Cítricos","notaEspecifica":"Naranja"},
|
|
{"categoria":"Floral","subcategoria":"Jazmín","notaEspecifica":null},
|
|
{"categoria":"Especiado","subcategoria":"Canela","notaEspecifica":"Canela dulce"}
|
|
]'::jsonb,
|
|
'[
|
|
{"categoria":"Chocolatado","subcategoria":"Chocolate negro","notaEspecifica":null},
|
|
{"categoria":"Nueces","subcategoria":"Almendra","notaEspecifica":"Tostada"}
|
|
]'::jsonb
|
|
);
|
|
|
|
-- Verificar que se guardaron correctamente
|
|
SELECT jsonb_array_length(fragancia_aroma_notas)
|
|
INTO notas_count
|
|
FROM evaluacion
|
|
WHERE muestra_id = test_muestra_id;
|
|
|
|
IF notas_count = 3 THEN
|
|
RAISE NOTICE ' ✓ Acepta múltiples notas de fragancia (3)';
|
|
ELSE
|
|
RAISE EXCEPTION ' ✗ Cantidad incorrecta de notas: % (esperado: 3)', notas_count;
|
|
END IF;
|
|
|
|
SELECT jsonb_array_length(sabor_notas)
|
|
INTO notas_count
|
|
FROM evaluacion
|
|
WHERE muestra_id = test_muestra_id;
|
|
|
|
IF notas_count = 2 THEN
|
|
RAISE NOTICE ' ✓ Acepta múltiples notas de sabor (2)';
|
|
ELSE
|
|
RAISE EXCEPTION ' ✗ Cantidad incorrecta de notas: % (esperado: 2)', notas_count;
|
|
END IF;
|
|
|
|
EXCEPTION WHEN OTHERS THEN
|
|
RAISE EXCEPTION ' ✗ Rechazó múltiples notas: %', SQLERRM;
|
|
END;
|
|
|
|
-- Cleanup
|
|
DELETE FROM sesion WHERE id = test_sesion_id;
|
|
DELETE FROM auth.users WHERE id = test_user_id;
|
|
|
|
RAISE NOTICE '✓ Arrays JSONB con múltiples elementos funcionan correctamente';
|
|
END $$;
|
|
|
|
\echo ''
|
|
|
|
-- ============================================
|
|
-- TEST: Evaluación mínima válida (solo intensidades requeridas)
|
|
-- ============================================
|
|
\echo '[EDGE 6] Validando evaluación mínima válida...'
|
|
|
|
DO $$
|
|
DECLARE
|
|
test_sesion_id uuid := gen_random_uuid();
|
|
test_user_id uuid := gen_random_uuid();
|
|
test_part_id uuid := gen_random_uuid();
|
|
test_muestra_id uuid := gen_random_uuid();
|
|
eval_id uuid;
|
|
BEGIN
|
|
-- Crear datos de prueba
|
|
INSERT INTO auth.users (id, email, nombre)
|
|
VALUES (test_user_id, 'test_edge6@test.com', 'Test User');
|
|
|
|
INSERT INTO sesion (id, codigo, fecha)
|
|
VALUES (test_sesion_id, 'TEST-EDGE-6', CURRENT_DATE);
|
|
|
|
INSERT INTO sesion_participante (id, sesion_id, catador_id)
|
|
VALUES (test_part_id, test_sesion_id, test_user_id);
|
|
|
|
INSERT INTO muestra (id, sesion_id, codigo)
|
|
VALUES (test_muestra_id, test_sesion_id, 'TEST-M6');
|
|
|
|
-- Test: solo intensidades (campo obligatorio), todo lo demás default/NULL
|
|
BEGIN
|
|
INSERT INTO evaluacion (
|
|
muestra_id, sesion_participante_id, intensidades
|
|
) VALUES (
|
|
test_muestra_id, test_part_id,
|
|
'{"fragancia":{"descriptiva":1,"afectiva":1}}'::jsonb
|
|
) RETURNING id INTO eval_id;
|
|
|
|
-- Verificar que los defaults se aplicaron
|
|
PERFORM 1
|
|
FROM evaluacion
|
|
WHERE id = eval_id
|
|
AND fragancia_aroma_notas = '[]'::jsonb
|
|
AND sabor_notas = '[]'::jsonb
|
|
AND tazas_no_uniformes = ARRAY[]::smallint[]
|
|
AND tazas_defectuosas = ARRAY[]::smallint[]
|
|
AND sensacion_en_boca = ARRAY[]::text[]
|
|
AND gustos_predominantes = ARRAY[]::text[]
|
|
AND defecto IS NULL
|
|
AND otras_notas IS NULL;
|
|
|
|
IF FOUND THEN
|
|
RAISE NOTICE ' ✓ Evaluación mínima válida con defaults correctos';
|
|
ELSE
|
|
RAISE EXCEPTION ' ✗ Defaults no se aplicaron correctamente';
|
|
END IF;
|
|
|
|
EXCEPTION WHEN OTHERS THEN
|
|
RAISE EXCEPTION ' ✗ Rechazó evaluación mínima: %', SQLERRM;
|
|
END;
|
|
|
|
-- Cleanup
|
|
DELETE FROM sesion WHERE id = test_sesion_id;
|
|
DELETE FROM auth.users WHERE id = test_user_id;
|
|
|
|
RAISE NOTICE '✓ Evaluación mínima válida funciona correctamente';
|
|
END $$;
|
|
|
|
\echo ''
|
|
|
|
-- ============================================
|
|
-- TEST: Texto largo en otras_notas
|
|
-- ============================================
|
|
\echo '[EDGE 7] Validando texto largo en otras_notas...'
|
|
|
|
DO $$
|
|
DECLARE
|
|
test_sesion_id uuid := gen_random_uuid();
|
|
test_user_id uuid := gen_random_uuid();
|
|
test_part_id uuid := gen_random_uuid();
|
|
test_muestra_id uuid := gen_random_uuid();
|
|
long_text text;
|
|
stored_text text;
|
|
BEGIN
|
|
-- Crear datos de prueba
|
|
INSERT INTO auth.users (id, email, nombre)
|
|
VALUES (test_user_id, 'test_edge7@test.com', 'Test User');
|
|
|
|
INSERT INTO sesion (id, codigo, fecha)
|
|
VALUES (test_sesion_id, 'TEST-EDGE-7', CURRENT_DATE);
|
|
|
|
INSERT INTO sesion_participante (id, sesion_id, catador_id)
|
|
VALUES (test_part_id, test_sesion_id, test_user_id);
|
|
|
|
INSERT INTO muestra (id, sesion_id, codigo)
|
|
VALUES (test_muestra_id, test_sesion_id, 'TEST-M7');
|
|
|
|
-- Generar texto de 1000 caracteres
|
|
long_text := repeat('Este es un texto largo con muchos detalles sobre la catación. ', 20);
|
|
|
|
-- Test: insertar texto largo
|
|
BEGIN
|
|
INSERT INTO evaluacion (
|
|
muestra_id, sesion_participante_id, intensidades, otras_notas
|
|
) VALUES (
|
|
test_muestra_id, test_part_id,
|
|
'{"fragancia":{"descriptiva":5,"afectiva":5}}'::jsonb,
|
|
long_text
|
|
);
|
|
|
|
SELECT otras_notas INTO stored_text
|
|
FROM evaluacion
|
|
WHERE muestra_id = test_muestra_id;
|
|
|
|
IF stored_text = long_text THEN
|
|
RAISE NOTICE ' ✓ Acepta y almacena texto largo (% caracteres)', length(stored_text);
|
|
ELSE
|
|
RAISE EXCEPTION ' ✗ Texto almacenado no coincide';
|
|
END IF;
|
|
|
|
EXCEPTION WHEN OTHERS THEN
|
|
RAISE EXCEPTION ' ✗ Falló con texto largo: %', SQLERRM;
|
|
END;
|
|
|
|
-- Cleanup
|
|
DELETE FROM sesion WHERE id = test_sesion_id;
|
|
DELETE FROM auth.users WHERE id = test_user_id;
|
|
|
|
RAISE NOTICE '✓ Texto largo funciona correctamente';
|
|
END $$;
|
|
|
|
\echo ''
|
|
|
|
\echo '=========================================='
|
|
\echo 'Tests de Casos Límite completados'
|
|
\echo '=========================================='
|