fix(advice): the no-token guard must cover all three shapes of "no token"
The guard matches on the absence of a token. `{"$exists": False}` covers
a reading with no token field, but NOT one whose token field is present
and empty.
Verified against the live database, before the fix:
token present but empty -> write matched: 0 <-- missed it
`{"$in": [None, ""]}` covers all three - a missing field, an empty
field, and a null one - because `$in` with null also matches a missing
field.
no token field -> write matched: 1
token present but empty -> write matched: 1
token is null -> write matched: 1
183 tests (up from 182).
This commit is contained in:
@@ -278,7 +278,10 @@ class BeerRepository:
|
||||
# Falling back to the gravity here would re-open the hole
|
||||
# this guard exists to close - a comment-only correction
|
||||
# leaves the gravity unchanged.
|
||||
query["advice_token"] = {"$exists": False}
|
||||
# `$in` with null also matches a MISSING field, so this
|
||||
# covers a reading with no token AND one whose token field
|
||||
# is present but empty.
|
||||
query["advice_token"] = {"$in": [None, ""]}
|
||||
elif expected_sg is not None:
|
||||
# A direct call with a gravity to check against.
|
||||
query["sg"] = str(expected_sg)
|
||||
|
||||
@@ -826,6 +826,33 @@ def test_a_pre_token_reading_is_still_guarded_against_a_stale_write(repo):
|
||||
assert after["comment"] == "corrected comment"
|
||||
|
||||
|
||||
def test_the_advice_is_written_for_a_reading_with_no_token_field(repo):
|
||||
"""All three shapes of "no token" must work.
|
||||
|
||||
A reading read from the database has no token at all; one written by
|
||||
an older version could have the field present but empty, or null.
|
||||
The guard matches on the absence of a token, so it has to cover all
|
||||
three - otherwise the advice is silently never written.
|
||||
"""
|
||||
for index, extra in enumerate(({}, {"advice_token": ""}, {"advice_token": None})):
|
||||
reading_id = f"noToken{index:04d}"
|
||||
repo.readings.insert_one({
|
||||
"_id": reading_id,
|
||||
"beer_run_id": str(index),
|
||||
"beer_type": "Ale",
|
||||
"sg": "1050",
|
||||
"date": "2026-01-01",
|
||||
"final_reading": "False",
|
||||
"comment": "c",
|
||||
**extra,
|
||||
})
|
||||
|
||||
written = repo.set_reading_advice(reading_id, "THE ADVICE", True,
|
||||
expected_sg=None,
|
||||
expected_token="")
|
||||
assert written == 1, f"the advice was not written for {extra!r}"
|
||||
|
||||
|
||||
def test_a_reply_cut_off_at_the_token_ceiling_is_marked(repo):
|
||||
"""A reply that stopped at the token limit is incomplete.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user