Initial commit - Phase 3/4
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
0
tests/integration/api/__init__.py
Normal file
0
tests/integration/api/__init__.py
Normal file
199
tests/integration/api/test_pm3_api.py
Normal file
199
tests/integration/api/test_pm3_api.py
Normal file
@@ -0,0 +1,199 @@
|
||||
"""Integration tests for PM3 API endpoints.
|
||||
|
||||
Tests the refactored PM3 API endpoints to ensure:
|
||||
- Proper integration with PM3Service
|
||||
- Correct HTTP status codes for different error types
|
||||
- Request/response format consistency
|
||||
- Session management integration
|
||||
"""
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
from unittest.mock import patch, AsyncMock, Mock
|
||||
|
||||
from app.backend.services.pm3_service import PM3ServiceResult, PM3ServiceError
|
||||
|
||||
|
||||
class TestPM3APIStatus:
|
||||
"""Test /api/pm3/status endpoint."""
|
||||
|
||||
def test_get_status_success(self, test_client, mock_pm3_service):
|
||||
"""Test successful status retrieval."""
|
||||
# Arrange
|
||||
mock_pm3_service.get_status.return_value = PM3ServiceResult(
|
||||
success=True,
|
||||
data={
|
||||
"connected": True,
|
||||
"device_path": "/dev/ttyACM0",
|
||||
"version": "Proxmark3 v4.0",
|
||||
"session_active": False
|
||||
}
|
||||
)
|
||||
|
||||
# Act
|
||||
with patch('app.backend.api.pm3.container') as mock_container:
|
||||
mock_container.pm3_service = mock_pm3_service
|
||||
response = test_client.get("/api/pm3/status")
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["connected"] is True
|
||||
assert data["device"] == "/dev/ttyACM0"
|
||||
assert "Proxmark3" in data["version"]
|
||||
|
||||
def test_get_status_error(self, test_client, mock_pm3_service):
|
||||
"""Test status retrieval with error."""
|
||||
# Arrange
|
||||
mock_pm3_service.get_status.return_value = PM3ServiceResult(
|
||||
success=False,
|
||||
error=PM3ServiceError(
|
||||
code="status_error",
|
||||
message="Failed to query status"
|
||||
)
|
||||
)
|
||||
|
||||
# Act
|
||||
with patch('app.backend.api.pm3.container') as mock_container:
|
||||
mock_container.pm3_service = mock_pm3_service
|
||||
response = test_client.get("/api/pm3/status")
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 500
|
||||
assert "Failed to query status" in response.json()["detail"]
|
||||
|
||||
|
||||
class TestPM3APICommand:
|
||||
"""Test /api/pm3/command endpoint."""
|
||||
|
||||
def test_execute_command_success(self, test_client, mock_pm3_service):
|
||||
"""Test successful command execution."""
|
||||
# Arrange
|
||||
mock_pm3_service.execute_command.return_value = PM3ServiceResult(
|
||||
success=True,
|
||||
data={
|
||||
"output": "Proxmark3 RFID instrument",
|
||||
"command": "hw version",
|
||||
"session_id": "test-session"
|
||||
}
|
||||
)
|
||||
|
||||
# Act
|
||||
with patch('app.backend.api.pm3.container') as mock_container:
|
||||
mock_container.pm3_service = mock_pm3_service
|
||||
response = test_client.post(
|
||||
"/api/pm3/command",
|
||||
json={"command": "hw version", "session_id": "test-session"}
|
||||
)
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["success"] is True
|
||||
assert "Proxmark3" in data["output"]
|
||||
assert data["error"] is None
|
||||
|
||||
def test_execute_command_session_locked(self, test_client, mock_pm3_service):
|
||||
"""Test command execution with session locked."""
|
||||
# Arrange
|
||||
mock_pm3_service.execute_command.return_value = PM3ServiceResult(
|
||||
success=False,
|
||||
error=PM3ServiceError(
|
||||
code="session_locked",
|
||||
message="Another session is active"
|
||||
)
|
||||
)
|
||||
|
||||
# Act
|
||||
with patch('app.backend.api.pm3.container') as mock_container:
|
||||
mock_container.pm3_service = mock_pm3_service
|
||||
response = test_client.post(
|
||||
"/api/pm3/command",
|
||||
json={"command": "hw version", "session_id": "test-session"}
|
||||
)
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 423 # Locked
|
||||
assert "Another session is active" in response.json()["detail"]
|
||||
|
||||
def test_execute_command_pm3_not_connected(self, test_client, mock_pm3_service):
|
||||
"""Test command execution when PM3 not connected."""
|
||||
# Arrange
|
||||
mock_pm3_service.execute_command.return_value = PM3ServiceResult(
|
||||
success=False,
|
||||
error=PM3ServiceError(
|
||||
code="pm3_not_connected",
|
||||
message="Proxmark3 not connected"
|
||||
)
|
||||
)
|
||||
|
||||
# Act
|
||||
with patch('app.backend.api.pm3.container') as mock_container:
|
||||
mock_container.pm3_service = mock_pm3_service
|
||||
response = test_client.post(
|
||||
"/api/pm3/command",
|
||||
json={"command": "hw version"}
|
||||
)
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200 # Returns in body, not HTTP error
|
||||
data = response.json()
|
||||
assert data["success"] is False
|
||||
assert "not connected" in data["error"].lower()
|
||||
|
||||
|
||||
class TestPM3APIConnection:
|
||||
"""Test PM3 connection endpoints."""
|
||||
|
||||
def test_connect_success(self, test_client, mock_pm3_service):
|
||||
"""Test successful PM3 connection."""
|
||||
# Arrange
|
||||
mock_pm3_service.connect.return_value = PM3ServiceResult(
|
||||
success=True,
|
||||
data={"message": "Connected to Proxmark3"}
|
||||
)
|
||||
|
||||
# Act
|
||||
with patch('app.backend.api.pm3.container') as mock_container:
|
||||
mock_container.pm3_service = mock_pm3_service
|
||||
response = test_client.post("/api/pm3/connect")
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
assert response.json()["success"] is True
|
||||
|
||||
def test_connect_failure(self, test_client, mock_pm3_service):
|
||||
"""Test PM3 connection failure."""
|
||||
# Arrange
|
||||
mock_pm3_service.connect.return_value = PM3ServiceResult(
|
||||
success=False,
|
||||
error=PM3ServiceError(
|
||||
code="connection_error",
|
||||
message="Device not found"
|
||||
)
|
||||
)
|
||||
|
||||
# Act
|
||||
with patch('app.backend.api.pm3.container') as mock_container:
|
||||
mock_container.pm3_service = mock_pm3_service
|
||||
response = test_client.post("/api/pm3/connect")
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 503
|
||||
assert "Device not found" in response.json()["detail"]
|
||||
|
||||
def test_disconnect_success(self, test_client, mock_pm3_service):
|
||||
"""Test successful PM3 disconnection."""
|
||||
# Arrange
|
||||
mock_pm3_service.disconnect.return_value = PM3ServiceResult(
|
||||
success=True,
|
||||
data={"message": "Disconnected from Proxmark3"}
|
||||
)
|
||||
|
||||
# Act
|
||||
with patch('app.backend.api.pm3.container') as mock_container:
|
||||
mock_container.pm3_service = mock_pm3_service
|
||||
response = test_client.post("/api/pm3/disconnect")
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
assert response.json()["success"] is True
|
||||
Reference in New Issue
Block a user