fix(tests): the backup stand-ins predate kind (#3849 step 1)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 45s
CI & Build / TypeScript typecheck (push) Successful in 56s
CI & Build / Python tests (push) Successful in 1m38s
CI & Build / Build & push image (push) Successful in 48s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 45s
CI & Build / TypeScript typecheck (push) Successful in 56s
CI & Build / Python tests (push) Successful in 1m38s
CI & Build / Build & push image (push) Successful in 48s
Two unit tests build a rule with SimpleNamespace rather than the model, so adding a column broke them — the fixture has no `kind` for `_rule_rows` to read. Fixture-only; the export itself was already right, which the existing column-coverage guard confirmed by passing. Adds the guard that coverage check cannot make. `_stand_in` walks `__table__.columns` and proves the KEY is emitted; it cannot prove the VALUE survives. A preference exported as a rule is a silent failure — the restored rule reads fine and simply binds when it was only ever a preference — and a fixture carrying the default would pass against a `_rule_rows` that dropped the field and let the importer's `or "rule"` refill it. So the new test asserts on `preference`, the one value that cannot be reconstructed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011cPyzNnegXHr5iRMzzy5KJ
This commit is contained in:
@@ -388,7 +388,7 @@ def test_rule_rows_carry_the_verification_fields():
|
|||||||
row = SimpleNamespace(
|
row = SimpleNamespace(
|
||||||
id=1, topic_id=2, project_id=None, title="t", statement="s",
|
id=1, topic_id=2, project_id=None, title="t", statement="s",
|
||||||
why="w", how_to_apply="h", order_index=0,
|
why="w", how_to_apply="h", order_index=0,
|
||||||
when_to_apply="when", tier="conditional",
|
when_to_apply="when", tier="conditional", kind="rule",
|
||||||
verify_with="cat some/file", expires_when="the file grows a shell",
|
verify_with="cat some/file", expires_when="the file grows a shell",
|
||||||
verified_at=checked, arose_from_id=99,
|
verified_at=checked, arose_from_id=99,
|
||||||
created_at=checked, updated_at=checked,
|
created_at=checked, updated_at=checked,
|
||||||
@@ -415,7 +415,7 @@ def test_rule_rows_keep_an_unverified_rule_unverified():
|
|||||||
row = SimpleNamespace(
|
row = SimpleNamespace(
|
||||||
id=1, topic_id=2, project_id=None, title="t", statement="s",
|
id=1, topic_id=2, project_id=None, title="t", statement="s",
|
||||||
why=None, how_to_apply=None, order_index=0,
|
why=None, how_to_apply=None, order_index=0,
|
||||||
when_to_apply=None, tier="always_on",
|
when_to_apply=None, tier="always_on", kind="rule",
|
||||||
verify_with=None, expires_when=None, verified_at=None,
|
verify_with=None, expires_when=None, verified_at=None,
|
||||||
arose_from_id=None,
|
arose_from_id=None,
|
||||||
created_at=datetime(2026, 8, 27, tzinfo=timezone.utc),
|
created_at=datetime(2026, 8, 27, tzinfo=timezone.utc),
|
||||||
@@ -426,3 +426,27 @@ def test_rule_rows_keep_an_unverified_rule_unverified():
|
|||||||
assert backup._dt_or_none("2026-08-27T12:00:00+00:00") == datetime(
|
assert backup._dt_or_none("2026-08-27T12:00:00+00:00") == datetime(
|
||||||
2026, 8, 27, 12, 0, tzinfo=timezone.utc
|
2026, 8, 27, 12, 0, tzinfo=timezone.utc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_rule_rows_carry_the_kind_so_a_preference_does_not_restore_as_a_rule():
|
||||||
|
"""FORCE has to survive a backup, and the failure would be silent.
|
||||||
|
|
||||||
|
A preference that comes back as a rule is not a missing field anyone would
|
||||||
|
notice — the rule reads fine, it simply binds when it was only ever meant
|
||||||
|
to be how the operator prefers things done. Nothing in the restored
|
||||||
|
rulebook says it used to be softer.
|
||||||
|
|
||||||
|
Asserted with `preference` rather than `rule` on purpose: a fixture
|
||||||
|
carrying the DEFAULT would pass just as happily against a `_rule_rows`
|
||||||
|
that dropped the field entirely and let the importer's `or "rule"` fill
|
||||||
|
the hole back in, which is precisely the bug this guards.
|
||||||
|
"""
|
||||||
|
stamp = datetime(2026, 9, 10, tzinfo=timezone.utc)
|
||||||
|
row = SimpleNamespace(
|
||||||
|
id=1, topic_id=2, project_id=None, title="t", statement="s",
|
||||||
|
why=None, how_to_apply=None, order_index=0,
|
||||||
|
when_to_apply="when", tier="conditional", kind="preference",
|
||||||
|
verify_with=None, expires_when=None, verified_at=None,
|
||||||
|
arose_from_id=None, created_at=stamp, updated_at=stamp,
|
||||||
|
)
|
||||||
|
assert backup._rule_rows([row])[0]["kind"] == "preference"
|
||||||
|
|||||||
Reference in New Issue
Block a user