from __future__ import annotations import importlib.util import sys import types import unittest from datetime import datetime from pathlib import Path ROOT = Path(__file__).resolve().parents[1] MODULE_PATH = ROOT / "scripts" / "check_hubspot_connector_worker_preflight.py" if "pymysql" not in sys.modules: try: import pymysql # noqa: F401 except ModuleNotFoundError: # Predicate tests do not open a database; keep local verification # independent from the live-runner-only PyMySQL dependency. sys.modules["pymysql"] = types.ModuleType("pymysql") SPEC = importlib.util.spec_from_file_location("check_hubspot_connector_worker_preflight", MODULE_PATH) assert SPEC is not None and SPEC.loader is not None MODULE = importlib.util.module_from_spec(SPEC) sys.modules[SPEC.name] = MODULE SPEC.loader.exec_module(MODULE) class RecordingCursor: def __init__(self, queries: list[tuple[str, list[object]]]) -> None: self.queries = queries self.sql = "" def __enter__(self): return self def __exit__(self, _exc_type, _exc, _traceback) -> None: return None def execute(self, sql: str, params: list[object]) -> None: self.sql = sql self.queries.append((sql, list(params))) def fetchone(self) -> dict[str, int]: return {"active_count": 0} def fetchall(self) -> list[dict[str, object]]: return [] class RecordingConnection: def __init__(self) -> None: self.queries: list[tuple[str, list[object]]] = [] def cursor(self) -> RecordingCursor: return RecordingCursor(self.queries) class HubSpotConnectorWorkerPreflightTests(unittest.TestCase): columns = { "id": "Id", "status": "Status", "namespace": "Namespace", "createddate": "CreatedDate", } cutoff = datetime(2026, 8, 27, 7, 0, 0) def run_split(self, workitem_coverage): connection = RecordingConnection() MODULE.fetch_nonterminal_split( connection, MODULE.CONNECTOR_EVENT_TABLE, self.columns, MODULE.DEFAULT_NAMESPACE, self.cutoff, 10, workitem_coverage, ) self.assertEqual(len(connection.queries), 3) return connection.queries[0] def test_workitem_ledger_makes_coverage_the_only_event_side_blocker(self) -> None: sql, params = self.run_split({"table": MODULE.CONNECTOR_WORKITEM_TABLE}) self.assertIn("direct_work", sql) self.assertIn("projection", sql) self.assertNotIn("COALESCE(`CreatedDate`, '1970-01-01 00:00:00') >= %s", sql) self.assertNotIn("`Status` = 'processing'", sql) self.assertEqual(params, [MODULE.DEFAULT_NAMESPACE]) def test_legacy_environment_without_workitems_keeps_freshness_gate(self) -> None: sql, params = self.run_split(None) self.assertNotIn("direct_work", sql) self.assertIn("COALESCE(`CreatedDate`, '1970-01-01 00:00:00') >= %s", sql) self.assertIn("LOWER(COALESCE(`Status`, '')) = 'processing'", sql) self.assertEqual(params, [MODULE.DEFAULT_NAMESPACE, "2026-08-27 07:00:00"]) if __name__ == "__main__": unittest.main()