- 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.
142 lines
4.2 KiB
Python
142 lines
4.2 KiB
Python
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"
|