Explorar el Código

Improved docker tests

maziggy hace 3 meses
padre
commit
c937e6781b

+ 24 - 18
backend/app/api/routes/camera.py

@@ -713,14 +713,15 @@ async def check_plate_empty(
     )
     from backend.app.services.printer_manager import printer_manager
 
+    # Check printer exists first (before OpenCV check)
+    printer = await get_printer_or_404(printer_id, db)
+
     if not is_plate_detection_available():
         raise HTTPException(
             status_code=503,
             detail="Plate detection not available. Install opencv-python-headless to enable.",
         )
 
-    printer = await get_printer_or_404(printer_id, db)
-
     # Check chamber light status
     light_warning = False
     state = printer_manager.get_status(printer_id)
@@ -818,14 +819,15 @@ async def calibrate_plate_detection(
     )
     from backend.app.services.printer_manager import printer_manager
 
+    # Check printer exists first (before OpenCV check)
+    printer = await get_printer_or_404(printer_id, db)
+
     if not is_plate_detection_available():
         raise HTTPException(
             status_code=503,
             detail="Plate detection not available. Install opencv-python-headless to enable.",
         )
 
-    printer = await get_printer_or_404(printer_id, db)
-
     # Check chamber light - warn but don't block
     state = printer_manager.get_status(printer_id)
     light_warning = state and not state.chamber_light
@@ -869,15 +871,15 @@ async def delete_plate_calibration(
         is_plate_detection_available,
     )
 
+    # Verify printer exists first (before OpenCV check)
+    await get_printer_or_404(printer_id, db)
+
     if not is_plate_detection_available():
         raise HTTPException(
             status_code=503,
             detail="Plate detection not available. Install opencv-python-headless to enable.",
         )
 
-    # Verify printer exists
-    await get_printer_or_404(printer_id, db)
-
     deleted = delete_calibration(printer_id, plate_type)
     plate_msg = f" for '{plate_type}'" if plate_type else ""
 
@@ -909,6 +911,9 @@ async def get_plate_detection_status(
     )
     from backend.app.services.printer_manager import printer_manager
 
