- Added a new function to reject documentation placeholder hosts in database URLs, improving error handling for misconfigurations. - Updated the `get_database_url` function to incorporate this new validation, ensuring that users are alerted when using "host" as a placeholder. - Enhanced error messages to provide clearer guidance on valid host configurations. These changes aim to improve the robustness and clarity of database connection handling in the application.
Backend test strategy (Anexo24)
Test suites
tests/e2e/: full business flow (catalogs -> import -> export -> balances/discharges).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 | 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 | Catálogos, tenant/company, facturas import/export con líneas enlazadas |
| E2E | e2e/test_inventory_flow_anexo24.py | Flujo negocio completo import → export → saldos/descargas |
| Integración | integration/test_import_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_currency_conversion_imports.py | Algoritmos puros / subprocesos sin HTTP |
Infraestructura (flujo común)
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_URLoCORE_DATABASE_URLosettings.core_database_url. Cada test corre dentro de una transacción; al terminar no persiste nada (rollback). - Celery: sin Redis;
task_always_eagerpara que el endpoint dispare lógica síncrona. - Seguridad en tests:
validate_access_to_resourcese reemplaza por un stub que devuelvetenant_iddel usuario fake.
Builders: qué se construye antes de llamar a la API
Orden típico en casi todos los tests que tocan proceso:
ensure_reference_data: tipos de factura (TEM,DEF,MEX,DONAC) y régimenA1si no existen.ensure_tenant_company(tenant_id=1, company_id=1).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.create_import_invoice_with_line/create_export_invoice_with_linesegú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: 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
- Flujo: datos ref + tenant/company + catálogos → factura import
TEMqty 10 →POST .../process→ compruebaBalanceMovementtipoENTRY→ factura export ligada a import/línea qty 4 →POST process→ compruebaCONSUMPTION,DischargeHeader,DischargeDetailconmovement_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
| 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
| 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
test_net_balance_accounts_for_returns_and_entry_void:_net_balance_for_lotcon 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_balancescon dosAvailableLot(órdenes 1 y 2), demanda 6; parche_resolve_import_uom→ PZA; comprueba consumo 3+3 yquantity_used == 6.
Unit IVA / moneda — unit/invoices/test_currency_conversion_imports.py
- Tres monedas en
assign_values_iva_lines: FOREIGN (ME), LOCAL (MN), MANUAL (MC) conSimpleNamespace(sin BD).
Diagrama de flujo de negocio (E2E + integración export)
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:
TEMgenera saldo;DEFno. - 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.
- Environment variable:
TEST_DATABASE_URL=postgresql://user:pass@127.0.0.1:5432/db_name(sustituye por el host real alcanzable desde el runner; no uses el literalhostde los ejemplos genéricos)
Run commands
- Fast subset (CI gate):
pytest -q tests/unit tests/integration
- Full suite:
pytest -q testspytest tests -v -rapytest tests -v -ra -s
- E2E only:
pytest -q tests/e2e
CI recommendations
- Pull request gate:
- Run unit + integration on every PR.
- Nightly / main branch:
- Run full suite including E2E.
- Keep Celery eager mode for deterministic process endpoint tests:
task_always_eager=Truetask_eager_propagates=True