From 0ea17fd091a5190f506cca3c81c346e45d42def8 Mon Sep 17 00:00:00 2001 From: AlexeerCT Date: Tue, 24 Mar 2026 12:58:01 -0500 Subject: [PATCH] Add detailed test flow documentation to backend tests README - Expanded the README.md for backend tests to include a comprehensive overview of the test flow, infrastructure, and edge cases. - Introduced sections detailing the structure of tests, including integration and unit tests, along with diagrams to illustrate the business flow and common scenarios. - Enhanced clarity on the setup and execution of tests, including database handling and security measures during testing. - This update aims to improve understanding and maintainability of the testing framework for future contributors. --- backend/tests/README.md | 124 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/backend/tests/README.md b/backend/tests/README.md index bfbab7c8..ef790e4b 100644 --- a/backend/tests/README.md +++ b/backend/tests/README.md @@ -6,6 +6,130 @@ - `tests/integration/`: process API behavior and edge cases. - `tests/unit/`: critical algorithms only (no trivial CRUD tests). +--- + +## Vista del flujo de tests (backend) + +### Dónde vive todo + +| Capa | Ruta | Rol | +|------|------|-----| +| Infra | [conftest.py](conftest.py) | DB en transacción + rollback, Celery eager, app mínima con router de process, overrides de DB/usuario, tareas import/export **inline** en la misma sesión | +| Datos | [fixtures/builders.py](fixtures/builders.py) | Catálogos, tenant/company, facturas import/export con líneas enlazadas | +| E2E | [e2e/test_inventory_flow_anexo24.py](e2e/test_inventory_flow_anexo24.py) | Flujo negocio completo import → export → saldos/descargas | +| Integración | [integration/test_import_process_api.py](integration/test_import_process_api.py), [integration/test_export_process_api.py](integration/test_export_process_api.py) | API HTTP + reglas por tipo de factura, saldo, doble proceso | +| Unit | [unit/invoices/test_balance_algorithm.py](unit/invoices/test_balance_algorithm.py), [unit/invoices/test_currency_conversion_imports.py](unit/invoices/test_currency_conversion_imports.py) | Algoritmos puros / subprocesos sin HTTP | + +### Infraestructura (flujo común) + +```mermaid +flowchart TB + subgraph fixtures [Fixtures conftest] + db[db_session: conexion + begin + Session] + roll[teardown: rollback + close] + celery[celery_eager autouse: memory broker] + app[app: FastAPI + process router] + client[TestClient] + end + db --> roll + celery --> app + db --> app + app --> client + subgraph inline [Monkeypatch rutas] + imp[process_invoice_task -> main_process import en db_session] + exp[process_export_invoice_task -> main_process export en db_session] + end + app --> inline +``` + +- **BD**: `TEST_DATABASE_URL` o `CORE_DATABASE_URL` o `settings.core_database_url`. Cada test corre dentro de una transacción; al terminar **no persiste** nada (rollback). +- **Celery**: sin Redis; `task_always_eager` para que el endpoint dispare lógica síncrona. +- **Seguridad en tests**: `validate_access_to_resource` se reemplaza por un stub que devuelve `tenant_id` del usuario fake. + +### Builders: qué se construye antes de llamar a la API + +Orden típico en casi todos los tests que tocan proceso: + +1. `ensure_reference_data`: tipos de factura (`TEM`, `DEF`, `MEX`, `DONAC`) y régimen `A1` si no existen. +2. `ensure_tenant_company(tenant_id=1, company_id=1)`. +3. `create_business_catalogs`: proveedor/cliente/destinatario (con dirección idempotente vía `_ensure_client_provider_address`), agente aduanal, UoM, part number FA, tipo cambio, etc. +4. `create_import_invoice_with_line` / `create_export_invoice_with_line` según el caso. + +### Parches al pipeline (import / export) + +Los tests **no** ejecutan validadores pesados del proceso real; sustituyen funciones en `main_process` para aislar el comportamiento de saldos y API: + +**Import** (varios tests): `pre_validators` devuelve la línea creada; se anulan reviews de clase, tipo de cambio, pesos, SISIMP, `_validate_lines`. + +**Export**: análogo con `pre_validators` + reviews de clase, TC, asignación, cantidad vs peso, costo, series. + +**Caso especial** — `test_process_endpoint_prevents_double_processing_import` en [integration/test_export_process_api.py](integration/test_export_process_api.py): usa `_patch_import_pipeline_without_prevalidators` (sin parchear `pre_validators`) para que el **segundo** `POST /process` recorra el flujo real y dispare la validación de “ya procesado”. + +### Mapa por archivo y edge cases + +#### E2E — [e2e/test_inventory_flow_anexo24.py](e2e/test_inventory_flow_anexo24.py) + +- **Flujo**: datos ref + tenant/company + catálogos → factura import `TEM` qty 10 → `POST .../process` → comprueba `BalanceMovement` tipo `ENTRY` → factura export ligada a import/línea qty 4 → `POST process` → comprueba `CONSUMPTION`, `DischargeHeader`, `DischargeDetail` con `movement_id`. +- **Edge implícito**: saldo neto por línea de import ≥ 0 y < 10 tras consumo parcial (no agota todo el inventario del escenario). + +#### Integración import — [integration/test_import_process_api.py](integration/test_import_process_api.py) + +| Test | Qué valida | +|------|------------| +| `test_process_import_endpoint_creates_balance_entries` | `TEM` + process → al menos un `ENTRY` por factura/línea | +| `test_process_import_def_does_not_create_balance_entries` | `DEF` + process → **ningún** movimiento de saldo (edge: tipo operación no genera entradas de balance) | + +#### Integración export + doble proceso — [integration/test_export_process_api.py](integration/test_export_process_api.py) + +| Test | Qué valida | +|------|------------| +| `_prepare_inventory` + `test_process_export_endpoint_consumes_existing_balances` | Tras import `TEM` qty 10, export qty 3 → existen `CONSUMPTION` | +| `test_process_export_prevents_negative_balance` | Export qty 99 vs saldo 10 → `ValidationException` y **cero** consumos para esa factura export | +| `test_process_endpoint_prevents_double_processing_import` | Segundo `POST` misma factura import → `ValidationException`; exactamente **un** `ENTRY` (no duplicar PEPS) | + +#### Unit saldos / FIFO — [unit/invoices/test_balance_algorithm.py](unit/invoices/test_balance_algorithm.py) + +- **`test_net_balance_accounts_for_returns_and_entry_void`**: `_net_balance_for_lot` con ENTRY, CONSUMPTION, RETURN, ENTRY_VOID (fórmula documentada en el docstring: 10 - 4 + 1 - 2 = 5). +- **`test_fifo_consumption_algorithm_uses_oldest_lots_first`**: `compare_balances` con dos `AvailableLot` (órdenes 1 y 2), demanda 6; parche `_resolve_import_uom` → PZA; comprueba consumo 3+3 y `quantity_used == 6`. + +#### Unit IVA / moneda — [unit/invoices/test_currency_conversion_imports.py](unit/invoices/test_currency_conversion_imports.py) + +- Tres monedas en `assign_values_iva_lines`: **FOREIGN (ME)**, **LOCAL (MN)**, **MANUAL (MC)** con `SimpleNamespace` (sin BD). + +### Diagrama de flujo de negocio (E2E + integración export) + +```mermaid +sequenceDiagram + participant T as Test + participant API as POST process + participant DB as Session PostgreSQL + T->>DB: seed ref + catalogs + import invoice + T->>API: process import + API->>DB: ENTRY movements + T->>DB: export invoice linked + T->>API: process export + alt qty OK + API->>DB: CONSUMPTION + discharges + else qty over balance + API-->>T: ValidationException + end +``` + +### Resumen de edge cases explícitos en la suite + +- **Tipo factura import**: `TEM` genera saldo; `DEF` no. +- **Saldo insuficiente en export**: error y sin consumos. +- **Doble procesamiento import**: error en segundo POST y una sola entrada. +- **Neteo de movimientos**: retornos y anulaciones de entrada en el cálculo de saldo. +- **FIFO**: reparto entre lotes por `order_peps`. +- **Moneda / IVA**: tres modos de captura y conversión esperada. + +### BD compartida / CI + +Si `TEST_DATABASE_URL` apunta a una base con datos previos, los builders reutilizan filas existentes donde aplica (por ejemplo direcciones de clientes vía `_ensure_client_provider_address`). Para máximo aislamiento, usar una BD o esquema dedicado a tests. + +--- + ## Prerequisites - PostgreSQL test database available.