# 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/.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.