fix: enforce integer storage and weekday_set validation in schema

This commit is contained in:
Joshua King
2026-09-13 21:48:23 -04:00
parent 8e0baaa5d9
commit ebf4b876a5
2 changed files with 179 additions and 10 deletions
+136
View File
@@ -303,6 +303,33 @@ def test_children_is_active_check_enforced(tmp_path) -> None:
_run(database.close())
@pytest.mark.parametrize(
("column", "bad_value"),
[
("sort_order", "abc"),
("sort_order", 1.5),
("is_active", "abc"),
("is_active", 1.5),
],
)
def test_children_integer_columns_reject_text_and_fraction(
tmp_path, column, bad_value
) -> None:
database = _open_db(tmp_path / f"children-{column}-typeof.db")
try:
_apply(database)
with pytest.raises(sqlite3.IntegrityError, match="CHECK"):
_run(
database.execute(
f"INSERT INTO children (display_name, {column}, created_at) "
"VALUES (?, ?, ?)",
("Ada", bad_value, "2026-09-13T00:00:00+00:00"),
)
)
finally:
_run(database.close())
def test_children_created_at_not_null_enforced(tmp_path) -> None:
database = _open_db(tmp_path / "created-at.db")
try:
@@ -488,6 +515,93 @@ def test_schedule_rules_interval_zero_fails(tmp_path) -> None:
_run(database.close())
@pytest.mark.parametrize("bad_interval", ["abc", 1.5])
def test_schedule_rules_interval_non_integer_fails(
tmp_path, bad_interval
) -> None:
database = _open_db(tmp_path / f"interval-{type(bad_interval).__name__}.db")
try:
_apply(database)
with pytest.raises(sqlite3.IntegrityError, match="CHECK"):
_insert_rule(database, interval=bad_interval)
finally:
_run(database.close())
def test_schedule_rules_interval_integer_one_succeeds(tmp_path) -> None:
database = _open_db(tmp_path / "interval-one.db")
try:
_apply(database)
rule_id = _insert_rule(database, interval=1)
row = _run(
database.fetch_one(
"SELECT interval FROM schedule_rules WHERE id = ?", (rule_id,)
)
)
assert row == (1,)
finally:
_run(database.close())
@pytest.mark.parametrize(
("column", "bad_value"),
[
("day_of_month", "abc"),
("day_of_month", 1.5),
("nth_weekday", "abc"),
("nth_weekday", 1.5),
("month", "abc"),
("month", 1.5),
],
)
def test_schedule_rules_integer_columns_reject_text_and_fraction(
tmp_path, column, bad_value
) -> None:
database = _open_db(tmp_path / f"{column}-typeof.db")
try:
_apply(database)
overrides: dict[str, object] = {"rule_type": "monthly", "weekday_set": None}
overrides[column] = bad_value
with pytest.raises(sqlite3.IntegrityError, match="CHECK"):
_insert_rule(database, **overrides)
finally:
_run(database.close())
@pytest.mark.parametrize(
"bad_weekday_set",
["", "x", "7", "0,x", "0,8", "0,", "0,1,2,3,4,5,6,0"],
)
def test_schedule_rules_weekday_set_invalid_csv_fails(
tmp_path, bad_weekday_set
) -> None:
database = _open_db(tmp_path / "weekday-set-invalid.db")
try:
_apply(database)
with pytest.raises(sqlite3.IntegrityError, match="CHECK"):
_insert_rule(database, weekday_set=bad_weekday_set)
finally:
_run(database.close())
@pytest.mark.parametrize("weekday_set", ["0", "6", "0,1,2,3,4,5,6"])
def test_schedule_rules_weekday_set_valid_csv_succeeds(
tmp_path, weekday_set
) -> None:
database = _open_db(tmp_path / "weekday-set-valid.db")
try:
_apply(database)
rule_id = _insert_rule(database, weekday_set=weekday_set)
row = _run(
database.fetch_one(
"SELECT weekday_set FROM schedule_rules WHERE id = ?", (rule_id,)
)
)
assert row == (weekday_set,)
finally:
_run(database.close())
def test_schedule_rules_day_of_month_out_of_range_fails(tmp_path) -> None:
database = _open_db(tmp_path / "day-of-month.db")
try:
@@ -705,6 +819,28 @@ def test_task_definitions_is_active_check_enforced(tmp_path) -> None:
_run(database.close())
@pytest.mark.parametrize("bad_is_active", ["abc", 1.5])
def test_task_definitions_is_active_non_integer_fails(
tmp_path, bad_is_active
) -> None:
database = _open_db(tmp_path / "definitions-is-active-typeof.db")
try:
_apply(database)
_run(
database.execute(
"INSERT INTO children (display_name, created_at) VALUES (?, ?)",
("Ada", "2026-09-13T00:00:00+00:00"),
)
)
_insert_rule(database)
with pytest.raises(sqlite3.IntegrityError, match="CHECK"):
_insert_definition(
database, child_id=1, rule_id=1, is_active=bad_is_active
)
finally:
_run(database.close())
def test_task_definitions_title_not_null_enforced(tmp_path) -> None:
database = _open_db(tmp_path / "definitions-title.db")
try: