126 lines
4.2 KiB
Python
126 lines
4.2 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")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|