test_discovery_api.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. """Integration tests for Discovery API endpoints.
  2. Tests the full request/response cycle for /api/v1/discovery/ endpoints.
  3. """
  4. import pytest
  5. from httpx import AsyncClient
  6. class TestDiscoveryAPI:
  7. """Integration tests for /api/v1/discovery/ endpoints."""
  8. # ========================================================================
  9. # Info endpoint
  10. # ========================================================================
  11. @pytest.mark.asyncio
  12. @pytest.mark.integration
  13. async def test_get_discovery_info(self, async_client: AsyncClient):
  14. """Verify discovery info endpoint returns expected fields."""
  15. response = await async_client.get("/api/v1/discovery/info")
  16. assert response.status_code == 200
  17. data = response.json()
  18. assert "is_docker" in data
  19. assert "ssdp_running" in data
  20. assert "scan_running" in data
  21. assert isinstance(data["is_docker"], bool)
  22. assert isinstance(data["ssdp_running"], bool)
  23. assert isinstance(data["scan_running"], bool)
  24. # ========================================================================
  25. # SSDP Discovery endpoints
  26. # ========================================================================
  27. @pytest.mark.asyncio
  28. @pytest.mark.integration
  29. async def test_get_discovery_status(self, async_client: AsyncClient):
  30. """Verify SSDP discovery status endpoint works."""
  31. response = await async_client.get("/api/v1/discovery/status")
  32. assert response.status_code == 200
  33. data = response.json()
  34. assert "running" in data
  35. assert isinstance(data["running"], bool)
  36. @pytest.mark.asyncio
  37. @pytest.mark.integration
  38. async def test_start_discovery(self, async_client: AsyncClient):
  39. """Verify SSDP discovery can be started."""
  40. response = await async_client.post("/api/v1/discovery/start?duration=1.0")
  41. assert response.status_code == 200
  42. data = response.json()
  43. assert "running" in data
  44. @pytest.mark.asyncio
  45. @pytest.mark.integration
  46. async def test_stop_discovery(self, async_client: AsyncClient):
  47. """Verify SSDP discovery can be stopped."""
  48. response = await async_client.post("/api/v1/discovery/stop")
  49. assert response.status_code == 200
  50. data = response.json()
  51. assert "running" in data
  52. assert data["running"] is False
  53. @pytest.mark.asyncio
  54. @pytest.mark.integration
  55. async def test_get_discovered_printers_empty(self, async_client: AsyncClient):
  56. """Verify empty list when no printers discovered."""
  57. response = await async_client.get("/api/v1/discovery/printers")
  58. assert response.status_code == 200
  59. data = response.json()
  60. assert isinstance(data, list)
  61. # ========================================================================
  62. # Subnet scanning endpoints
  63. # ========================================================================
  64. @pytest.mark.asyncio
  65. @pytest.mark.integration
  66. async def test_start_subnet_scan(self, async_client: AsyncClient):
  67. """Verify subnet scan can be started."""
  68. response = await async_client.post(
  69. "/api/v1/discovery/scan",
  70. json={"subnet": "192.168.1.0/30", "timeout": 0.1}, # Small subnet for testing
  71. )
  72. assert response.status_code == 200
  73. data = response.json()
  74. assert "running" in data
  75. assert "scanned" in data
  76. assert "total" in data
  77. @pytest.mark.asyncio
  78. @pytest.mark.integration
  79. async def test_get_scan_status(self, async_client: AsyncClient):
  80. """Verify subnet scan status endpoint works."""
  81. response = await async_client.get("/api/v1/discovery/scan/status")
  82. assert response.status_code == 200
  83. data = response.json()
  84. assert "running" in data
  85. assert "scanned" in data
  86. assert "total" in data
  87. @pytest.mark.asyncio
  88. @pytest.mark.integration
  89. async def test_stop_subnet_scan(self, async_client: AsyncClient):
  90. """Verify subnet scan can be stopped."""
  91. response = await async_client.post("/api/v1/discovery/scan/stop")
  92. assert response.status_code == 200
  93. data = response.json()
  94. assert "running" in data
  95. @pytest.mark.asyncio
  96. @pytest.mark.integration
  97. async def test_subnet_scan_invalid_subnet(self, async_client: AsyncClient):
  98. """Verify invalid subnet format is rejected."""
  99. response = await async_client.post("/api/v1/discovery/scan", json={"subnet": "invalid-subnet", "timeout": 1.0})
  100. # Should return 422 validation error or 200 with empty results
  101. assert response.status_code in [200, 422]
  102. class TestDiscoveryService:
  103. """Unit tests for discovery service functionality."""
  104. @pytest.mark.asyncio
  105. @pytest.mark.integration
  106. async def test_docker_detection_fields(self, async_client: AsyncClient):
  107. """Verify Docker detection returns consistent response."""
  108. # Call multiple times to ensure consistency
  109. response1 = await async_client.get("/api/v1/discovery/info")
  110. response2 = await async_client.get("/api/v1/discovery/info")
  111. assert response1.status_code == 200
  112. assert response2.status_code == 200
  113. assert response1.json()["is_docker"] == response2.json()["is_docker"]