test: cross-file stub-scoping repairs — hub ConfigFlow base carries the full plumbing, standalone rebuilds when its holder is gone, test_init scoped hygiene mirrors scoped_stubs (completes t30 G6)

This commit is contained in:
James Mackay committed 2026-10-09 07:38:24 +01:00
1 parent 80ddff313a
commit e77bc12d81
2 files changed
+40 -3

No files matched your search

+31 -1
View File
@@ -131,8 +131,38 @@ def install() -> None:
config_entries = types.ModuleType("homeassistant.config_entries")
config_entries.ConfigEntry = type("ConfigEntry", (), {})
async def _stub_set_unique_id(self, unique_id):
# hub shape: record; a full flow test file scopes its own version
self._unique_id = unique_id
def _noop_abort(self, *, error=None, **kwargs):
return None
class _ConfigFlowStub:
"""ConfigFlow shape used by flow tests (t29 G3a API included)."""
"""ConfigFlow shape used by entity tests (t29 G3a API included).
Late loads under the hub stubs (e.g. test_init designs run AFTER the
other flow files) still get the base plumbing the flow modules rely
on — show/create/abort/unique-id — so the flow classes never import
against a bare base.
"""
async_set_unique_id = _stub_set_unique_id
_abort_if_unique_id_configured = _noop_abort
def async_show_form(self, *, step_id, data_schema=None, errors=None):
return {
"type": "form",
"step_id": step_id,
"errors": dict(errors or {}),
"data_schema": data_schema,
}
def async_create_entry(self, *, title, data, options=None):
return {"type": "create_entry", "title": title, "data": data}
def async_abort(self, *, reason):
return {"type": "abort", "reason": reason}
def _get_reauth_entry(self, entry=None):
if entry is not None: