feat: reorder project route registration to prioritize static UI paths and add pytest coverage for navigation endpoints
This commit is contained in:
@@ -13,3 +13,4 @@
|
||||
- Delivered a new dashboard experience with `templates/dashboard.html`, dedicated styling, and a FastAPI route supplying real project/scenario metrics via repository helpers.
|
||||
- Extended repositories with count/recency utilities and added pytest coverage, including a dashboard rendering smoke test validating empty-state messaging.
|
||||
- Brought project and scenario detail pages plus their forms in line with the dashboard visuals, adding metric cards, layout grids, and refreshed CTA styles.
|
||||
- Reordered project route registration to prioritize static UI paths, eliminating 422 errors on `/projects/ui` and `/projects/create`, and added pytest smoke coverage for the navigation endpoints.
|
||||
|
||||
@@ -46,45 +46,6 @@ def create_project(
|
||||
return _to_read_model(created)
|
||||
|
||||
|
||||
@router.get("/{project_id}", response_model=ProjectRead)
|
||||
def get_project(project_id: int, uow: UnitOfWork = Depends(get_unit_of_work)) -> ProjectRead:
|
||||
try:
|
||||
project = uow.projects.get(project_id)
|
||||
except EntityNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
|
||||
return _to_read_model(project)
|
||||
|
||||
|
||||
@router.put("/{project_id}", response_model=ProjectRead)
|
||||
def update_project(
|
||||
project_id: int,
|
||||
payload: ProjectUpdate,
|
||||
uow: UnitOfWork = Depends(get_unit_of_work),
|
||||
) -> ProjectRead:
|
||||
try:
|
||||
project = uow.projects.get(project_id)
|
||||
except EntityNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
|
||||
|
||||
update_data = payload.model_dump(exclude_unset=True)
|
||||
for field, value in update_data.items():
|
||||
setattr(project, field, value)
|
||||
|
||||
uow.flush()
|
||||
return _to_read_model(project)
|
||||
|
||||
|
||||
@router.delete("/{project_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def delete_project(project_id: int, uow: UnitOfWork = Depends(get_unit_of_work)) -> None:
|
||||
try:
|
||||
uow.projects.delete(project_id)
|
||||
except EntityNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@router.get(
|
||||
"/ui",
|
||||
response_class=HTMLResponse,
|
||||
@@ -188,6 +149,48 @@ def create_project_submit(
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{project_id}", response_model=ProjectRead)
|
||||
def get_project(project_id: int, uow: UnitOfWork = Depends(get_unit_of_work)) -> ProjectRead:
|
||||
try:
|
||||
project = uow.projects.get(project_id)
|
||||
except EntityNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)
|
||||
) from exc
|
||||
return _to_read_model(project)
|
||||
|
||||
|
||||
@router.put("/{project_id}", response_model=ProjectRead)
|
||||
def update_project(
|
||||
project_id: int,
|
||||
payload: ProjectUpdate,
|
||||
uow: UnitOfWork = Depends(get_unit_of_work),
|
||||
) -> ProjectRead:
|
||||
try:
|
||||
project = uow.projects.get(project_id)
|
||||
except EntityNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)
|
||||
) from exc
|
||||
|
||||
update_data = payload.model_dump(exclude_unset=True)
|
||||
for field, value in update_data.items():
|
||||
setattr(project, field, value)
|
||||
|
||||
uow.flush()
|
||||
return _to_read_model(project)
|
||||
|
||||
|
||||
@router.delete("/{project_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def delete_project(project_id: int, uow: UnitOfWork = Depends(get_unit_of_work)) -> None:
|
||||
try:
|
||||
uow.projects.delete(project_id)
|
||||
except EntityNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)
|
||||
) from exc
|
||||
|
||||
|
||||
@router.get(
|
||||
"/{project_id}/view",
|
||||
response_class=HTMLResponse,
|
||||
|
||||
@@ -71,3 +71,15 @@ class TestDashboardRoute:
|
||||
assert "No simulation runs yet" in html
|
||||
assert "All scenarios look good" in html
|
||||
assert "—" in html # Last data import placeholder
|
||||
|
||||
|
||||
class TestProjectUIRoutes:
|
||||
def test_projects_ui_page_resolves(self, client: TestClient) -> None:
|
||||
response = client.get("/projects/ui")
|
||||
assert response.status_code == 200
|
||||
assert "Projects" in response.text
|
||||
|
||||
def test_projects_create_form_resolves(self, client: TestClient) -> None:
|
||||
response = client.get("/projects/create")
|
||||
assert response.status_code == 200
|
||||
assert "Create Project" in response.text
|
||||
|
||||
Reference in New Issue
Block a user