Merge pull request 'Add detailed test flow documentation to backend tests README' (#246) from feature/testing into development
Reviewed-on: ADUANASOFT/anexo76#246
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user