[ADD] website_sale_aplicoop: restore the test coverage lost with the dead code
The dead-code cleanup dropped 11 test files that were never wired into tests/__init__.py. Reviewing what they covered turned up real holes, so the worthwhile ones come back, rewritten against the current schema. Blacklists were the serious gap: product, supplier and category exclusions have absolute priority over product discovery and nothing exercised them. The old file had two separate defects. Its supplier fixtures wrote `main_seller_id` directly, but product_main_seller computes that field from `variant_seller_ids`, so the compute reset it to False and the blacklist had nothing to exclude; they now create real supplierinfo records. Worse, four whole classes asserted against `group_order.product_ids` -- the m2m *input* -- instead of the discovery result, so they set `category_ids` and then checked a field they never touched. Those go through `_get_products_for_group_order` now, and three tests that had no assertions at all got some. The remaining three failures were test bugs too, all Odoo 17->18 leftovers: * Date cases assumed `pickup_date` derives from `start_date`. The chain is cutoff -> pickup -> delivery, and a recurring order whose start date has passed rolls forward to the current cycle, so a 2024 order has no 2024 pickup. The new file anchors on future dates and finds the next 29 February dynamically, with a class documenting the roll-forward itself. * `/eskaera/labels` is `type="json"`; the old test hit it with a plain GET and read the resulting 400 as a bug. It is called over JSON-RPC now, and a test pins the 400 so nobody repeats it. Also `uom.uom.categ` -> `uom.category`. * `price_include` is computed in 18.0, so fixtures must set `price_include_override`. On top of that `_get_price` filters taxes by company and defaults to `env.company`, not the fixture's, which left the tax list empty -- `tax_included` was False for the wrong reason. Two of the portal tests were passing for the wrong reason as well: the access guard bounced them to /eskaera, which also answers 200. Membership has to be set from the member side with `is_group`, and a new test checks the final URL rather than the status alone. Each fixture that can silently build the wrong thing now carries a guard test. Left out on purpose: three files were unimplemented placeholders, and test_draft_persistence still deserves recovering (see the notes file). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
3eb79e2431
commit
3e4bd5e5db
6 changed files with 1817 additions and 0 deletions
147
website_sale_aplicoop/COBERTURA_TESTS_PENDIENTE.md
Normal file
147
website_sale_aplicoop/COBERTURA_TESTS_PENDIENTE.md
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
# Cobertura de tests — website_sale_aplicoop
|
||||
|
||||
Estado tras recuperar y reescribir los tests que se habían perdido con la limpieza
|
||||
de código muerto (commit `b3999e2`).
|
||||
|
||||
La suite quedó en verde y creció en unos 90 tests respecto a los 270 que había
|
||||
tras la limpieza.
|
||||
|
||||
Los ficheros originales, si alguna vez hacen falta:
|
||||
|
||||
```bash
|
||||
git show b3999e2^:website_sale_aplicoop/tests/<fichero>.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recuperado y arreglado
|
||||
|
||||
### 1. `test_product_discovery.py` — blacklists y descubrimiento (46 tests)
|
||||
|
||||
Era el hueco grave: **ningún test cubría las tres blacklists**, que son lógica viva
|
||||
con "prioridad absoluta" sobre el descubrimiento
|
||||
([group_order.py:571-627](models/group_order.py#L571-L627)).
|
||||
|
||||
Dos bugs distintos en el fichero original:
|
||||
|
||||
- **`TestSupplierBlacklist` (6 fallos)**: el fixture escribía `main_seller_id` en el
|
||||
`create` del template, pero en el addon OCA `product_main_seller` ese campo es
|
||||
*computed + store* derivado de `variant_seller_ids` — el compute lo pisaba a `False`,
|
||||
los productos quedaban sin proveedor principal y la blacklist no tenía nada que
|
||||
excluir. Arreglado creando `product.supplierinfo` de verdad, más un test-guarda
|
||||
(`test_main_seller_is_computed_from_supplierinfo`) para que no vuelva a pasar en
|
||||
silencio.
|
||||
- **Cuatro clases enteras no probaban el descubrimiento**: hacían aserciones contra
|
||||
`group_order.product_ids`, que es el campo m2m de *entrada*, no el resultado. Es
|
||||
decir, asignaban `category_ids` y comprobaban `product_ids`, así que sólo podían
|
||||
fallar; y algunas "pasaban" por el motivo equivocado (el campo estaba vacío de
|
||||
todos modos). Tres tests no tenían ni una aserción. Todo reescrito contra
|
||||
`_get_products_for_group_order`.
|
||||
|
||||
Añadido de paso: productos archivados, pedido sin ninguna fuente, id inexistente, y
|
||||
el contrato de ordenación real (`is_out_of_stock`, `website_sequence`, nombre).
|
||||
|
||||
### 2. `test_date_edge_cases.py` — calendario (12 tests)
|
||||
|
||||
Sustituye al antiguo `test_edge_cases.py`. Los 4 fallos que había eran **del test**,
|
||||
no de producción: daban por hecho que `pickup_date` se calcula desde `start_date`,
|
||||
cuando en realidad la cadena es `cutoff_date` → `pickup_date` → `delivery_date`, y
|
||||
para un pedido recurrente con `start_date` pasada la referencia pasa a ser **hoy**
|
||||
(el ciclo avanza al actual). Un pedido de 2024 no tiene fecha de recogida en 2024.
|
||||
|
||||
Los nuevos anclan en fechas **futuras** para que el avance de ciclo no mueva el caso
|
||||
bajo los pies, y buscan el próximo 29-F dinámicamente (no hay fechas quemadas que
|
||||
caduquen). Cubren: recogida justo en 29-F, ciclo que cruza el 29-F, entrega el 1-M,
|
||||
cruce de mes y de año, último día de mes, rejilla mensual desde un ancla de 31-E y
|
||||
en febrero bisiesto. `TestRollForwardBehaviour` documenta el avance de ciclo, que es
|
||||
justo lo que el test viejo malinterpretaba.
|
||||
|
||||
### 3. `test_portal_routes.py` — humo HTTP con usuario portal (8 tests)
|
||||
|
||||
Une los tres ficheros portal borrados. Los fallos eran del test:
|
||||
|
||||
- **`/eskaera/labels` devolvía 400**: la ruta es `type="json"` y el test la llamaba
|
||||
con un GET plano. Odoo responde 400 correctamente. Ahora se llama por JSON-RPC
|
||||
(`make_jsonrpc_request`), y hay un test que fija ese 400 del GET para que nadie
|
||||
repita el error.
|
||||
- **`uom.uom.categ` no existe** en Odoo 18 (es `uom.category`), y `factor_inv` →
|
||||
`factor`.
|
||||
- **La afiliación al grupo no se aplicaba**: hay que poner `is_group=True` en el
|
||||
grupo y asignar `group_ids` desde el *miembro* (es el idioma que usa
|
||||
`test_record_rules.py`). Sin eso el guard rebotaba a `/eskaera`.
|
||||
|
||||
Ojo con esto último: el smoke test original sólo miraba `status_code == 200`, y el
|
||||
rebote a la lista **también** devuelve 200 — pasaba sin que el socio entrase nunca a
|
||||
la tienda. Añadido `test_shop_page_is_not_bounced_to_the_list`, que comprueba la URL
|
||||
final.
|
||||
|
||||
### 4. `test_price_with_taxes_included.py` — impuestos (14 tests)
|
||||
|
||||
Dos causas, ambas del test:
|
||||
|
||||
- **`price_include` es computed en Odoo 18**, derivado de `price_include_override`
|
||||
(Selection `tax_included`/`tax_excluded`). El fixture escribía `price_include=True`
|
||||
y se descartaba en silencio. Añadido `test_price_include_is_driven_by_the_override`
|
||||
como guarda.
|
||||
- **`_get_price` filtra los impuestos por compañía**, y su parámetro `company` cae
|
||||
por defecto en `self.env.company`. Como el fixture crea una compañía propia, la
|
||||
lista de impuestos salía **vacía** y `tax_included` era siempre `False`. Nótese que
|
||||
`test_oca_get_price_returns_base_without_tax` pasaba por este motivo equivocado.
|
||||
Ahora todas las llamadas van por un helper que pasa `company=self.company`.
|
||||
|
||||
---
|
||||
|
||||
## Sin recuperar (no había nada que rescatar)
|
||||
|
||||
Tres ficheros eran plantillas sin implementar — setUp seguido de métodos con
|
||||
`# Placeholder: will be implemented...` y cero aserciones, o aserciones sobre
|
||||
diccionarios simulados en vez de llamar al controlador:
|
||||
|
||||
- `test_endpoints.py`
|
||||
- `test_helper_methods_phase1.py`
|
||||
- `test_phase2_eskaera_shop.py`
|
||||
|
||||
---
|
||||
|
||||
## Pendiente
|
||||
|
||||
### `test_draft_persistence.py` — persistencia de borradores
|
||||
|
||||
Lo único de los 11 ficheros que aún no se ha rehecho. Cubría casos que hoy no cubre
|
||||
nadie (`test_save_order_endpoints.py` y `test_group_order_status_endpoint.py` cubren
|
||||
el guardado y el ciclo, no esto):
|
||||
|
||||
- **el precio del borrador es una foto fija**: cambiar `list_price` después no altera
|
||||
el borrador ya guardado. El más valioso — es una garantía de negocio real (al socio
|
||||
se le respeta el precio que vio) y ahora mismo nada la protege.
|
||||
- borrador con producto archivado después de guardarlo
|
||||
- borrador de un pedido ya cerrado / de hace 6 meses
|
||||
- un borrador no es visible para otro usuario
|
||||
- recuento de borradores por usuario
|
||||
|
||||
Sólo 2 de sus 14 tests fallaban, así que la recuperación debería ser barata.
|
||||
|
||||
### Huecos menores
|
||||
|
||||
- Transiciones de estado **ilegales** (draft→closed, cancelled→open). La suite cubre
|
||||
las legales en `test_group_order.py`.
|
||||
- `available_products_count` fuera del contexto de blacklists (dentro de ellas ya
|
||||
está cubierto).
|
||||
|
||||
Nota: las constraints `_check_company_groups` y `_check_dates` **sí** están cubiertas
|
||||
(`test_multi_company.py:147`, `test_group_order.py:66`) — no son hueco.
|
||||
|
||||
---
|
||||
|
||||
## Conclusión sobre los "posibles bugs de producción"
|
||||
|
||||
Los tres que quedaron marcados para investigar (fechas 29-F, `/eskaera/labels` 400,
|
||||
`tax_included`) resultaron ser **todos bugs de los tests**, en su mayoría restos de la
|
||||
migración 17→18: `is_supplier`, `main_seller_id`, `uom.uom.categ`, `factor_inv`,
|
||||
`price_include`. No apareció ningún bug de producción.
|
||||
|
||||
Lo que sí apareció, y es más incómodo, son **tests que pasaban por el motivo
|
||||
equivocado** — el smoke test del portal que se conformaba con el rebote, y
|
||||
`test_oca_get_price_returns_base_without_tax` que verificaba `tax_included == False`
|
||||
sobre una lista de impuestos vacía. Por eso cada arreglo lleva ahora un test-guarda
|
||||
que falla si el fixture deja de construir lo que dice construir.
|
||||
Loading…
Add table
Add a link
Reference in a new issue