Add user profiles with node adoption via /v1/adoptions endpoint

Move adopt/release from profile routes to dedicated /v1/adoptions endpoint.
Node API now returns adopted_by field. Profile page shows read-only adopted
nodes. Node detail page has adopt/release buttons (operator adopts, admin
can release any). Admin release bypasses ownership check.
This commit is contained in:
Louis King
2026-04-30 00:07:49 +01:00
parent 6a5a23845f
commit 31418e6847
39 changed files with 1849 additions and 174 deletions
+28
View File
@@ -22,6 +22,21 @@ class TestListNodes:
assert data["items"][0]["public_key"] == sample_node.public_key
assert data["items"][0]["name"] == sample_node.name
assert "tags" in data["items"][0]
assert data["items"][0]["adopted_by"] is None
def test_list_nodes_with_adopted_node(
self, client_no_auth, sample_node, sample_user_profile, sample_adopted_node
):
"""Test listing nodes includes adopted_by info."""
response = client_no_auth.get("/api/v1/nodes")
assert response.status_code == 200
data = response.json()
assert len(data["items"]) == 1
adopted_by = data["items"][0]["adopted_by"]
assert adopted_by is not None
assert adopted_by["user_id"] == "oidc-user-123"
assert adopted_by["name"] == "Test User"
assert adopted_by["callsign"] == "W1TEST"
def test_list_nodes_includes_tags(
self, client_no_auth, sample_node, sample_node_tag
@@ -180,6 +195,19 @@ class TestGetNode:
assert data["name"] == sample_node.name
assert "tags" in data
assert data["tags"] == []
assert data["adopted_by"] is None
def test_get_node_with_adoption(
self, client_no_auth, sample_node, sample_user_profile, sample_adopted_node
):
"""Test getting a node shows adopted_by info."""
response = client_no_auth.get(f"/api/v1/nodes/{sample_node.public_key}")
assert response.status_code == 200
data = response.json()
assert data["adopted_by"] is not None
assert data["adopted_by"]["user_id"] == "oidc-user-123"
assert data["adopted_by"]["name"] == "Test User"
assert data["adopted_by"]["callsign"] == "W1TEST"
def test_get_node_with_tags(self, client_no_auth, sample_node, sample_node_tag):
"""Test getting a node includes its tags."""