Files
RollCalcPython/tests/test_calculation_api.py
T

145 lines
5.0 KiB
Python

import base64
import os
import tempfile
import unittest
from unittest.mock import patch
import app as rollcalc_app
class CalculationApiTests(unittest.TestCase):
def setUp(self):
self.temp_dir = tempfile.TemporaryDirectory()
self.original_log_file = rollcalc_app.LOG_FILE
rollcalc_app.LOG_FILE = os.path.join(self.temp_dir.name, "access.json")
rollcalc_app.app.config.update(TESTING=True)
self.client = rollcalc_app.app.test_client()
credentials = base64.b64encode(b"mtazl:rollcalc").decode("ascii")
self.headers = {"Authorization": f"Basic {credentials}"}
def tearDown(self):
rollcalc_app.LOG_FILE = self.original_log_file
self.temp_dir.cleanup()
def test_calculation_endpoint_returns_machine_readable_authoritative_result(self):
response = self.client.post(
"/api/calculations/roll",
json={
"article_number": "180205",
"roll_length_m": 65,
"core_diameter_mm": 150,
},
headers=self.headers,
)
result = response.get_json()
self.assertEqual(response.status_code, 200)
self.assertEqual(result["status"], "success")
self.assertEqual(result["resolved_article"]["number"], "180205")
self.assertEqual(
result["provenance"]["calculator"],
"roll_calculation.calculate_roll",
)
def test_modification_endpoint_changes_state_and_recalculates(self):
response = self.client.post(
"/api/calculations/roll/modify",
json={
"state": {
"request": {
"article_number": "180205",
"roll_length_m": 65,
"core_diameter_mm": 150,
}
},
"changes": {"roll_length_m": 80},
},
headers=self.headers,
)
result = response.get_json()
self.assertEqual(response.status_code, 200)
self.assertEqual(result["status"], "success")
self.assertEqual(result["state"]["request"]["roll_length_m"], 80.0)
self.assertEqual(result["calculation"]["effective_roll_length_m"], 80.0)
def test_product_length_endpoint_uses_the_domain_calculation(self):
response = self.client.post(
"/api/calculations/product-length",
json={
"target_roll_diameter_mm": 600,
"core_diameter_mm": 140,
"thickness_mm": 4.311611,
"thickness_stddev_mm": 0.249999,
"width_m": 6.0,
"area_weight_g_m2": 495.395833,
},
headers=self.headers,
)
result = response.get_json()
self.assertEqual(response.status_code, 200)
self.assertEqual(result["status"], "success")
self.assertAlmostEqual(
result["calculation"]["average_product_length_m"], 62.0068774341
)
def test_transport_endpoint_delegates_to_shared_domain_service(self):
payload = {
"length_m": 10,
"width_m": 5,
"height_m": 5,
"max_weight_kg": 10000,
"roll_diameter_mm": 1000,
"core_diameter_mm": 150,
"roll_width_m": 1,
"roll_weight_kg": 1000,
}
with patch.object(
rollcalc_app,
"analyze_transport",
return_value={"status": "success", "analysis": {"final_rolls": 10}},
) as analyze:
response = self.client.post(
"/api/calculations/transport",
json=payload,
headers=self.headers,
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get_json()["analysis"]["final_rolls"], 10)
analyze.assert_called_once_with(payload)
def test_transport_endpoint_returns_structured_domain_validation(self):
response = self.client.post(
"/api/calculations/transport",
json={"length_m": 0},
headers=self.headers,
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get_json()["status"], "invalid_parameter")
def test_production_feasibility_endpoint_uses_shared_domain(self):
response = self.client.post(
"/api/calculations/production-feasibility",
json={
"machine": "B1",
"roll_weight_kg": 2500,
"average_diameter_mm": 876,
"maximum_diameter_mm": 877,
"core_diameter_mm": 168,
"product_width_m": 5,
},
headers=self.headers,
)
result = response.get_json()
self.assertEqual(response.status_code, 200)
self.assertEqual(result["feasibility"], "feasible_with_warnings")
self.assertEqual(result["warning_constraints"], ["roll_diameter_mm"])
if __name__ == "__main__":
unittest.main()