+    # Verify printer exists first (before OpenCV check)
+    await get_printer_or_404(printer_id, db)
+
     if not is_plate_detection_available():
         return {
             "available": False,
@@ -918,9 +923,6 @@ async def get_plate_detection_status(
             "message": "OpenCV not installed",
         }
 
-    # Verify printer exists
-    await get_printer_or_404(printer_id, db)
-
     # Get chamber light status
     state = printer_manager.get_status(printer_id)
     chamber_light = state.chamber_light if state else False
@@ -942,11 +944,12 @@ async def get_plate_references(
     """
     from backend.app.services.plate_detection import PlateDetector, is_plate_detection_available
 
+    # Verify printer exists first (before OpenCV check)
+    await get_printer_or_404(printer_id, db)
+
     if not is_plate_detection_available():
         raise HTTPException(503, "Plate detection not available")
 
-    await get_printer_or_404(printer_id, db)
-
     detector = PlateDetector()
     references = detector.get_references(printer_id)
 
@@ -973,11 +976,12 @@ async def get_reference_thumbnail(
 
     from backend.app.services.plate_detection import PlateDetector, is_plate_detection_available
 
+    # Verify printer exists first (before OpenCV check)
+    await get_printer_or_404(printer_id, db)
+
     if not is_plate_detection_available():
         raise HTTPException(503, "Plate detection not available")
 
-    await get_printer_or_404(printer_id, db)
-
     detector = PlateDetector()
     thumbnail = detector.get_reference_thumbnail(printer_id, index)
 
@@ -997,11 +1001,12 @@ async def update_reference_label(
     """Update the label for a calibration reference."""
     from backend.app.services.plate_detection import PlateDetector, is_plate_detection_available
 
+    # Verify printer exists first (before OpenCV check)
+    await get_printer_or_404(printer_id, db)
+
     if not is_plate_detection_available():
         raise HTTPException(503, "Plate detection not available")
 
-    await get_printer_or_404(printer_id, db)
-
     detector = PlateDetector()
     success = detector.update_reference_label(printer_id, index, label)
 
@@ -1020,11 +1025,12 @@ async def delete_reference(
     """Delete a specific calibration reference."""
     from backend.app.services.plate_detection import PlateDetector, is_plate_detection_available
 
+    # Verify printer exists first (before OpenCV check)
+    await get_printer_or_404(printer_id, db)
+
     if not is_plate_detection_available():
         raise HTTPException(503, "Plate detection not available")
 
-    await get_printer_or_404(printer_id, db)
-
     detector = PlateDetector()
     success = detector.delete_reference(printer_id, index)
 

+ 2 - 0
backend/app/services/plate_detection.py

@@ -5,6 +5,8 @@ Uses calibration-based difference detection - compares current frame to
 a reference image of the empty plate.
 """
 
+from __future__ import annotations
+
 import logging
 from pathlib import Path
 

+ 27 - 5
backend/tests/integration/test_camera_api.py

@@ -285,6 +285,7 @@ class TestCameraAPI:
         mock_result.difference_percent = 0.5
         mock_result.message = "Plate appears empty"
         mock_result.needs_calibration = False
+        mock_result.debug_image = None
         mock_result.to_dict.return_value = {
             "is_empty": True,
             "confidence": 0.95,
@@ -294,7 +295,16 @@ class TestCameraAPI:
             "needs_calibration": False,
         }
 
-        with patch("backend.app.services.plate_detection.check_plate_empty", new_callable=AsyncMock) as mock_check:
+        # Mock PlateDetector for reference count
+        mock_detector = MagicMock()
+        mock_detector.get_calibration_count.return_value = 0
+        mock_detector.MAX_REFERENCES = 5
+
+        with (
+            patch("backend.app.services.plate_detection.is_plate_detection_available", return_value=True),
+            patch("backend.app.services.plate_detection.check_plate_empty", new_callable=AsyncMock) as mock_check,
+            patch("backend.app.services.plate_detection.PlateDetector", return_value=mock_detector),
+        ):
             mock_check.return_value = mock_result
             response = await async_client.get(f"/api/v1/printers/{printer.id}/camera/check-plate")
 
@@ -319,7 +329,10 @@ class TestCameraAPI:
         printer = await printer_factory()
 
         # Mock calibrate_plate at the source module to avoid camera timeout
-        with patch("backend.app.services.plate_detection.calibrate_plate", new_callable=AsyncMock) as mock_calibrate:
+        with (
+            patch("backend.app.services.plate_detection.is_plate_detection_available", return_value=True),
+            patch("backend.app.services.plate_detection.calibrate_plate", new_callable=AsyncMock) as mock_calibrate,
+        ):
             mock_calibrate.return_value = (True, "Calibration saved (1/5 references)", 0)
             response = await async_client.post(f"/api/v1/printers/{printer.id}/camera/plate-detection/calibrate")
 
@@ -342,7 +355,8 @@ class TestCameraAPI:
         """Verify delete calibration returns proper structure."""
         printer = await printer_factory()
 
-        response = await async_client.delete(f"/api/v1/printers/{printer.id}/camera/plate-detection/calibrate")
+        with patch("backend.app.services.plate_detection.is_plate_detection_available", return_value=True):
+            response = await async_client.delete(f"/api/v1/printers/{printer.id}/camera/plate-detection/calibrate")
 
         assert response.status_code == 200
         result = response.json()
@@ -374,8 +388,16 @@ class TestCameraAPI:
         """Verify get references returns proper structure."""
         printer = await printer_factory()
 
-        # OpenCV is available in test environment, just check the response structure
-        response = await async_client.get(f"/api/v1/printers/{printer.id}/camera/plate-detection/references")
+        # Mock OpenCV availability and PlateDetector
+        mock_detector = MagicMock()
+        mock_detector.get_references.return_value = []
+        mock_detector.MAX_REFERENCES = 5
+
+        with (
+            patch("backend.app.services.plate_detection.is_plate_detection_available", return_value=True),
+            patch("backend.app.services.plate_detection.PlateDetector", return_value=mock_detector),
+        ):
+            response = await async_client.get(f"/api/v1/printers/{printer.id}/camera/plate-detection/references")
 
         assert response.status_code == 200
         result = response.json()

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
static/assets/index-0Pk0mZuT.css


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
static/assets/index-B3Buyqqk.css


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
static/assets/index-B6QcllFX.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
static/assets/index-BvTstZiS.js


+ 2 - 2
static/index.html

@@ -23,8 +23,8 @@
 
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-DpCP4Cea.js"></script>
-    <link rel="stylesheet" crossorigin href="/assets/index-0Pk0mZuT.css">
+    <script type="module" crossorigin src="/assets/index-B6QcllFX.js"></script>
+    <link rel="stylesheet" crossorigin href="/assets/index-B3Buyqqk.css">
   </head>
   <body>
     <div id="root"></div>

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio