mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-04-02 08:12:21 -07:00
feat(api): MCP, OpenAPI & Dynamic Introspection
New Features: - API endpoints now support comprehensive input validation with detailed error responses via Pydantic models. - OpenAPI specification endpoint (/openapi.json) and interactive Swagger UI documentation (/docs) now available for API discovery. - Enhanced MCP session lifecycle management with create, retrieve, and delete operations. - Network diagnostic tools: traceroute, nslookup, NMAP scanning, and network topology viewing exposed via API. - Device search, filtering by status (including 'offline'), and bulk operations (copy, delete, update). - Wake-on-LAN functionality for remote device management. - Added dynamic tool disablement and status reporting. Bug Fixes: - Fixed get_tools_status in registry to correctly return boolean values instead of None for enabled tools. - Improved error handling for invalid API inputs with standardized validation responses. - Fixed OPTIONS request handling for cross-origin requests. Refactoring: - Significant refactoring of api_server_start.py to use decorator-based validation (@validate_request).
This commit is contained in:
@@ -1,11 +1,6 @@
|
||||
import sys
|
||||
import random
|
||||
import os
|
||||
import pytest
|
||||
|
||||
INSTALL_PATH = os.getenv('NETALERTX_APP', '/app')
|
||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from helper import get_setting_value # noqa: E402 [flake8 lint suppression]
|
||||
from api_server.api_server_start import app # noqa: E402 [flake8 lint suppression]
|
||||
|
||||
@@ -106,7 +101,9 @@ def test_traceroute_device(client, api_token, test_mac):
|
||||
assert len(devices) > 0
|
||||
|
||||
# 3. Pick the first device
|
||||
device_ip = devices[0].get("devLastIP", "192.168.1.1") # fallback if dummy has no IP
|
||||
device_ip = devices[0].get("devLastIP")
|
||||
if not device_ip:
|
||||
device_ip = "192.168.1.1"
|
||||
|
||||
# 4. Call the traceroute endpoint
|
||||
resp = client.post(
|
||||
@@ -116,25 +113,20 @@ def test_traceroute_device(client, api_token, test_mac):
|
||||
)
|
||||
|
||||
# 5. Assertions
|
||||
if not device_ip or device_ip.lower() == 'invalid':
|
||||
# Expect 400 if IP is missing or invalid
|
||||
assert resp.status_code == 400
|
||||
data = resp.json
|
||||
assert data.get("success") is False
|
||||
else:
|
||||
# Expect 200 and valid traceroute output
|
||||
assert resp.status_code == 200
|
||||
data = resp.json
|
||||
assert data.get("success") is True
|
||||
assert "output" in data
|
||||
assert isinstance(data["output"], list)
|
||||
assert all(isinstance(line, str) for line in data["output"])
|
||||
|
||||
# Expect 200 and valid traceroute output
|
||||
assert resp.status_code == 200
|
||||
data = resp.json
|
||||
assert data.get("success") is True
|
||||
assert "output" in data
|
||||
assert isinstance(data["output"], list)
|
||||
assert all(isinstance(line, str) for line in data["output"])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("ip,expected_status", [
|
||||
("8.8.8.8", 200),
|
||||
("256.256.256.256", 400), # Invalid IP
|
||||
("", 400), # Missing IP
|
||||
("256.256.256.256", 422), # Invalid IP -> 422
|
||||
("", 422), # Missing IP -> 422
|
||||
])
|
||||
def test_nslookup_endpoint(client, api_token, ip, expected_status):
|
||||
payload = {"devLastIP": ip} if ip else {}
|
||||
@@ -152,13 +144,14 @@ def test_nslookup_endpoint(client, api_token, ip, expected_status):
|
||||
assert "error" in data
|
||||
|
||||
|
||||
@pytest.mark.feature_complete
|
||||
@pytest.mark.parametrize("ip,mode,expected_status", [
|
||||
("127.0.0.1", "fast", 200),
|
||||
pytest.param("127.0.0.1", "normal", 200, marks=pytest.mark.feature_complete),
|
||||
pytest.param("127.0.0.1", "detail", 200, marks=pytest.mark.feature_complete),
|
||||
("127.0.0.1", "normal", 200),
|
||||
("127.0.0.1", "detail", 200),
|
||||
("127.0.0.1", "skipdiscovery", 200),
|
||||
("127.0.0.1", "invalidmode", 400),
|
||||
("999.999.999.999", "fast", 400),
|
||||
("127.0.0.1", "invalidmode", 422),
|
||||
("999.999.999.999", "fast", 422),
|
||||
])
|
||||
def test_nmap_endpoint(client, api_token, ip, mode, expected_status):
|
||||
payload = {"scan": ip, "mode": mode}
|
||||
@@ -202,7 +195,7 @@ def test_internet_info_endpoint(client, api_token):
|
||||
|
||||
if resp.status_code == 200:
|
||||
assert data.get("success") is True
|
||||
assert isinstance(data.get("output"), dict)
|
||||
assert isinstance(data.get("output"), dict)
|
||||
assert len(data["output"]) > 0 # ensure output is not empty
|
||||
else:
|
||||
# Handle errors, e.g., curl failure
|
||||
|
||||
Reference in New Issue
Block a user