solorpower/crawler/tests/test_time_utils.py
haneulai a716dbef96
Some checks are pending
CI / Crawler (Python ${{ matrix.python-version }}) (3.10) (push) Waiting to run
CI / Crawler (Python ${{ matrix.python-version }}) (3.11) (push) Waiting to run
CI / API (Python 3.11) (push) Waiting to run
CI / Database migration (push) Waiting to run
CI / App web build (Node 20) (push) Waiting to run
feat: harden solar monitoring through stage 7
2026-08-07 14:07:22 +09:00

85 lines
2.8 KiB
Python

import sqlite3
import sys
import tempfile
import unittest
from contextlib import closing
from datetime import date, datetime, timezone
from pathlib import Path
CRAWLER_DIR = Path(__file__).resolve().parents[1]
if str(CRAWLER_DIR) not in sys.path:
sys.path.insert(0, str(CRAWLER_DIR))
from crawler_manager import CrawlerManager
from time_utils import (
KST,
ensure_kst,
kst_day_bounds_utc,
parse_legacy_kst_datetime,
)
class TimeUtilsTest(unittest.TestCase):
def test_new_year_kst_day_uses_previous_utc_date(self):
start, end = kst_day_bounds_utc(date(2026, 1, 1))
self.assertEqual("2025-12-31T15:00:00+00:00", start.isoformat())
self.assertEqual("2026-01-01T15:00:00+00:00", end.isoformat())
def test_month_end_is_half_open_at_next_kst_midnight(self):
start, end = kst_day_bounds_utc(date(2026, 8, 31))
self.assertEqual("2026-08-30T15:00:00+00:00", start.isoformat())
self.assertEqual("2026-08-31T15:00:00+00:00", end.isoformat())
def test_legacy_naive_sqlite_datetime_is_treated_as_kst(self):
parsed = parse_legacy_kst_datetime("2026-08-06T09:00:00")
self.assertEqual(KST, parsed.tzinfo)
self.assertEqual(9, parsed.hour)
def test_aware_utc_datetime_is_converted_to_kst(self):
parsed = ensure_kst(datetime(2026, 8, 5, 15, 0, tzinfo=timezone.utc))
self.assertEqual(date(2026, 8, 6), parsed.date())
self.assertEqual(0, parsed.hour)
class CrawlerManagerTimezoneTest(unittest.TestCase):
def setUp(self):
self.temp_dir = tempfile.TemporaryDirectory()
self.current = datetime(2026, 8, 5, 19, 59, tzinfo=timezone.utc)
self.manager = CrawlerManager(
db_path=Path(self.temp_dir.name) / "crawler_manager.db",
now_provider=lambda: self.current,
)
def tearDown(self):
self.temp_dir.cleanup()
def test_night_window_uses_kst_when_host_clock_is_utc(self):
# UTC 19:59 == KST 04:59
self.assertFalse(self.manager.should_run("plant-a"))
# UTC 20:00 == KST 05:00
self.current = datetime(2026, 8, 5, 20, 0, tzinfo=timezone.utc)
self.assertTrue(self.manager.should_run("plant-a"))
def test_legacy_naive_heartbeat_value_can_be_compared(self):
self.current = datetime(2026, 8, 6, 1, 0, tzinfo=timezone.utc) # KST 10:00
self.assertTrue(self.manager.should_save("plant-a", {"kw": 10, "today": 20}))
with closing(sqlite3.connect(self.manager.db_path)) as conn:
conn.execute(
"UPDATE site_data SET updated_at = ? WHERE site_id = ?",
("2026-08-06T08:59:59", "plant-a"),
)
conn.commit()
self.assertTrue(self.manager.should_save("plant-a", {"kw": 10, "today": 20}))
if __name__ == "__main__":
unittest.main()