Files
calminer/tests/test_import_export_integration.py

124 lines
4.6 KiB
Python

from __future__ import annotations
from io import BytesIO
import pandas as pd
import pytest
from fastapi.testclient import TestClient
from models import (
MiningOperationType,
Project,
Scenario,
ScenarioStatus,
)
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