test_plate_detection.py 6.6 KB

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