- Added monitoring metrics for project creation success and error handling in `ProjectRepository`. - Implemented similar monitoring for scenario creation in `ScenarioRepository`. - Refactored `run_monte_carlo` function in `simulation.py` to include timing and success/error metrics. - Introduced new CSS styles for headers, alerts, and navigation buttons in `main.css` and `projects.css`. - Created a new JavaScript file for navigation logic to handle chevron buttons. - Updated HTML templates to include new navigation buttons and improved styling for buttons. - Added tests for reporting service and routes to ensure proper functionality and access control. - Removed unused imports and optimized existing test files for better clarity and performance.
120 lines
4.5 KiB
Python
120 lines
4.5 KiB
Python
from __future__ import annotations
|
|
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from models import (
|
|
MiningOperationType,
|
|
Project,
|
|
)
|
|
from models.import_export_log import ImportExportLog
|
|
|
|
|
|
@pytest.fixture()
|
|
def project_seed(unit_of_work_factory):
|
|
with unit_of_work_factory() as uow:
|
|
assert uow.projects is not None
|
|
project = Project(name="Seed Project", operation_type=MiningOperationType.OPEN_PIT)
|
|
uow.projects.create(project)
|
|
yield project
|
|
|
|
|
|
def test_project_import_preview_and_commit(client: TestClient, unit_of_work_factory) -> None:
|
|
csv_content = (
|
|
"name,location,operation_type\n"
|
|
"Project Import A,Chile,open pit\n"
|
|
"Project Import B,Canada,underground\n"
|
|
)
|
|
files = {"file": ("projects.csv", csv_content, "text/csv")}
|
|
|
|
preview_response = client.post("/imports/projects/preview", files=files)
|
|
assert preview_response.status_code == 200
|
|
preview_payload = preview_response.json()
|
|
assert preview_payload["summary"]["accepted"] == 2
|
|
assert preview_payload["stage_token"]
|
|
|
|
token = preview_payload["stage_token"]
|
|
|
|
commit_response = client.post("/imports/projects/commit", json={"token": token})
|
|
assert commit_response.status_code == 200
|
|
commit_payload = commit_response.json()
|
|
assert commit_payload["summary"]["created"] == 2
|
|
|
|
with unit_of_work_factory() as uow:
|
|
assert uow.projects is not None
|
|
names = {project.name for project in uow.projects.list()}
|
|
assert {"Project Import A", "Project Import B"}.issubset(names)
|
|
# ensure audit logs recorded preview and commit events
|
|
assert uow.session is not None
|
|
logs = (
|
|
uow.session.query(ImportExportLog)
|
|
.filter(ImportExportLog.dataset == "projects")
|
|
.order_by(ImportExportLog.created_at)
|
|
.all()
|
|
)
|
|
actions = [log.action for log in logs]
|
|
assert "preview" in actions
|
|
assert "commit" in actions
|
|
|
|
|
|
def test_scenario_import_preview_and_commit(client: TestClient, unit_of_work_factory, project_seed) -> None:
|
|
csv_content = (
|
|
"project_name,name,status\n"
|
|
"Seed Project,Scenario Import A,Draft\n"
|
|
"Seed Project,Scenario Import B,Active\n"
|
|
)
|
|
files = {"file": ("scenarios.csv", csv_content, "text/csv")}
|
|
|
|
preview_response = client.post("/imports/scenarios/preview", files=files)
|
|
assert preview_response.status_code == 200
|
|
preview_payload = preview_response.json()
|
|
assert preview_payload["summary"]["accepted"] == 2
|
|
token = preview_payload["stage_token"]
|
|
|
|
commit_response = client.post("/imports/scenarios/commit", json={"token": token})
|
|
assert commit_response.status_code == 200
|
|
commit_payload = commit_response.json()
|
|
assert commit_payload["summary"]["created"] == 2
|
|
|
|
with unit_of_work_factory() as uow:
|
|
assert uow.projects is not None and uow.scenarios is not None
|
|
project = uow.projects.list()[0]
|
|
scenarios = uow.scenarios.list_for_project(project.id)
|
|
names = {scenario.name for scenario in scenarios}
|
|
assert {"Scenario Import A", "Scenario Import B"}.issubset(names)
|
|
assert uow.session is not None
|
|
logs = (
|
|
uow.session.query(ImportExportLog)
|
|
.filter(ImportExportLog.dataset == "scenarios")
|
|
.order_by(ImportExportLog.created_at)
|
|
.all()
|
|
)
|
|
actions = [log.action for log in logs]
|
|
assert "preview" in actions
|
|
assert "commit" in actions
|
|
|
|
|
|
def test_project_export_endpoint(client: TestClient, unit_of_work_factory) -> None:
|
|
with unit_of_work_factory() as uow:
|
|
assert uow.projects is not None
|
|
uow.projects.create(Project(name="Export Project", operation_type=MiningOperationType.OPEN_PIT))
|
|
|
|
response = client.post("/exports/projects", json={"format": "csv"})
|
|
assert response.status_code == 200
|
|
assert response.headers["Content-Type"].startswith("text/csv")
|
|
assert "attachment; filename=" in response.headers["Content-Disposition"]
|
|
body = response.content.decode("utf-8")
|
|
assert "Export Project" in body
|
|
|
|
with unit_of_work_factory() as uow:
|
|
assert uow.session is not None
|
|
logs = (
|
|
uow.session.query(ImportExportLog)
|
|
.filter(ImportExportLog.dataset == "projects", ImportExportLog.action == "export")
|
|
.order_by(ImportExportLog.created_at.desc())
|
|
.first()
|
|
)
|
|
assert logs is not None
|
|
assert logs.status == "success"
|
|
assert logs.row_count >= 1 |