Commit Graph
5 Commits
Author SHA1 Message Date
flan 0a5441779a Fix produce-box select cancelling config entry setup
Validate / hassfest (push) Skipped
Validate / pytest (push) Successful in 11s
Validate / HACS (push) Skipped
async_added_to_hass listed the switchable boxes inline, one fetch per box
popup, so on a slower connection the platform setup ran past
SLOW_SETUP_MAX_WAIT and the whole config entry was cancelled into
setup_error — every entity unavailable despite valid credentials. Move the
listing to a background task so setup never blocks on it; the options fill in
once it returns.

Also bound every portal request to a 30s timeout so one hung request can no
longer drag a refresh, or a first setup, past Home Assistant's own limits and
fail it outright.

Regression covered in tests/test_setup_hygiene.py.
2026-08-04 16:04:27 +00:00
flan 73a3409353 Refactor: real mixin, shared event helper, structural tests
Validate / hassfest (push) Failing after 6s
Validate / HACS (push) Failing after 17s
Validate / pytest (push) Failing after 8s
FreshHarvestActions inherited from itself to graft on basket switching, which
is legal Python and a trap. BasketMixin now sits above it and is inherited
normally.

The four control platforms each carried an identical private _fire; it moves to
the base entity as fire_action. Rewriting those call sites mechanically broke
two of them - select fired 'donate' instead of 'change_basket', and button lost
an argument entirely, a TypeError reachable only by pressing it. Both fixed,
and two tests now assert call arity and that no class inherits from itself,
because neither fault is reachable from a unit test.
2026-08-03 20:40:17 +00:00
flan 0a218acd45 Report the item a cart action actually acted on
Validate / hassfest (push) Failing after 6s
Validate / HACS (push) Failing after 16s
Validate / pytest (push) Failing after 7s
_cart_action scraped the first .item-name off the item page, which belongs to
whatever is in the mini-cart rather than the item being added — so an add
announced someone else's groceries in its event payload. Callers pass the name
they resolved instead; verified by an add/remove round trip against a live
order.
2026-08-03 20:23:49 +00:00
flan 5e9d721a0f Add restore, and separate the produce box from add-ons
Validate / hassfest (push) Failing after 8s
Validate / HACS (push) Failing after 17s
Validate / pytest (push) Failing after 8s
Restore is POST /s/submit/restore-delivery, wired to switch.turn_off. Its
popup only exists once an order is actually skipped, which is why it could not
be found earlier; verified end to end by skipping Aug 18 and restoring it.

Fixes two bugs found while testing that. async_fetch treated popup and AJAX
fragments as full pages, so the signed-in heuristic read them as logged out and
skip could never run. And the to-do list mixed box produce with add-ons, which
would have invited deletes with no endpoint behind them: only add-ons are
add/removable, so the entity is now scoped to those.
2026-08-03 20:20:15 +00:00
flan 551d3240a2 Add control entities: box to-do list, skip switch, donate button, subscriptions
Validate / hassfest (push) Failing after 6s
Validate / pytest (push) Failing after 8s
Validate / HACS (push) Failing after 1m8s
The to-do list exists so Home Assistant's own conversation agent can manage the
order through HassListAddItem rather than through anything bespoke. Skip is a
switch because skipped/not-skipped is state worth reading back; donate is a
button because it cannot be undone. Un-skip raises rather than guessing at an
endpoint that has never been observed.

Fixes subscription parsing, which matched the heading row and so reported zero
on an account that has one.
2026-08-03 20:13:32 +00:00