feat: add integration tests for project and scenario lifecycles, update templates to new Starlette signature, and optimize project retrieval logic
This commit is contained in:
106
tests/integration/test_scenario_lifecycle.py
Normal file
106
tests/integration/test_scenario_lifecycle.py
Normal file
@@ -0,0 +1,106 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
class TestScenarioLifecycle:
|
||||
def test_scenario_lifecycle_flow(self, client: TestClient) -> None:
|
||||
# Create a project to attach scenarios to
|
||||
project_response = client.post(
|
||||
"/projects",
|
||||
json={
|
||||
"name": "Scenario Host Project",
|
||||
"location": "Ontario",
|
||||
"operation_type": "open_pit",
|
||||
"description": "Project for scenario lifecycle testing",
|
||||
},
|
||||
)
|
||||
assert project_response.status_code == 201
|
||||
project_id = project_response.json()["id"]
|
||||
|
||||
# Create a scenario via the API for the project
|
||||
scenario_response = client.post(
|
||||
f"/projects/{project_id}/scenarios",
|
||||
json={
|
||||
"name": "Lifecycle Scenario",
|
||||
"description": "Initial scenario description",
|
||||
"status": "draft",
|
||||
"currency": "usd",
|
||||
"primary_resource": "diesel",
|
||||
},
|
||||
)
|
||||
assert scenario_response.status_code == 201
|
||||
scenario_id = scenario_response.json()["id"]
|
||||
|
||||
# Project detail page should list the new scenario in draft state
|
||||
project_detail = client.get(f"/projects/{project_id}/view")
|
||||
assert project_detail.status_code == 200
|
||||
assert "Lifecycle Scenario" in project_detail.text
|
||||
assert "<td>Draft</td>" in project_detail.text
|
||||
|
||||
# Update the scenario through the HTML form
|
||||
form_response = client.post(
|
||||
f"/scenarios/{scenario_id}/edit",
|
||||
data={
|
||||
"name": "Lifecycle Scenario Revised",
|
||||
"description": "Revised scenario assumptions",
|
||||
"status_value": "active",
|
||||
"start_date": "2025-01-01",
|
||||
"end_date": "2025-12-31",
|
||||
"discount_rate": "5.5",
|
||||
"currency": "cad",
|
||||
"primary_resource": "electricity",
|
||||
},
|
||||
follow_redirects=False,
|
||||
)
|
||||
assert form_response.status_code == 303
|
||||
assert form_response.headers["Location"].endswith(
|
||||
f"/scenarios/{scenario_id}/view")
|
||||
|
||||
# Scenario detail page should reflect the updated information
|
||||
scenario_detail = client.get(f"/scenarios/{scenario_id}/view")
|
||||
assert scenario_detail.status_code == 200
|
||||
assert "Lifecycle Scenario Revised" in scenario_detail.text
|
||||
assert "Status: Active" in scenario_detail.text
|
||||
assert "CAD" in scenario_detail.text
|
||||
assert "Electricity" in scenario_detail.text
|
||||
assert "Revised scenario assumptions" in scenario_detail.text
|
||||
|
||||
# Project detail page should show the scenario as active with updated currency/resource
|
||||
project_detail = client.get(f"/projects/{project_id}/view")
|
||||
assert "<td>Active</td>" in project_detail.text
|
||||
assert "<td>CAD</td>" in project_detail.text
|
||||
assert "<td>Electricity</td>" in project_detail.text
|
||||
|
||||
# Attempt to update the scenario with invalid currency to trigger validation error
|
||||
invalid_update = client.put(
|
||||
f"/scenarios/{scenario_id}",
|
||||
json={"currency": "ca"},
|
||||
)
|
||||
assert invalid_update.status_code == 422
|
||||
assert (
|
||||
invalid_update.json()["detail"][0]["msg"]
|
||||
== "Value error, Currency code must be a 3-letter ISO value"
|
||||
)
|
||||
|
||||
# Scenario detail should still show the previous (valid) currency
|
||||
scenario_detail = client.get(f"/scenarios/{scenario_id}/view")
|
||||
assert "CAD" in scenario_detail.text
|
||||
|
||||
# Archive the scenario through the API
|
||||
archive_response = client.put(
|
||||
f"/scenarios/{scenario_id}",
|
||||
json={"status": "archived"},
|
||||
)
|
||||
assert archive_response.status_code == 200
|
||||
assert archive_response.json()["status"] == "archived"
|
||||
|
||||
# Scenario detail reflects archived status
|
||||
scenario_detail = client.get(f"/scenarios/{scenario_id}/view")
|
||||
assert "Status: Archived" in scenario_detail.text
|
||||
|
||||
# Project detail metrics and table entries reflect the archived state
|
||||
project_detail = client.get(f"/projects/{project_id}/view")
|
||||
assert "<h2>Archived</h2>" in project_detail.text
|
||||
assert '<p class="metric-value">1</p>' in project_detail.text
|
||||
assert "<td>Archived</td>" in project_detail.text
|
||||
Reference in New Issue
Block a user