Compare celebration stamps as whole entries; queue events
Child ids sharing a prefix no longer suppress each other (split and compare entries for equality), and queued mode keeps a second child's day-complete event from being dropped while the first notify runs.
This commit is contained in:
@@ -60,7 +60,7 @@ blueprint:
|
|||||||
filter:
|
filter:
|
||||||
- domain: input_text
|
- domain: input_text
|
||||||
|
|
||||||
mode: single
|
mode: queued
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
celebrate: !input celebrate
|
celebrate: !input celebrate
|
||||||
@@ -74,12 +74,17 @@ conditions:
|
|||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ celebrate | bool }}"
|
value_template: "{{ celebrate | bool }}"
|
||||||
# Once-per-child-per-day dedupe: celebrate only when THIS child has
|
# Once-per-child-per-day dedupe: celebrate only when THIS child has
|
||||||
# no entry for today in the helper. An unset or missing helper reads
|
# no equal entry for today in the helper. Entries compare as whole
|
||||||
# as '' and celebrates.
|
# comma-separated tokens — a substring check would wrongly suppress
|
||||||
|
# child 1 after child 11 was celebrated. An unset or missing helper
|
||||||
|
# reads as '' and celebrates.
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >-
|
value_template: >-
|
||||||
{{ (trigger.payload.child_id ~ ':' ~ now().strftime('%Y-%m-%d'))
|
{{ (trigger.payload.child_id ~ ':' ~ now().strftime('%Y-%m-%d'))
|
||||||
not in (states(last_celebrated_helper) or '') }}
|
not in ((states(last_celebrated_helper) or '')
|
||||||
|
.split(',')
|
||||||
|
| select('ne', '')
|
||||||
|
| list) }}
|
||||||
|
|
||||||
actions:
|
actions:
|
||||||
- action: !input notify_target
|
- action: !input notify_target
|
||||||
|
|||||||
@@ -256,3 +256,19 @@ def test_celebration_never_hard_codes_notify_target() -> None:
|
|||||||
"the input description should show a placeholder example"
|
"the input description should show a placeholder example"
|
||||||
)
|
)
|
||||||
assert bp["actions"][0]["action"] == BlueprintInput("notify_target")
|
assert bp["actions"][0]["action"] == BlueprintInput("notify_target")
|
||||||
|
|
||||||
|
def test_celebration_dedupe_entry_equality_not_substring() -> None:
|
||||||
|
"""Child ids sharing a prefix must not suppress each other: after
|
||||||
|
child 11 is celebrated, child 1 still celebrates (whole-entry
|
||||||
|
comparison, not substring)."""
|
||||||
|
assert render_dedupe("11:2026-09-19", child_id=11) == "False"
|
||||||
|
assert render_dedupe("11:2026-09-19", child_id=1) == "True", (
|
||||||
|
"child 1's entry must not be found inside child 11's entry"
|
||||||
|
)
|
||||||
|
assert render_dedupe("1:2026-09-19", child_id=11) == "True"
|
||||||
|
|
||||||
|
|
||||||
|
def test_celebration_mode_is_queued() -> None:
|
||||||
|
"""Two children completing at nearly the same time must both be
|
||||||
|
processed: queued mode does not drop the second event."""
|
||||||
|
assert celebration()["mode"] == "queued"
|
||||||
|
|||||||
Reference in New Issue
Block a user