The scheduler.py already supported "daily HH:MM,HH:MM,HH:MM" format
(commit 5f27d05), but config.py validation regex only accepted single
time "daily HH:MM", causing data-refresh to crash on startup.
Also adds:
- tests/test_config_sync_schedule.py (16 test cases)
- Makefile with validate-config target for CI/CD integration
103 lines
3.3 KiB
Python
103 lines
3.3 KiB
Python
"""Tests for TableConfig.sync_schedule field validation."""
|
|
|
|
import pytest
|
|
|
|
from src.config import TableConfig
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Helpers
|
|
# ---------------------------------------------------------------------------
|
|
def _make_table(**overrides) -> TableConfig:
|
|
"""Create a TableConfig with sensible defaults, applying overrides."""
|
|
defaults = dict(
|
|
id="test.dataset.table",
|
|
name="test_table",
|
|
description="Test",
|
|
primary_key="id",
|
|
sync_strategy="full_refresh",
|
|
)
|
|
defaults.update(overrides)
|
|
return TableConfig(**defaults)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Tests
|
|
# ---------------------------------------------------------------------------
|
|
class TestSyncScheduleDefault:
|
|
def test_default_is_none(self):
|
|
table = _make_table()
|
|
assert table.sync_schedule is None
|
|
|
|
|
|
class TestSyncScheduleValidValues:
|
|
@pytest.mark.parametrize(
|
|
"schedule",
|
|
[
|
|
"every 15m",
|
|
"every 1h",
|
|
"daily 05:00",
|
|
"daily 07:00,13:00,18:00",
|
|
"daily 00:00,12:00",
|
|
],
|
|
ids=[
|
|
"every-15m",
|
|
"every-1h",
|
|
"daily-single",
|
|
"daily-three-times",
|
|
"daily-two-times",
|
|
],
|
|
)
|
|
def test_valid_schedule_accepted(self, schedule: str):
|
|
table = _make_table(sync_schedule=schedule)
|
|
assert table.sync_schedule == schedule
|
|
|
|
|
|
class TestSyncScheduleEdgeCases:
|
|
def test_every_zero_minutes(self):
|
|
"""every 0m matches the regex -- validation is syntactic, not semantic."""
|
|
table = _make_table(sync_schedule="every 0m")
|
|
assert table.sync_schedule == "every 0m"
|
|
|
|
def test_daily_2359(self):
|
|
table = _make_table(sync_schedule="daily 23:59")
|
|
assert table.sync_schedule == "daily 23:59"
|
|
|
|
|
|
class TestSyncScheduleInvalid:
|
|
@pytest.mark.parametrize(
|
|
"bad_schedule",
|
|
[
|
|
"daily 07:00,13:00,18:00,", # trailing comma
|
|
"daily 7:00", # single-digit hour
|
|
"daily", # missing time
|
|
"hourly", # unsupported keyword
|
|
"weekly", # unsupported keyword
|
|
],
|
|
ids=[
|
|
"trailing-comma",
|
|
"single-digit-hour",
|
|
"daily-no-time",
|
|
"hourly-keyword",
|
|
"weekly-keyword",
|
|
],
|
|
)
|
|
def test_invalid_schedule_raises(self, bad_schedule: str):
|
|
with pytest.raises(ValueError, match="Invalid sync_schedule"):
|
|
_make_table(sync_schedule=bad_schedule)
|
|
|
|
def test_empty_string_treated_as_none(self):
|
|
"""Empty string is falsy, so validation is skipped (same as None)."""
|
|
table = _make_table(sync_schedule="")
|
|
assert table.sync_schedule == ""
|
|
|
|
def test_daily_25_accepted_by_regex(self):
|
|
"""25:00 passes regex validation (two digits). Document this behavior."""
|
|
table = _make_table(sync_schedule="daily 25:00")
|
|
assert table.sync_schedule == "daily 25:00"
|
|
|
|
|
|
class TestSyncScheduleNoneExplicit:
|
|
def test_explicit_none_accepted(self):
|
|
table = _make_table(sync_schedule=None)
|
|
assert table.sync_schedule is None
|