feat(tv-power): implement server PR1 with tests and documentation
This commit is contained in:
106
scheduler/test_power_intent_utils.py
Normal file
106
scheduler/test_power_intent_utils.py
Normal file
@@ -0,0 +1,106 @@
|
||||
import unittest
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from scheduler.db_utils import (
|
||||
build_group_power_intent_body,
|
||||
compute_group_power_intent_basis,
|
||||
compute_group_power_intent_fingerprint,
|
||||
)
|
||||
|
||||
|
||||
class PowerIntentUtilsTests(unittest.TestCase):
|
||||
def test_no_events_results_in_off(self):
|
||||
now = datetime(2026, 3, 31, 10, 0, 0, tzinfo=timezone.utc)
|
||||
basis = compute_group_power_intent_basis(events=[], group_id=7, now_utc=now)
|
||||
|
||||
self.assertEqual(basis["group_id"], 7)
|
||||
self.assertEqual(basis["desired_state"], "off")
|
||||
self.assertEqual(basis["reason"], "no_active_event")
|
||||
self.assertIsNone(basis["event_window_start"])
|
||||
self.assertIsNone(basis["event_window_end"])
|
||||
|
||||
def test_active_event_results_in_on(self):
|
||||
now = datetime(2026, 3, 31, 10, 5, 0, tzinfo=timezone.utc)
|
||||
events = [
|
||||
{
|
||||
"id": 101,
|
||||
"group_id": 2,
|
||||
"start": "2026-03-31T10:00:00+00:00",
|
||||
"end": "2026-03-31T10:30:00+00:00",
|
||||
}
|
||||
]
|
||||
|
||||
basis = compute_group_power_intent_basis(events=events, group_id=2, now_utc=now)
|
||||
|
||||
self.assertEqual(basis["desired_state"], "on")
|
||||
self.assertEqual(basis["reason"], "active_event")
|
||||
self.assertEqual(basis["event_window_start"], "2026-03-31T10:00:00Z")
|
||||
self.assertEqual(basis["event_window_end"], "2026-03-31T10:30:00Z")
|
||||
self.assertEqual(basis["active_event_ids"], [101])
|
||||
|
||||
def test_adjacent_events_are_merged_without_off_blip(self):
|
||||
now = datetime(2026, 3, 31, 10, 30, 0, tzinfo=timezone.utc)
|
||||
events = [
|
||||
{
|
||||
"id": 1,
|
||||
"group_id": 3,
|
||||
"start": "2026-03-31T10:00:00+00:00",
|
||||
"end": "2026-03-31T10:30:00+00:00",
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"group_id": 3,
|
||||
"start": "2026-03-31T10:30:00+00:00",
|
||||
"end": "2026-03-31T11:00:00+00:00",
|
||||
},
|
||||
]
|
||||
|
||||
basis = compute_group_power_intent_basis(events=events, group_id=3, now_utc=now)
|
||||
|
||||
self.assertEqual(basis["desired_state"], "on")
|
||||
self.assertEqual(basis["event_window_start"], "2026-03-31T10:00:00Z")
|
||||
self.assertEqual(basis["event_window_end"], "2026-03-31T11:00:00Z")
|
||||
|
||||
def test_true_gap_results_in_off(self):
|
||||
now = datetime(2026, 3, 31, 10, 31, 0, tzinfo=timezone.utc)
|
||||
events = [
|
||||
{
|
||||
"id": 1,
|
||||
"group_id": 4,
|
||||
"start": "2026-03-31T10:00:00+00:00",
|
||||
"end": "2026-03-31T10:30:00+00:00",
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"group_id": 4,
|
||||
"start": "2026-03-31T10:35:00+00:00",
|
||||
"end": "2026-03-31T11:00:00+00:00",
|
||||
},
|
||||
]
|
||||
|
||||
basis = compute_group_power_intent_basis(events=events, group_id=4, now_utc=now)
|
||||
|
||||
self.assertEqual(basis["desired_state"], "off")
|
||||
self.assertEqual(basis["reason"], "no_active_event")
|
||||
|
||||
def test_fingerprint_is_stable_for_same_semantics(self):
|
||||
basis = {
|
||||
"schema_version": "1.0",
|
||||
"group_id": 9,
|
||||
"desired_state": "on",
|
||||
"reason": "active_event",
|
||||
"event_window_start": "2026-03-31T10:00:00Z",
|
||||
"event_window_end": "2026-03-31T10:30:00Z",
|
||||
"active_event_ids": [12, 7],
|
||||
}
|
||||
body_a = build_group_power_intent_body(basis, poll_interval_sec=15)
|
||||
body_b = build_group_power_intent_body(basis, poll_interval_sec=15)
|
||||
|
||||
fingerprint_a = compute_group_power_intent_fingerprint(body_a)
|
||||
fingerprint_b = compute_group_power_intent_fingerprint(body_b)
|
||||
|
||||
self.assertEqual(fingerprint_a, fingerprint_b)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user