import os
import httpx
import pytest
import uuid
BASE_URL = os.getenv("SYNC_TEST_BASE_URL", "http://127.0.0.1:8002/api/v1")
def _get_user_id() -> str:
"""Gets the active super-admin or test runner user ID."""
return os.getenv("SYNC_TEST_USER_ID", "c4401d34-8784-4d6e-93a0-c702bd202b66")
def _headers():
return {"X-User-ID": _get_user_id(), "Authorization": os.getenv("SYNC_TEST_AUTH_TOKEN", "")}
def test_node_registration_flow():
"""
Tests the Node Registration API flow from an Administrator standpoint.
1. Registers a new test node with a unique ID and proper skill configurations.
2. Verifies an invite token is generated strictly successfully.
3. Confirms the Node metadata correctly persists and is accessible via the admin listing endpoint.
"""
user_id = _get_user_id()
node_id = f"test-integration-node-{uuid.uuid4().hex[:8]}"
display_name = f"Integration {node_id}"
payload = {
"node_id": node_id,
"display_name": display_name,
"is_active": True,
"skill_config": {"shell": {"enabled": True}, "sync": {"enabled": True}}
}
with httpx.Client(timeout=15.0) as client:
# Step 1: Register New Node
r_node = client.post(
f"{BASE_URL}/nodes/admin",
params={"admin_id": user_id},
json=payload,
headers=_headers()
)
assert r_node.status_code == 200, f"Node registration failed unexpectedly: {r_node.text}"
node_data = r_node.json()
assert node_data["node_id"] == node_id, "Payload collision: Returned node ID parameter does not match registration generation."
assert "invite_token" in node_data, "Critcal field drop: Invite token completely absent in valid creation serialization response"
assert len(node_data["invite_token"]) > 0, "Invite token string resolved fully blank."
# Step 2: Ensure Node exists natively in the database via the admin nodes listing
r_list = client.get(
f"{BASE_URL}/nodes/admin",
params={"admin_id": user_id},
headers=_headers()
)
assert r_list.status_code == 200, "Node listing retrieval critically failed."
node_list = r_list.json()
# Find our freshly pushed node in the complete node listing array map
matched_node = next((n for n in node_list if n["node_id"] == node_id), None)
assert matched_node is not None, "Node completely failed to persist across DB contexts despite positive returned 200 serialization creation code."
assert matched_node["display_name"] == display_name, "Node display name persisted to DB unaligned."
assert matched_node["is_active"] is True, "Node default is_active flag failed persistence"