import os import tempfile import unittest from datetime import datetime from app import create_app, db from app.models import Recipe, SyncConflict, SyncQueue from config import TestingConfig class LegacyFourthBatchConfig(TestingConfig): _TMP_DIR = tempfile.mkdtemp(prefix="wesp-legacy-batch4-tests-") SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(_TMP_DIR, 'recipes_test.db')}" SQLALCHEMY_BINDS = {"reports": f"sqlite:///{os.path.join(_TMP_DIR, 'reports_test.db')}"} AUTH_LOGIN = "legacy4-admin" AUTH_PASSWORD = "legacy4-secret" class LegacyCompatFourthBatchTests(unittest.TestCase): def setUp(self) -> None: self.app = create_app(LegacyFourthBatchConfig) self.client = self.app.test_client() self.ctx = self.app.app_context() self.ctx.push() db.create_all() login = self.client.post( "/api/auth/login", json={"login": "legacy4-admin", "password": "legacy4-secret"} ) self.assertEqual(login.status_code, 200) def tearDown(self) -> None: db.session.remove() db.drop_all() self.ctx.pop() def test_sync_extended_endpoints(self) -> None: init_resp = self.client.post("/api/sync/init") self.assertEqual(init_resp.status_code, 200) metadata_resp = self.client.get("/api/sync/metadata") self.assertEqual(metadata_resp.status_code, 200) self.assertEqual(metadata_resp.get_json()["node_type"], "server") register_resp = self.client.post( "/api/sync/register", json={"client_id": "client-4", "client_name": "Client 4"} ) self.assertEqual(register_resp.status_code, 200) client_resp = self.client.get("/api/sync/clients/client-4") self.assertEqual(client_resp.status_code, 200) self.assertEqual(client_resp.get_json()["node_id"], "client-4") db.session.add( SyncQueue( table_name="recipe", record_id="r-any", action="update", status="pending", priority=2, retry_count=0, max_retries=3, created_at=datetime.now(), ) ) db.session.add( SyncConflict( table_name="recipe", record_id="r-any", conflict_type="version_mismatch", local_data="{}", remote_data="{}", ) ) db.session.commit() queue_resp = self.client.get("/api/sync/queue") self.assertEqual(queue_resp.status_code, 200) self.assertGreaterEqual(len(queue_resp.get_json()), 1) stats_resp = self.client.get("/api/sync/queue/stats") self.assertEqual(stats_resp.status_code, 200) self.assertIn("pending", stats_resp.get_json()) conflicts_resp = self.client.get("/api/sync/conflicts") self.assertEqual(conflicts_resp.status_code, 200) conflicts = conflicts_resp.get_json() self.assertGreaterEqual(len(conflicts), 1) conflict_id = conflicts[0]["id"] resolve_resp = self.client.post( f"/api/sync/conflicts/{conflict_id}/resolve", json={"resolution": "remote"} ) self.assertEqual(resolve_resp.status_code, 200) status_resp = self.client.get("/api/sync/status") self.assertEqual(status_resp.status_code, 200) self.assertIn("queue", status_resp.get_json()) check_db_resp = self.client.post("/api/sync/check-db") self.assertEqual(check_db_resp.status_code, 200) self.assertTrue(check_db_resp.get_json()["success"]) check_client_resp = self.client.post("/api/sync/check-db-client", json={"client_id": "client-4"}) self.assertEqual(check_client_resp.status_code, 200) self.assertEqual(check_client_resp.get_json()["client_id"], "client-4") def test_reports_legacy_endpoints(self) -> None: recipe = Recipe(id="r-legacy4", name="Recipe 4", heads_per_trip=10, mixing_time=5) db.session.add(recipe) db.session.commit() save_report_resp = self.client.post( "/api/save_report", json={ "recipe_id": "r-legacy4", "total_weight": 100.5, "target_mixing_time": 5, "actual_mixing_time": 6, "components": [ {"name": "Corn", "target_weight": 50, "actual_weight": 49, "overload": 1} ], "component_loading_times": [ { "component_name": "Corn", "start_time": "2026-01-01T10:00:00", "end_time": "2026-01-01T10:01:00", "loading_duration": 60, "loading_order": 1, } ], }, ) self.assertEqual(save_report_resp.status_code, 200) report_id = save_report_resp.get_json()["report_id"] loading_times_resp = self.client.get(f"/api/reports/{report_id}/loading_times") self.assertEqual(loading_times_resp.status_code, 200) self.assertEqual(loading_times_resp.get_json()["status"], "success") consumption_resp = self.client.get("/api/consumption_by_component") self.assertEqual(consumption_resp.status_code, 200) self.assertIsInstance(consumption_resp.get_json(), list) save_unloading_resp = self.client.post( "/api/save_unloading_report", json={ "loading_report_id": report_id, "recipe_id": "r-legacy4", "total_weight": 100.5, "total_unloaded_weight": 99.0, "remaining_weight": 1.5, "unloading_groups": [ { "name": "Group A", "target_weight": 100.5, "unloaded_weight": 99.0, "remaining_weight": 1.5, "distribution_type": "percent", "distribution_value": 100, "order": 1, } ], }, ) self.assertEqual(save_unloading_resp.status_code, 200) unloading_report_id = save_unloading_resp.get_json()["unloading_report_id"] unloading_reports_resp = self.client.get("/api/unloading_reports") self.assertEqual(unloading_reports_resp.status_code, 200) self.assertGreaterEqual(len(unloading_reports_resp.get_json()), 1) unloading_groups_resp = self.client.get(f"/api/reports/{unloading_report_id}/unloading_groups") self.assertEqual(unloading_groups_resp.status_code, 200) self.assertEqual(unloading_groups_resp.get_json()["status"], "success") if __name__ == "__main__": unittest.main()