Saltar a contenido

Tests

Catálogo completo de la suite de tests del backend. Son 106 archivos de test que cubren desde el seam-compat y el dialecto SQL Server hasta los clientes AFIP (WSAA/WSFE), los endpoints SOAP, el cockpit, el modelo multi-ente (EnteFacturador) y la red de paridad con el legacy. Para el qué prueba cada uno mirá las tablas; para el contexto de la migración que estos tests blindan, Backend e Invariantes.

Cómo correr

Todo corre con mvn test (perfil de test sobre H2 embebido). El build con tests es mvn clean package. Tres grupos NO corren en CI normal y están condicionados por flag (se detallan abajo): los smoke contra AFIP homologación, los smoke contra DB real y un método de paridad @Disabled. Sin esos flags, esos tests quedan skipped — no rompen el build.

Tipos

Marca Significado
unit JUnit + Mockito o construcción manual, sin levantar contexto Spring. Rápido, offline.
integración Levanta contexto Spring sobre H2 (la mayoría extiende AbstractSeamComponentTest = @SpringBootTest).
smoke-AFIP Pega contra AFIP homologación con cert real. Gated por -Dafipsmoke=true / -Dsoapsmoke=true. EMITE CAE real.
real-DB Corre contra la base SQL Server real (perfil realdb, gitignored). Gated por -Drealdb=true.
paridad Red de seguridad SPEC-016: si falla, el fix iguala al legacy (no se toca el viejo). Ver nota de paridad.

Núcleo / AFIP / SOAP

Raíz com.tipre.tifacturaonlinemanager. Seam-compat, dialecto, contrato de error, infra Quartz, clientes AFIP (WSAA/WSFE) y publicación de los endpoints SOAP. Ver Cliente AFIP y API SOAP.

