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>
6.8 KiB
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:
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).
Dos bugs distintos en el fichero original:
TestSupplierBlacklist(6 fallos): el fixture escribíamain_seller_iden elcreatedel template, pero en el addon OCAproduct_main_sellerese campo es computed + store derivado devariant_seller_ids— el compute lo pisaba aFalse, los productos quedaban sin proveedor principal y la blacklist no tenía nada que excluir. Arreglado creandoproduct.supplierinfode 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, asignabancategory_idsy comprobabanproduct_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/labelsdevolvía 400: la ruta estype="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.categno existe en Odoo 18 (esuom.category), yfactor_inv→factor.- La afiliación al grupo no se aplicaba: hay que poner
is_group=Trueen el grupo y asignargroup_idsdesde el miembro (es el idioma que usatest_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_includees computed en Odoo 18, derivado deprice_include_override(Selectiontax_included/tax_excluded). El fixture escribíaprice_include=Truey se descartaba en silencio. Añadidotest_price_include_is_driven_by_the_overridecomo guarda._get_pricefiltra los impuestos por compañía, y su parámetrocompanycae por defecto enself.env.company. Como el fixture crea una compañía propia, la lista de impuestos salía vacía ytax_includedera siempreFalse. Nótese quetest_oca_get_price_returns_base_without_taxpasaba por este motivo equivocado. Ahora todas las llamadas van por un helper que pasacompany=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.pytest_helper_methods_phase1.pytest_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_pricedespué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_countfuera 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.