Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions app/seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ def _load_dir(subdir: Path) -> list[dict[str, Any]]:
for path in sorted(subdir.rglob("*.json")): # recurse into brand subfolders
record = json.loads(path.read_text(encoding="utf-8"))
# SQLModel table models skip validation, so coerce ISO date strings here.
if isinstance(record.get("release_date"), str):
record["release_date"] = date.fromisoformat(record["release_date"])
# Keyed on the *_date suffix rather than one field name: a category whose
# date column is not called release_date (website.launch_date) would
# otherwise reach SQLite as a str and fail the insert.
for key, value in list(record.items()):
if key.endswith("_date") and isinstance(value, str):
record[key] = date.fromisoformat(value)
items.append(record)
return items

Expand Down
55 changes: 55 additions & 0 deletions tests/unit/test_seed_date_coercion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""The seed loader must turn ISO date strings into date objects.

Regression test for a category whose date column is not named ``release_date``:
websites use ``launch_date``, and while the field-name-specific coercion was in
place such a record reached SQLite as a str and the insert failed with
"SQLite Date type only accepts Python date objects as input".

The endpoint tests insert fixtures through the model with real date objects, so
they never covered the JSON -> DB path this exercises.
"""

from __future__ import annotations

import json
from datetime import date
from pathlib import Path

from app.seed import _load_dir


def test_load_dir_coerces_any_date_suffixed_field(tmp_path: Path) -> None:
(tmp_path / "a.json").write_text(
json.dumps(
{
"slug": "example-site",
"name": "Example",
"launch_date": "2001-01-15",
"release_date": "1998-01-02",
"verified": False,
"source_urls": ["https://example.com"],
}
),
encoding="utf-8",
)

records = _load_dir(tmp_path)

assert len(records) == 1
assert records[0]["launch_date"] == date(2001, 1, 15)
assert records[0]["release_date"] == date(1998, 1, 2)


def test_load_dir_leaves_non_date_fields_alone(tmp_path: Path) -> None:
(tmp_path / "a.json").write_text(
json.dumps({"slug": "x", "name": "X", "homepage_url": "https://x.example"}),
encoding="utf-8",
)

records = _load_dir(tmp_path)

assert records[0]["homepage_url"] == "https://x.example"


def test_load_dir_missing_directory_is_empty(tmp_path: Path) -> None:
assert _load_dir(tmp_path / "nope") == []
Loading