Files
plantillas-proyectos/backend/tests
AlexeerCT 78c534df10 Add models for transportation in test configuration
Updated the test configuration file to include imports for Trailer, Transporter, and Vehicle models from the transportation module, enhancing the testing capabilities for related functionalities.
2026-04-02 08:32:08 -05:00
..

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_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 (alineado con el fixture test_tenant).

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. Fixture test_tenant: asigna IDs efímeros altos y crea tenant + company; el app usa ese tenant_id en el usuario fake.
  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 especialtest_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 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

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_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

  • 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)

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.
  • 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 literal host de los ejemplos genéricos)

Run commands

  • Fast subset (CI gate):
    • pytest -q tests/unit tests/integration
  • Full suite:
    • pytest -q tests
    • pytest tests -v -ra
    • pytest 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=True
    • task_eager_propagates=True