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:
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_self_purge_logic():
"""
Verifies that a node can deregister itself using its invite_token via the /purge endpoint.
"""
user_id = _get_user_id()
node_id = f"purge-test-{uuid.uuid4().hex[:8]}"
payload = {
"node_id": node_id,
"display_name": "Purge Test Node",
"is_active": True,
"skill_config": {"shell": {"enabled": True}}
}
with httpx.Client(timeout=15.0) as client:
# 1. Register the node
r_create = client.post(f"{BASE_URL}/nodes/admin", params={"admin_id": user_id}, json=payload, headers=_headers())
assert r_create.status_code == 200
node_data = r_create.json()
invite_token = node_data["invite_token"]
# Verify it exists
r_check = client.get(f"{BASE_URL}/nodes/admin/{node_id}", params={"admin_id": user_id}, headers=_headers())
assert r_check.status_code == 200
# 2. Attempt purge with INVALID token
r_fail = client.post(f"{BASE_URL}/nodes/purge", params={"node_id": node_id, "token": "wrong-token"})
assert r_fail.status_code == 401
# 3. Attempt purge with VALID token
r_purge = client.post(f"{BASE_URL}/nodes/purge", params={"node_id": node_id, "token": invite_token})
assert r_purge.status_code == 200
assert "deregistered" in r_purge.json()["message"]
# 4. Verify the node is GONE from the Hub
r_gone = client.get(f"{BASE_URL}/nodes/admin/{node_id}", params={"admin_id": user_id}, headers=_headers())
assert r_gone.status_code == 404
# 5. Verify it's gone from the mesh registry (indirectly)
r_list = client.get(f"{BASE_URL}/nodes/admin", params={"admin_id": user_id}, headers=_headers())
assert not any(n["node_id"] == node_id for n in r_list.json())
def test_purge_non_existent_node():
with httpx.Client() as client:
r = client.post(f"{BASE_URL}/nodes/purge", params={"node_id": "ghost-node", "token": "any"})
assert r.status_code == 401