Test Qué valida Tipo
AbstractSeamComponentTest Base de los tests con contexto: re-asocia el bridge Seam↔Spring antes de cada test para evitar errores de transacción por contextos cacheados. integración
AfipCaeServiceTest Mapeo TrxFecaeInput y emisión/consulta de CAE, con actualización de la Trx y registro de métricas. unit
AfipHomologacionSmokeTest End-to-end real: WSAA LoginCms + WSFE FECAESolicitar y FECompUltimoAutorizado contra homologación con cert real. smoke-AFIP
AfipRequestGoldenMasterTest Golden master del request SOAP a AFIP (WSFEv1) por variante de comprobante: congela byte-a-byte el XML que arma cada cliente contra src/test/resources/golden/afip/ (CAE factura B, tributos, opcionales, NC con CbtesAsoc, servicios concepto 2, multi-alícuota, moneda extranjera, todos los sub-arrays juntos y CAEA RegInformativo); caza cualquier drift de mapeo. unit
ArcaTlsContextFactoryTest Construcción del SSLContext de ARCA: mutual-TLS, truststore default del JDK y modo insecure (trust-all). unit
CaeaHomologacionSmokeTest Wire format de TODAS las ops CAEA contra homologación: que AFIP acepte el envelope y responda (no valida negocio). smoke-AFIP
CockpitRealDbSmokeTest End-to-end del cockpit contra DB real: los endpoints /api/cockpit/* responden 200 con datos. real-DB
CockpitTest Métricas del cockpit (contadores, tasa de éxito, errores acotados a 50) y el endpoint /api/cockpit/summary. unit
ErrorHardeningTest Los handlers NUEVOS (cockpit, mapping, 404/405) nunca filtran stacktrace ni mensaje interno, a diferencia del contrato legacy SPEC-009. unit
LoginTicketRequestTest El TRA de WSAA conforme al legacy: estructura, tiempos (generationTime/expirationTime/uniqueId) y validez del XML. unit
MigrationFilteredUniquesDeclaredTest Regression guard (sin Spring/DB): las migraciones SIGUEN declarando los UNIQUE filtrados UQ_Trx_nextgen/UQ_Trx_pv_comprobante_aprobado con su WHERE version='V2' (H2 no lo soporta). unit
QuartzInfraTest Infra Quartz: el scheduler agenda un job desde DB y registra la Tarea; clases inexistentes no rompen el arranque. integración
RealDbSchemaValidationTest Los mapeos JPA contra el esquema real de prod: las queries ejercitan columnas y un mismatch de @Table/@Column falla. real-DB
UqTrxNextgenEnforcedRealDbTest Prueba contra SQL Server real que los UNIQUE filtrados V2 rechazan el duplicado: segunda fila con misma clave NextGen y dos aprobadas con mismo ptoVta+comprobante violan el índice (cada test en tx con rollback). real-DB
RestErrorContractTest Contrato de error REST SPEC-009: una excepción no manejada da 500 con headers exception-class/message y el stacktrace en el body. unit
SQLServerDialectTest El dialecto propio mapea BOOLEANbit (como el legacy) y extiende el dialecto SQL Server de Hibernate. unit
SeamCompatPocTest PoC del seam-compat: bridge por nombre, scope EVENT, EntityHome.persist/find, update() sin merge y el endpoint de versión. integración
SoapEndpointPublishTest Los 3 endpoints SOAP se publican y sirven su WSDL en las URLs de producción. integración
TfomWsEndpointTest Wiring del endpoint TiFacturaOnlineManagerWS: feCompUltimoAutorizado y fecaeSolicitar/NextGen (V1 y V2). unit
TfomWsSoapSmokeTest End-to-end del cable SOAP del gateway contra homologación: emite CAE real en operaciones V1 y V2. smoke-AFIP
TrxWsEndpointTest Wiring de TrxWS.saveTrx (notificación CAEA) y el armado del Response. unit
WsaaClientTest Flujo completo del WsaaClient: TRA → firma CMS → envelope SOAP → parse de credenciales. unit
WsaaCmsSignerTest Firma CMS con BouncyCastle 1.78: digest SHA-1 y contenido encapsulado (invariante §5.5). unit
WsaaLoginResponseParserTest Parseo de la respuesta WSAA LoginCms (token/sign/expiration) y manejo del faultstring. unit
WsaaTokenCacheTest Cache del TA: reusa el vigente, renueva al expirar con margen y separa por clave. unit
WsaaTokenCacheEvictTest Evict del TA (L1): evict(cuit) remueve solo esa entrada (próximo get es miss), es idempotente con CUIT ausente y no afecta a los demás. unit
WsdlDiffGateTest Gate bloqueante: el WSDL servido por CXF es idéntico al baseline congelado en producción (invariante §5.9). integración
WsfeCaeClientTest FECAESolicitar offline: request con XSD correcto y parse de CAE / rechazo con observaciones / errors de AFIP. unit
WsfeCaeaClientTest WsfeCaeaClient offline: armado y parseo de las 4 operaciones CAEA (solicitar/consultar/registrar/sin-movimiento). unit
WsfeDummyClientTest FEDummy: online=true solo si AppServer, AuthServer y DbServer son "OK". unit
WsfeUltimoComprobanteClientTest FECompUltimoAutorizado: envelope con Auth+PtoVta+CbteTipo, parse del CbteNro y manejo de errors. unit

Jobs (action/job y action/quartz)

Bitácora de ejecución de jobs Quartz y warm-up del scheduler. Ver Jobs Quartz.

Test Qué valida Tipo
JobEjecucionRecordingTest Registra OK/ERROR en la ejecución de un job según si completó o capturó un error. integración
JobEjecucionRegistroTest Última ejecución por job en la bitácora y truncado de errores largos. integración
CommonJobScopeClearTest CommonJob.finallyDo limpia el scope EVENT seam-compat al terminar cada job, evitando state bleed de Home/List entre corridas en el mismo worker. integración
TokenManagerJobMultiEnteTest TokenManagerJob itera N entes habilitados en tx REQUIRES_NEW: hace get(ente) por cada uno, un fallo no aborta a los demás y single-ente queda byte-equivalente. integración
TokenManagerJobWarmUpMultiEnteTest El warm-up (ApplicationReadyEvent/scheduleAllFromDb) dispara el TokenManagerJob, que invoca get(ente) por cada ente con aislamiento de fallos. integración
NotaCreditoReconciliacionJobContractTest Hardening F2: contrato del wrapper Quartz de la reconciliación de NC: si el service revienta, el ciclo CommonJob igual asienta ERROR con el mensaje en la bitácora y libera el lock de ThreadSafety (la próxima corrida puede ejecutar). integración
TareaSchedulerWarmUpFqcnTest FIX #3 (hardening F0): una Tarea sembrada con el FQCN del TokenManagerJob (no el simple name) igual dispara el warm-up del TA al arranque; la detección compara la clase resuelta, no el string crudo. integración

Servicios de facturación (action/ws y action/ws/client)

El corazón del negocio: emisión CAE/CAEA, idempotencia, reconciliación de notas de crédito y serialización de numeración.

Test Qué valida Tipo
CaeaConsultaServiceSucPosPVTest Búsqueda y handoff de PV por sucursal/posición y obtención del CUIT habilitado. integración
CaeaConsultaServiceTest Vigencia de CAEA: devuelve los no vencidos ordenados y excluye los vencidos. integración
CaeaGestionServiceTest Consulta CAEA; ante error 602, solicita uno nuevo y lo persiste. integración
CaeaNotificacionServiceTest Registro de CAEA a ARCA: dedup por ptoVta+comprobante y validación de fecha. integración
ComprobantesEmitidosServiceTest Informa a AFIP los comprobantes pendientes cuyo número supera el último autorizado. integración
FacturacionServiceNextGenTest Dedup y emisión CAE/CAEA con sus 4 ramas lógicas, persistencia de hijos en cascada (ALTO-2). integración
FacturacionServiceTest Idempotencia de fecaeSolicitar/feCompConsultar, saveTrx CAEA e inicialización lazy. integración
NotaCreditoReconciliacionServiceTest Reconcilia el par CAE+CAEA y emite la NC: idempotencia y manejo del huérfano. integración
NumeracionLockInMemoryTest Serialización conLock: dos hilos sobre la misma clave no se solapan; claves distintas corren en paralelo. unit
NumeracionLockEnteTest conLock(idEnte,ptoVta,tipo): entes distintos con misma clave no se bloquean entre sí; mismo ente con misma clave se serializa. unit
NumeracionLockConnectionAffinityProbeTest Probe contra SQL Server real (@@SPID/APPLOCK_TEST): el applock de sesión de numeración sobrevive a un REQUIRES_NEW (afinidad de conexión preservada). real-DB
NumeracionLockSqlServerTxGuardTest Hardening F0: conLock sin transacción activa falla inmediato y claro (IllegalStateException), evitando que el applock de sesión quede huérfano en el pool por acquire y release en conexiones distintas. unit
PvSinMovimientoServiceTest Informa a AFIP los PV CAEA sin movimientos y los registra. integración
ComprobanteFechaValidatorTest Guard de formato YYYYMMDD: acepta 8 dígitos y rechaza null, vacío, con guiones, de 7 y de 9 dígitos. unit
EnteResolverTest EnteResolver.resolve(trx) (ente válido/null/inexistente/deshabilitado) y validarPropiedad(ente,suc,pos) con INTEGRIDAD_FISCAL y 0 llamadas a AFIP. integración
EnteFacturadorSeleccionDeterministaTest Selección determinística del ente habilitado (id asc), fail-closed ENTE_NO_DECLARADO sin tocar AFIP, y get() sin parámetro devuelve el primero por id. integración
IntegridadFiscalEnteResolverTest Integración del EnteResolver en fecaeSolicitarNextGen (V2): rechaza ente incorrecto o sin ente ANTES de AFIP, sin fila persistida y con 0 llamadas a AFIP. integración
PtoVentaConsultaServiceEnteAwareTest PtoVentaConsultaService ente-aware: usa el TA del ente indicado (get(ente)) y el CUIT del WsfeAuth corresponde al ente correcto, no al genérico. unit
SucPosPVListEnteTest SucPosPVList.getBySucPos(ente,suc,pos): cada ente obtiene solo su propia fila (multi-ente con misma suc/pos) e inexistente devuelve null. integración
EnteFacturadorTokenProviderTest Reusa el TA vigente en DB sin re-login; si no hay, hace login y persiste el nuevo en el ente. integración
EnteFacturadorTokenProviderEvictTest Evict de dos niveles (L1 memoria + L2 DB): tras evict(ente) el TA queda nulo en DB y el próximo get re-loguea; no afecta a otro ente y persiste sobre entes detached (§5.2). integración
TokenProviderWiringTest Regresión de bean-shadowing: mockear el Supplier<WsaaCredentials> legacy no reemplaza al EnteFacturadorTokenProvider concreto, que sigue siendo bean real inyectable. integración
AfipCertLoaderTest Lógica pura de resolución del cert por ente: valida certP12Path, fallback alias→CUIT y tolerancia a password null (sin cargar keystore). unit
RetryWiringTest Hardening F2: invariante de no-idempotencia del wiring: los clientes que emiten (WsfeCaeClient, WsfeCaeaClient con writes) NO llevan RetryingSoapTransport; solo los read-only (dummy/ultimo/consulta) lo llevan. integración
RetryingSoapTransportTest Hardening F2: el decorador de retry con max-attempts=1 (default) es pass-through exacto (un intento, sin re-post); con N intentos reintenta ante fallo y propaga la última excepción al agotarse. unit
TrafficCaptureRedactionTest Hardening F1: el body traffic del cockpit runner redacta el TA (token/sign de WSAA) en sus dos formas reales (crudas <ar:Token>/<ar:Sign> y escapadas dentro del loginCmsReturn); con la captura inactiva record es no-op. unit

Cockpit (cockpit)

Panel de operación: KPIs, pendientes, desglose por PV, snapshot de métricas, ABM de SucPosPV y runner de tests. Ver Cockpit.

Test Qué valida Tipo
CockpitAdminControllerTest ABM de SucPosPV: auth por secret y CRUD con validación ARCA (200/401/409/404/503). unit
CockpitAdminControllerSucPosPVExtTest ABM SucPosPV con idEnteFacturador (MockMvc standalone): POST 201/422/400, PUT reasignación 200/422 y GET con/sin filtro ?idEnteFacturador. unit
CockpitPageTest Gate HTTP de /cockpit (302/401 sin auth, pasa con auth) y verifica en el cockpit.html el marcador abm-section y que el password del cert arranca vacío. integración
CockpitAfipStatusMultiEnteTest CockpitAfipStatus.status() retorna la lista facturadores con {cuit, razonSocial, ta:{vigente,expira}} por cada ente habilitado, backward-compatible con single-ente. integración
CockpitEnteFilterTest Los endpoints del cockpit (pos-stats, kpi, pendientes, por-pos, ultimas-trx) filtran por ?ente (CSV), sin ente devuelven todos, y /entes lista solo habilitados. integración
CockpitPosStatsSinglePassTest La dedup de posStats() (single-pass por request) no desincroniza /server-stats, /kpi ni /ranking, y posStats es idempotente. integración
CockpitStatSnapshotEnteTest CockpitStat incluye idEnteFacturador: los factory methods lo aceptan, el legacy queda null y el GROUP BY idEnteFacturador separa registros por ente. integración
CockpitJobsTest Una Tarea registrada en Quartz con ejecución en bitácora aparece en la grilla con resultado, error y próxima ejecución. integración
CockpitKpiRankingTest KPI y ranking: cálculo del % de éxito de CAE, totales en cero y orden "peor primero". integración
CockpitPendientesTest Las tres cuentas (pendientesDeCae, conError, autorizados) contabilizan correctamente por estado. integración
CockpitPorPosTest Desglose por PV/modalidad/período: CAE/CAEA/rechazados se separan y el filtro por rango funciona. integración
CockpitPosTrxTest Filtros de transacciones por resultado (ok/error/reproceso) y presencia de los campos de salida. integración
CockpitStatSnapshotTest El snapshot inserta filas ARCA/SERVER/POS, calcula arcaUptimePct y sin datos devuelve cero. integración
CockpitTestRunnerServiceTest Runner con servicios AFIP mockeados: consulta/emisión CAE, dummy, validación de PV, token y CAEA. integración
CockpitTestRunnerTrxBuilderTest Builders de los escenarios del runner (Factura B con Imp. Internos y Factura A completa con 3 alícuotas de IVA + 3 tributos): el detalle impositivo (ids e importes) cuadra como lo espera AFIP antes de emitir real. unit
CockpitV1DataTest V1 mapea ptoVta a (suc,pos), los POS configurados aparecen en cero y las notas de crédito se excluyen. integración
SucPosPVAdminServiceTest CRUD con unicidades (suc+pos, pvcae/caea global), validación ARCA y reset de fechas al cambiar el PV. integración
TrxErrorRegistroTest La grilla de errores filtra por tipo y rango de fechas, tipos() puebla el desplegable y se truncan los mensajes. integración
EnteFacturadorAdminControllerTest ABM EnteFacturador (MockMvc standalone): gate del secret (503/401), CRUD (200/201/409/404), habilitar/deshabilitar y no-fuga de password. unit
EnteFacturadorAdminControllerCertTest PUT /{id}/cert (MockMvc standalone): set/update del cert (200/404/401) y que la respuesta nunca incluye certP12Password. unit
EnteFacturadorAdminControllerReloadTest POST /{id}/cert/reload (MockMvc standalone): invoca recargarCert/evict (200) y escenarios de error 422/404/401. unit
EnteFacturadorPasswordLeakTest No-fuga end-to-end HTTP: certP12Password nunca aparece en las respuestas JSON de GET/listar/POST/PUT-cert, vía whitelist DTO. unit
EnteFacturadorPasswordLogLeakTest No-fuga en LOGS: con ListAppender de Logback sobre el servicio real contra H2, ni crear ni setCert loguean el valor de la password. integración
PvsAfipComparacionTest Comparación local-vs-AFIP en verificarPvsContraAfip: clasifica PVs ok/faltantes/no-configurados (CAE y CAEA), 404 si el comercio no existe y AfipException si AFIP falla. integración
PvsAfipControllerTest GET /comercios/{id}/pvs-afip (MockMvc standalone): devuelve la comparación (ok/faltantes/noConfigurados), 404 comercio inexistente, 502 ante error AFIP y 401 sin auth. unit
SucPosPVEnteResolverConsistencyTest Consistencia ABM SucPosPVEnteResolver: un PV creado por ABM (con ente) resuelve sin INTEGRIDAD_FISCAL, y un PV legacy sin ente no rompe el resolver (error de dominio, no NPE). integración
ArcaLinkHealthTest Debounce del enlace ARCA (homologación es flaky): un blip aislado nunca declara "caído"; recién tras N fallos consecutivos pasa a caido, 1..N-1 es verificando y un OK resetea el contador. Umbral configurable. unit
MensajeCuradorTest Cura el mensaje humano del error crudo para TrxErrorLog.mensajeCurado (lo consume el job de alarmas): extrae el Reason del SOAP fault, el message del JSON y la observación del rechazo AFIP; null/blanco → null y trunca a 500 chars. unit

Configuración (config)

Test Qué valida Tipo
AfipBatchConfigTest Config de batch: default 1; el constructor setea el estático que lee TrxList (seam-compat). unit
CockpitSecurityTest Contrato del SecurityFilterChain: /api/cockpit/** 401 sin credenciales, permit-all del SOAP/REST de facturación, CSRF off para POST máquina y forwards/static del cockpit con auth. integración
SecurityConfigProdFailFastTest Hardening F2: con perfil prod y credenciales del cockpit vacías o admin/changeme, el arranque falla (IllegalStateException, fail-fast); con credenciales reales arranca y en dev es solo un warning. unit
TrafficLoggingFilterTest El filtro preserva el body de respuesta intacto (vía cache) y loguea IN/OUT al logger TRAFFIC. unit

Modelo (model)

Test Qué valida Tipo
EnteFacturadorTest Seguridad (hallazgo #7 del code-review): el toString() de EnteFacturador nunca filtra el valor del TA (token/sign de WSAA) —los redacta como [REDACTED]— pero conserva visibles los datos no sensibles (cuit) para diagnóstico; con TA null muestra null. unit

Paridad con el legacy (parity)

Red de seguridad de SPEC-016 que blinda los invariantes §5 contra el comportamiento del sistema Seam original. Contexto completo en src/test/java/.../parity/PARIDAD.md.

Test Qué valida Tipo
IdempotenciaParidadTest Paridad legacy: lookup idempotente de la Trx ya facturada con ordering id desc + maxResults(1) (invariantes §5.3/§5.4). paridad
InvariantesParidadTest Paridad legacy de los invariantes §5: update() sin merge (§5.2) y demás. El método de flush manual (§5.1) está @Disabled (GAP conocido). paridad
JobLockingParidadTest Paridad legacy: el locking por ThreadSafety evita la ejecución solapada de tareas (§5.13). paridad

Mapeo SOAP / endpoints (ws/endpoint y web)

Mappers gen↔modelo y discriminación de versión en el dispatch.

Test Qué valida Tipo
GenTfomTrxMapperTest Mapeo gen.tfom.Trx ↔ entidad: CAE y CAEA contra muestras reales; el round-trip preserva los campos. unit
GenTrxTrxMapperTest Mapeo gen.trx.Trx ↔ entidad: CAEA con detalle y receptor; el round-trip preserva campos e hijos. unit
GenTrxMappersDriftTest Guard de drift por reflexión: gen.tfom.Trx y gen.trx.Trx comparten el mismo set de campos salvo los 4 de NextGen; cualquier otra diferencia rompe el build. unit
TfomWsEndpointFecaeDispatchTest Discriminación V1/V2 por dato (nroTicketPos vs comprobante); enviar ambos a la vez se rechaza. unit
CaeaWsRestControllerTest Contrato JSON de getCaea: omite nulls (no cascadea a los nested) y el path legacy resuelve igual. Ver API REST. unit
CaeaNotificacionRestControllerTest Fix #5 (judgment-day): POST /fecaeaSolicitar devuelve un DTO plano de scalars (200) en vez de la entidad JPA cruda, evitando el LazyInit 500 al serializar las relaciones lazy con open-in-view apagado. unit

Paridad y smoke: grupos especiales

Los smoke y real-DB están gated — no corren en mvn test solo

  • smoke-AFIP (AfipHomologacionSmokeTest, CaeaHomologacionSmokeTest, TfomWsSoapSmokeTest): requieren -Dafipsmoke=true (o -Dsoapsmoke=true) y un cert real de homologación (NUNCA en el repo). EMITEN CAE real en homologación.
  • real-DB (RealDbSchemaValidationTest, CockpitRealDbSmokeTest, UqTrxNextgenEnforcedRealDbTest, NumeracionLockConnectionAffinityProbeTest): requieren -Drealdb=true y el perfil realdb (gitignored, con credenciales). Validan los mapeos JPA, el cockpit, los UNIQUE filtrados V2 y la afinidad de conexión del applock contra la base SQL Server real.
  • Sin esos flags quedan skipped vía @EnabledIfSystemProperty — el CI normal no los toca.

Paridad: si falla, se arregla lo nuevo

El grupo parity (SPEC-016) es la red de seguridad de la migración: cada test fija un comportamiento del legacy Seam (los invariantes §5). La regla es que si un test de paridad falla, el fix iguala al legacy — el sistema viejo no se toca. Un método (inv_5_1_flushManual... en InvariantesParidadTest) está @Disabled porque Spring/Hibernate fuerza auto-flush: es un GAP conocido y documentado, no un test roto.

Para levantar el entorno y poder correr estos grupos (cert de homologación, perfil realdb), seguí el Setup del entorno.