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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ dynamic = ["version"]
dependencies = [
"fastapi",
"fmu-datamodels",
"fmu-settings>=0.26.0",
"fmu-settings>=0.28.0",
"httpx",
"packaging",
"pydantic",
Expand Down
30 changes: 28 additions & 2 deletions src/fmu_settings_api/v1/routes/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
from fmu.datamodels.fmu_results.fields import Model
from fmu.settings import CacheResource, ProjectFMUDirectory
from fmu.settings._global_config import InvalidGlobalConfigurationError
from fmu.settings._init import (
REQUIRED_FMU_PROJECT_SUBDIRS,
InvalidFMUProjectPathError,
)
from fmu.settings.models.change_info import ChangeInfo
from fmu.settings.models.diff import ResourceDiff
from fmu.settings.models.log import Log
Expand Down Expand Up @@ -60,6 +64,9 @@
)

router = APIRouter(prefix="/project", tags=["project"])
REQUIRED_PROJECT_DIRS_TEXT = ", ".join(
f"'{dir_name}'" for dir_name in REQUIRED_FMU_PROJECT_SUBDIRS
)

ProjectResponses: Final[Responses] = {
**inline_add_response(
Expand Down Expand Up @@ -104,6 +111,24 @@
),
}

ProjectInitResponses: Final[Responses] = {
**ProjectResponses,
**ProjectExistsResponses,
**inline_add_response(
422,
"The requested path exists but is not a valid FMU project root.",
[
{
"detail": (
"Failed initializing .fmu directory. Initialize it from a "
f"project root containing {REQUIRED_PROJECT_DIRS_TEXT}. "
"Did not find: {missing_project_dirs}."
),
},
],
),
}

LockConflictResponses: Final[Responses] = {
**inline_add_response(
423,
Expand Down Expand Up @@ -481,8 +506,7 @@ async def post_project(
),
responses={
**GetSessionResponses,
**ProjectResponses,
**ProjectExistsResponses,
**ProjectInitResponses,
},
)
async def post_init_project(
Expand All @@ -504,6 +528,8 @@ async def post_init_project(
raise HTTPException(
status_code=404, detail=f"Path {path} does not exist"
) from e
except InvalidFMUProjectPathError as e:
raise HTTPException(status_code=422, detail=str(e)) from e
except FileExistsError as e:
raise HTTPException(
status_code=409, detail=f".fmu already exists at {path}"
Expand Down
44 changes: 40 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
)
from fmu.settings import ProjectFMUDirectory
from fmu.settings._fmu_dir import UserFMUDirectory
from fmu.settings._init import init_fmu_directory, init_user_fmu_directory
from fmu.settings._init import (
REQUIRED_FMU_PROJECT_SUBDIRS,
init_fmu_directory,
init_user_fmu_directory,
)
from pytest import MonkeyPatch

from fmu_settings_api.__main__ import app
Expand All @@ -29,6 +33,31 @@
from fmu_settings_api.session import SessionManager, add_fmu_project_to_session


@pytest.fixture
def make_fmu_project_root() -> Callable[[Path], Path]:
"""Return a helper that prepares a valid FMU project root for a test path."""

def _make_fmu_project_root(path: Path) -> Path:
path.mkdir(parents=True, exist_ok=True)
for dir_name in REQUIRED_FMU_PROJECT_SUBDIRS:
(path / dir_name).mkdir(parents=True, exist_ok=True)
return path

return _make_fmu_project_root


@pytest.fixture
def init_project_fmu_directory(
make_fmu_project_root: Callable[[Path], Path],
) -> Callable[[Path], ProjectFMUDirectory]:
"""Return a helper that initializes a valid project .fmu directory."""

def _init_project_fmu_directory(path: Path) -> ProjectFMUDirectory:
return init_fmu_directory(make_fmu_project_root(path))

return _init_project_fmu_directory


@pytest.fixture
def create_stratigraphic_unit() -> Callable[..., StratigraphicUnit]:
"""Fixture that returns a helper function to create StratigraphicUnit.
Expand Down Expand Up @@ -153,9 +182,11 @@ def mock_token() -> str:


@pytest.fixture
def fmu_dir(tmp_path: Path) -> ProjectFMUDirectory:
def fmu_dir(
tmp_path: Path, make_fmu_project_root: Callable[[Path], Path]
) -> ProjectFMUDirectory:
"""Creates a .fmu directory in a tmp path."""
return init_fmu_directory(tmp_path)
return init_fmu_directory(make_fmu_project_root(tmp_path))


@pytest.fixture
Expand Down Expand Up @@ -193,7 +224,11 @@ def user_fmu_dir_no_permissions(fmu_dir_path: Path) -> Generator[Path]:


@pytest.fixture
def tmp_path_mocked_home(tmp_path: Path, monkeypatch: MonkeyPatch) -> Generator[Path]:
def tmp_path_mocked_home(
tmp_path: Path,
monkeypatch: MonkeyPatch,
make_fmu_project_root: Callable[[Path], Path],
) -> Generator[Path]:
"""Mocks Path.home() for routes that depend on UserFMUDirectory.

This mocks the user .fmu into tmp_path/home/.fmu.
Expand All @@ -203,6 +238,7 @@ def tmp_path_mocked_home(tmp_path: Path, monkeypatch: MonkeyPatch) -> Generator[
"""
mocked_user_home = tmp_path / "home"
mocked_user_home.mkdir()
make_fmu_project_root(tmp_path)
with patch("pathlib.Path.home", return_value=mocked_user_home):
monkeypatch.chdir(tmp_path)
yield tmp_path
Expand Down
Loading
Loading