diff --git a/rowan/project.py b/rowan/project.py index 30e1589..da5d842 100644 --- a/rowan/project.py +++ b/rowan/project.py @@ -197,8 +197,15 @@ def default_project() -> Project: Raises: httpx.HTTPStatusError: API request fails + ValueError: the user has no default project in the API key's organization """ with api_client() as client: response = client.get("/user/me/default_project") response.raise_for_status() - return Project(**response.json()) + project = response.json() + if project is None: + raise ValueError( + "You have no default project in this organization. " + "Set a default project, or pass a folder or project." + ) + return Project(**project) diff --git a/tests/test_project.py b/tests/test_project.py new file mode 100644 index 0000000..a06f4cf --- /dev/null +++ b/tests/test_project.py @@ -0,0 +1,35 @@ +"""Tests for project retrieval.""" + +from collections.abc import Iterator +from contextlib import contextmanager +from unittest.mock import MagicMock + +import pytest + +from rowan import project as project_module + + +def _mock_client(monkeypatch: pytest.MonkeyPatch, payload: dict | None) -> None: + client = MagicMock() + client.get.return_value.json.return_value = payload + + @contextmanager + def mock_api_client() -> Iterator[MagicMock]: + yield client + + monkeypatch.setattr(project_module, "api_client", mock_api_client) + + +def test_default_project_returns_the_project(monkeypatch: pytest.MonkeyPatch) -> None: + """Return the default project the API reports.""" + _mock_client(monkeypatch, {"uuid": "project-uuid", "name": "Default"}) + + assert project_module.default_project().uuid == "project-uuid" + + +def test_default_project_without_one_raises_a_clear_error(monkeypatch: pytest.MonkeyPatch) -> None: + """Explain a missing default project instead of failing to build one from null.""" + _mock_client(monkeypatch, None) + + with pytest.raises(ValueError, match="no default project"): + project_module.default_project()