test_plate_detection.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. """Unit tests for plate detection service."""
  2. import tempfile
  3. from pathlib import Path
  4. from unittest.mock import MagicMock, patch
  5. import pytest
  6. # Mock cv2 and numpy before importing the module
  7. cv2_mock = MagicMock()
  8. np_mock = MagicMock()
  9. class TestPlateDetectionResult:
  10. """Tests for PlateDetectionResult class."""
  11. def test_result_to_dict(self):
  12. """Verify PlateDetectionResult.to_dict() returns correct structure."""
  13. with patch.dict("sys.modules", {"cv2": cv2_mock, "numpy": np_mock}):
  14. from backend.app.services.plate_detection import PlateDetectionResult
  15. result = PlateDetectionResult(
  16. is_empty=True,
  17. confidence=0.95,
  18. difference_percent=0.5,
  19. message="Test message",
  20. debug_image=None,
  21. needs_calibration=False,
  22. )
  23. d = result.to_dict()
  24. assert d["is_empty"] is True
  25. assert d["confidence"] == 0.95
  26. assert d["difference_percent"] == 0.5
  27. assert d["message"] == "Test message"
  28. assert d["has_debug_image"] is False
  29. assert d["needs_calibration"] is False
  30. def test_result_with_debug_image(self):
  31. """Verify has_debug_image is True when debug_image is provided."""
  32. with patch.dict("sys.modules", {"cv2": cv2_mock, "numpy": np_mock}):
  33. from backend.app.services.plate_detection import PlateDetectionResult
  34. result = PlateDetectionResult(
  35. is_empty=False,
  36. confidence=0.8,
  37. difference_percent=5.0,
  38. message="Objects detected",
  39. debug_image=b"fake_image_data",
  40. needs_calibration=False,
  41. )
  42. d = result.to_dict()
  43. assert d["has_debug_image"] is True
  44. def test_result_needs_calibration(self):
  45. """Verify needs_calibration flag is preserved."""
  46. with patch.dict("sys.modules", {"cv2": cv2_mock, "numpy": np_mock}):
  47. from backend.app.services.plate_detection import PlateDetectionResult
  48. result = PlateDetectionResult(
  49. is_empty=True,
  50. confidence=0.0,
  51. difference_percent=0.0,
  52. message="No calibration",
  53. needs_calibration=True,
  54. )
  55. d = result.to_dict()
  56. assert d["needs_calibration"] is True
  57. class TestPlateDetector:
  58. """Tests for PlateDetector class."""
  59. def test_detector_initialization(self):
  60. """Verify PlateDetector initializes with default values."""
  61. with patch.dict("sys.modules", {"cv2": cv2_mock, "numpy": np_mock}):
  62. # Re-import to get fresh module
  63. import importlib
  64. import backend.app.services.plate_detection as pd_module
  65. importlib.reload(pd_module)
  66. # Mock OPENCV_AVAILABLE
  67. pd_module.OPENCV_AVAILABLE = True
  68. detector = pd_module.PlateDetector()
  69. assert detector.roi == (0.15, 0.35, 0.70, 0.55)
  70. assert detector.difference_threshold == 1.0
  71. def test_detector_custom_roi(self):
  72. """Verify PlateDetector accepts custom ROI."""
  73. with patch.dict("sys.modules", {"cv2": cv2_mock, "numpy": np_mock}):
  74. import importlib
  75. import backend.app.services.plate_detection as pd_module
  76. importlib.reload(pd_module)
  77. pd_module.OPENCV_AVAILABLE = True
  78. custom_roi = (0.1, 0.2, 0.8, 0.6)
  79. detector = pd_module.PlateDetector(roi=custom_roi)
  80. assert detector.roi == custom_roi
  81. def test_detector_raises_without_opencv(self):
  82. """Verify PlateDetector raises when OpenCV not available."""
  83. with patch.dict("sys.modules", {"cv2": cv2_mock, "numpy": np_mock}):
  84. import importlib
  85. import backend.app.services.plate_detection as pd_module
  86. importlib.reload(pd_module)
  87. pd_module.OPENCV_AVAILABLE = False
  88. with pytest.raises(RuntimeError, match="OpenCV is not installed"):
  89. pd_module.PlateDetector()
  90. class TestCalibrationStatus:
  91. """Tests for calibration status functions."""
  92. def test_get_calibration_status_no_opencv(self):
  93. """Verify calibration status when OpenCV not available."""
  94. with patch.dict("sys.modules", {"cv2": cv2_mock, "numpy": np_mock}):
  95. import importlib
  96. import backend.app.services.plate_detection as pd_module
  97. importlib.reload(pd_module)
  98. pd_module.OPENCV_AVAILABLE = False
  99. status = pd_module.get_calibration_status(1)
  100. assert status["available"] is False
  101. assert status["calibrated"] is False
  102. assert status["reference_count"] == 0
  103. assert "OpenCV not available" in status["message"]
  104. def test_is_plate_detection_available_true(self):
  105. """Verify is_plate_detection_available returns True when OpenCV available."""
  106. with patch.dict("sys.modules", {"cv2": cv2_mock, "numpy": np_mock}):
  107. import importlib
  108. import backend.app.services.plate_detection as pd_module
  109. importlib.reload(pd_module)
  110. pd_module.OPENCV_AVAILABLE = True
  111. assert pd_module.is_plate_detection_available() is True
  112. def test_is_plate_detection_available_false(self):
  113. """Verify is_plate_detection_available returns False when OpenCV not available."""
  114. with patch.dict("sys.modules", {"cv2": cv2_mock, "numpy": np_mock}):
  115. import importlib
  116. import backend.app.services.plate_detection as pd_module
  117. importlib.reload(pd_module)
  118. pd_module.OPENCV_AVAILABLE = False
  119. assert pd_module.is_plate_detection_available() is False
  120. class TestDeleteCalibration:
  121. """Tests for delete_calibration function."""
  122. def test_delete_calibration_no_opencv(self):
  123. """Verify delete_calibration returns False when OpenCV not available."""
  124. with patch.dict("sys.modules", {"cv2": cv2_mock, "numpy": np_mock}):
  125. import importlib
  126. import backend.app.services.plate_detection as pd_module
  127. importlib.reload(pd_module)
  128. pd_module.OPENCV_AVAILABLE = False
  129. result = pd_module.delete_calibration(1)
  130. assert result is False