From 9a4bf4f7652dcb5677a2eaecc0e4efb07c71bb91 Mon Sep 17 00:00:00 2001 From: Joshua King Date: Mon, 14 Sep 2026 08:07:41 -0400 Subject: [PATCH] docs: correct gate comment and get_by_child cross-reference --- custom_components/nestquest/dao_presence.py | 2 +- tests/test_dao_presence.py | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/custom_components/nestquest/dao_presence.py b/custom_components/nestquest/dao_presence.py index b05fc7f..c19e821 100644 --- a/custom_components/nestquest/dao_presence.py +++ b/custom_components/nestquest/dao_presence.py @@ -11,7 +11,7 @@ Semantics per the done-condition and Feature 05: - A child has AT MOST ONE presence schedule (schema UNIQUE); upserting by child updates the existing row rather than raising. - A child with NO schedule row is present every day — the absence of a - row is meaningful state, expressed by :meth:`PresenceSchedulesDao.get` + row is meaningful state, expressed by :meth:`PresenceSchedulesDao.get_by_child` returning None, never by an empty pattern row. - Overrides beat the pattern for their date range (that resolution is the presence engine's job, Feature 05); the DAO only stores and diff --git a/tests/test_dao_presence.py b/tests/test_dao_presence.py index 022a9c4..c4d183e 100644 --- a/tests/test_dao_presence.py +++ b/tests/test_dao_presence.py @@ -166,10 +166,13 @@ def test_upsert_concurrent_same_child_serializes(tmp_path) -> None: from unittest.mock import MagicMock hass = MagicMock() - # Gate exactly ONE job: the first executor job issued after + # Gate exactly ONE job: the first _fetch_one issued after # arming, which is task A's child-existence SELECT inside its - # transaction (A holds the connection lock from that moment). - # Everything before arming (open, migrations, child create) + # transaction. The transaction's BEGIN runs first and is NOT + # gated, so when the gated fetch signals, BEGIN has executed + # and SQLite is inside the open transaction (A holds the + # connection lock from BEGIN until commit). Everything before + # arming (open, migrations, child create) # and everything after (B's jobs, A's remaining jobs, reads) # pass straight through. armed = {"active": False, "gated": False}