feat(navigation): Enhance navigation links and add legacy route redirects
- Updated navigation links in `init_db.py` to include href overrides and parent slugs for profitability, opex, and capex planners. - Modified `NavigationService` to handle child links and href overrides, ensuring proper routing when context is missing. - Adjusted scenario detail and list templates to use new route names for opex and capex forms, with legacy fallbacks. - Introduced integration tests for legacy calculation routes to ensure proper redirection and error handling. - Added tests for navigation sidebar to validate role-based access and link visibility. - Enhanced navigation sidebar tests to include calculation links and contextual URLs based on project and scenario IDs.
This commit is contained in:
141
tests/integration/test_calculations_legacy_routes.py
Normal file
141
tests/integration/test_calculations_legacy_routes.py
Normal file
@@ -0,0 +1,141 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
def _create_project(client: TestClient, name: str) -> int:
|
||||
response = client.post(
|
||||
"/projects",
|
||||
json={
|
||||
"name": name,
|
||||
"location": "Western Australia",
|
||||
"operation_type": "open_pit",
|
||||
"description": "Legacy calculations redirect test project",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 201
|
||||
return response.json()["id"]
|
||||
|
||||
|
||||
def _create_scenario(client: TestClient, project_id: int, name: str) -> int:
|
||||
response = client.post(
|
||||
f"/projects/{project_id}/scenarios",
|
||||
json={
|
||||
"name": name,
|
||||
"description": "Scenario for legacy calculations redirect tests",
|
||||
"status": "draft",
|
||||
"currency": "usd",
|
||||
"primary_resource": "diesel",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 201
|
||||
return response.json()["id"]
|
||||
|
||||
|
||||
def test_legacy_opex_redirects_to_scenario_route(
|
||||
client: TestClient,
|
||||
scenario_calculation_url: Callable[[str, int, int], str],
|
||||
) -> None:
|
||||
project_id = _create_project(client, "Opex Legacy Redirect Project")
|
||||
scenario_id = _create_scenario(
|
||||
client, project_id, "Opex Legacy Redirect Scenario")
|
||||
|
||||
response = client.get(
|
||||
f"/calculations/opex?project_id={project_id}&scenario_id={scenario_id}",
|
||||
follow_redirects=False,
|
||||
)
|
||||
|
||||
assert response.status_code == 308
|
||||
assert response.headers["location"] == scenario_calculation_url(
|
||||
"calculations.scenario_opex_form",
|
||||
project_id,
|
||||
scenario_id,
|
||||
)
|
||||
|
||||
post_response = client.post(
|
||||
f"/calculations/opex?project_id={project_id}&scenario_id={scenario_id}",
|
||||
data={},
|
||||
follow_redirects=False,
|
||||
)
|
||||
|
||||
assert post_response.status_code == 308
|
||||
assert post_response.headers["location"] == scenario_calculation_url(
|
||||
"calculations.scenario_opex_submit",
|
||||
project_id,
|
||||
scenario_id,
|
||||
)
|
||||
|
||||
|
||||
def test_legacy_capex_redirects_to_scenario_route(
|
||||
client: TestClient,
|
||||
scenario_calculation_url: Callable[[str, int, int], str],
|
||||
) -> None:
|
||||
project_id = _create_project(client, "Capex Legacy Redirect Project")
|
||||
scenario_id = _create_scenario(
|
||||
client, project_id, "Capex Legacy Redirect Scenario")
|
||||
|
||||
response = client.get(
|
||||
f"/calculations/capex?project_id={project_id}&scenario_id={scenario_id}",
|
||||
follow_redirects=False,
|
||||
)
|
||||
|
||||
assert response.status_code == 308
|
||||
assert response.headers["location"] == scenario_calculation_url(
|
||||
"calculations.scenario_capex_form",
|
||||
project_id,
|
||||
scenario_id,
|
||||
)
|
||||
|
||||
post_response = client.post(
|
||||
f"/calculations/capex?project_id={project_id}&scenario_id={scenario_id}",
|
||||
data={},
|
||||
follow_redirects=False,
|
||||
)
|
||||
|
||||
assert post_response.status_code == 308
|
||||
assert post_response.headers["location"] == scenario_calculation_url(
|
||||
"calculations.scenario_capex_submit",
|
||||
project_id,
|
||||
scenario_id,
|
||||
)
|
||||
|
||||
|
||||
def test_legacy_opex_redirects_to_project_scenarios_when_only_project(
|
||||
client: TestClient,
|
||||
app_url_for: Callable[..., str],
|
||||
) -> None:
|
||||
project_id = _create_project(client, "Opex Legacy Project Only")
|
||||
|
||||
response = client.get(
|
||||
f"/calculations/opex?project_id={project_id}",
|
||||
follow_redirects=False,
|
||||
)
|
||||
|
||||
assert response.status_code == 303
|
||||
assert response.headers["location"] == app_url_for(
|
||||
"scenarios.project_scenario_list", project_id=project_id
|
||||
)
|
||||
|
||||
|
||||
def test_legacy_capex_rejects_invalid_identifiers(client: TestClient) -> None:
|
||||
response = client.get(
|
||||
"/calculations/capex?project_id=abc&scenario_id=-10",
|
||||
follow_redirects=False,
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
assert "project_id" in response.json()["detail"].lower()
|
||||
|
||||
|
||||
def test_legacy_opex_returns_not_found_for_missing_entities(client: TestClient) -> None:
|
||||
project_id = _create_project(client, "Opex Legacy Missing Scenario")
|
||||
|
||||
response = client.get(
|
||||
f"/calculations/opex?project_id={project_id}&scenario_id=999999",
|
||||
follow_redirects=False,
|
||||
)
|
||||
|
||||
assert response.status_code == 404
|
||||
assert response.json()["detail"] == "Scenario not found"
|
||||
Reference in New Issue
Block a user