import pytest from sqlalchemy import select from hub_core.models.domain import Domain from hub_core.utils import PageParams, apply_pagination, normalize_trailing_slash, resolve_repo_path, slugify class RepoStub: local_path = "/fallback/path" host_paths = {"workstation": "/host/path"} def test_slugify_normalizes_text() -> None: assert slugify(" The Custodian: Hub Core! ") == "the-custodian-hub-core" def test_slugify_rejects_empty_slug() -> None: with pytest.raises(ValueError, match="slug cannot be empty"): slugify(" !!! ") def test_page_params_bounds() -> None: assert PageParams(limit=10, offset=20).limit == 10 with pytest.raises(ValueError, match="limit"): PageParams(limit=0) with pytest.raises(ValueError, match="offset"): PageParams(offset=-1) def test_apply_pagination_sets_limit_and_offset() -> None: query = apply_pagination(select(Domain), PageParams(limit=25, offset=50)) compiled = str(query.compile(compile_kwargs={"literal_binds": True})) assert "LIMIT 25" in compiled assert "OFFSET 50" in compiled def test_resolve_repo_path_prefers_host_path() -> None: repo = RepoStub() assert resolve_repo_path(repo, "workstation") == "/host/path" assert resolve_repo_path(repo, "unknown-host") == "/fallback/path" def test_normalize_trailing_slash_preserves_query_and_fragment() -> None: assert normalize_trailing_slash("/repos?status=active#top") == "/repos/?status=active#top" assert normalize_trailing_slash("/repos/?status=active", trailing=False) == "/repos?status=active"