Enhance testing framework and UI feedback
- Updated architecture documentation to include details on UI rendering checks and Playwright end-to-end tests. - Revised testing documentation to specify Playwright for frontend E2E tests and added details on running tests. - Implemented feedback mechanism in scenario form for successful creation notifications. - Added feedback div in ScenarioForm.html for user notifications. - Created new fixtures for Playwright tests to manage server and browser instances. - Developed comprehensive E2E tests for consumption, costs, equipment, maintenance, production, and scenarios. - Added smoke tests to verify UI page loading and form submissions. - Enhanced unit tests for simulation and validation, including new tests for report generation and validation errors. - Created new test files for router validation to ensure consistent error handling. - Established a new test suite for UI routes to validate dashboard and reporting functionalities. - Implemented validation tests to ensure proper handling of JSON payloads.
This commit is contained in:
100
tests/unit/test_ui_routes.py
Normal file
100
tests/unit/test_ui_routes.py
Normal file
@@ -0,0 +1,100 @@
|
||||
from typing import Any, Dict, cast
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from models.scenario import Scenario
|
||||
|
||||
|
||||
def test_dashboard_route_provides_summary(
|
||||
api_client: TestClient, seeded_ui_data: Dict[str, Any]
|
||||
) -> None:
|
||||
response = api_client.get("/ui/dashboard")
|
||||
assert response.status_code == 200
|
||||
|
||||
template = getattr(response, "template", None)
|
||||
assert template is not None
|
||||
assert template.name == "Dashboard.html"
|
||||
|
||||
context = cast(Dict[str, Any], getattr(response, "context", {}))
|
||||
assert context.get("report_available") is True
|
||||
|
||||
metric_labels = {item["label"] for item in context["summary_metrics"]}
|
||||
assert {"CAPEX Total", "OPEX Total", "Production", "Simulation Iterations"}.issubset(metric_labels)
|
||||
|
||||
scenario = cast(Scenario, seeded_ui_data["scenario"])
|
||||
scenario_row = next(
|
||||
row for row in context["scenario_rows"] if row["scenario_name"] == scenario.name
|
||||
)
|
||||
assert scenario_row["iterations"] == 3
|
||||
assert scenario_row["simulation_mean_display"] == "971,666.67"
|
||||
assert scenario_row["capex_display"] == "$1,000,000.00"
|
||||
assert scenario_row["opex_display"] == "$250,000.00"
|
||||
assert scenario_row["production_display"] == "800.00"
|
||||
assert scenario_row["consumption_display"] == "1,200.00"
|
||||
|
||||
|
||||
def test_scenarios_route_lists_seeded_scenario(
|
||||
api_client: TestClient, seeded_ui_data: Dict[str, Any]
|
||||
) -> None:
|
||||
response = api_client.get("/ui/scenarios")
|
||||
assert response.status_code == 200
|
||||
|
||||
template = getattr(response, "template", None)
|
||||
assert template is not None
|
||||
assert template.name == "ScenarioForm.html"
|
||||
|
||||
context = cast(Dict[str, Any], getattr(response, "context", {}))
|
||||
names = [item["name"] for item in context["scenarios"]]
|
||||
scenario = cast(Scenario, seeded_ui_data["scenario"])
|
||||
assert scenario.name in names
|
||||
|
||||
|
||||
def test_reporting_route_includes_summary(
|
||||
api_client: TestClient, seeded_ui_data: Dict[str, Any]
|
||||
) -> None:
|
||||
response = api_client.get("/ui/reporting")
|
||||
assert response.status_code == 200
|
||||
|
||||
template = getattr(response, "template", None)
|
||||
assert template is not None
|
||||
assert template.name == "reporting.html"
|
||||
|
||||
context = cast(Dict[str, Any], getattr(response, "context", {}))
|
||||
summaries = context["report_summaries"]
|
||||
scenario = cast(Scenario, seeded_ui_data["scenario"])
|
||||
scenario_summary = next(
|
||||
item for item in summaries if item["scenario_id"] == scenario.id
|
||||
)
|
||||
assert scenario_summary["iterations"] == 3
|
||||
mean_value = float(scenario_summary["summary"]["mean"])
|
||||
assert abs(mean_value - 971_666.6666666666) < 1e-6
|
||||
|
||||
|
||||
def test_dashboard_data_endpoint_returns_aggregates(
|
||||
api_client: TestClient, seeded_ui_data: Dict[str, Any]
|
||||
) -> None:
|
||||
response = api_client.get("/ui/dashboard/data")
|
||||
assert response.status_code == 200
|
||||
|
||||
payload = response.json()
|
||||
assert payload["report_available"] is True
|
||||
|
||||
metric_map = {item["label"]: item["value"] for item in payload["summary_metrics"]}
|
||||
assert metric_map["CAPEX Total"].startswith("$")
|
||||
assert metric_map["Maintenance Cost"].startswith("$")
|
||||
|
||||
scenario = cast(Scenario, seeded_ui_data["scenario"])
|
||||
scenario_rows = payload["scenario_rows"]
|
||||
scenario_entry = next(
|
||||
row for row in scenario_rows if row["scenario_name"] == scenario.name
|
||||
)
|
||||
assert scenario_entry["capex_display"] == "$1,000,000.00"
|
||||
assert scenario_entry["production_display"] == "800.00"
|
||||
|
||||
labels = payload["scenario_cost_chart"]["labels"]
|
||||
idx = labels.index(scenario.name)
|
||||
assert payload["scenario_cost_chart"]["capex"][idx] == 1_000_000.0
|
||||
|
||||
activity_labels = payload["scenario_activity_chart"]["labels"]
|
||||
activity_idx = activity_labels.index(scenario.name)
|
||||
assert payload["scenario_activity_chart"]["production"][activity_idx] == 800.0
|
||||
Reference in New Issue
Block a user