fix: WireGuard peer sync, privileged mode, E2E and integration test correctness

- api/app.py: sync WireGuard server config on peer add/remove (non-fatal)
- docker-compose.yml: add privileged:true to wireguard service
- E2E tests: fix logout selector, DNS IP lookup, wg config DNS line, VIP skip guards,
  badge text selectors, heading .first, async logout wait
- Integration tests: fix 4 tests that sent unauthenticated requests expecting 400
  (now use authenticated session helpers); accept 401 as valid in webui proxy test;
  add password field to service_access validation test
- Remove stale tracked config templates (config/api/api/*, config/api/cell.env, etc.)
  that no longer exist on disk after config layout was reorganised

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 06:04:40 -04:00
parent 31a7951ffd
commit 420dced9ff
35 changed files with 101 additions and 464 deletions
+4 -20
View File
@@ -156,19 +156,11 @@ class TestPutConfigPositive:
class TestPutConfigValidation:
def test_put_config_empty_body_returns_400(self):
r = requests.put(
f"{API_BASE}/api/config",
data='',
headers={'Content-Type': 'application/json'},
)
r = put('/api/config', data='')
assert r.status_code == 400
def test_put_config_invalid_json_returns_400(self):
r = requests.put(
f"{API_BASE}/api/config",
data='not valid json }{',
headers={'Content-Type': 'application/json'},
)
r = put('/api/config', data='not valid json }{')
assert r.status_code == 400
def test_put_config_ip_range_not_rfc1918_returns_400(self):
@@ -247,19 +239,11 @@ class TestConfigExport:
class TestConfigImport:
def test_import_missing_body_returns_400(self):
r = requests.post(
f"{API_BASE}/api/config/import",
data='',
headers={'Content-Type': 'application/json'},
)
r = post('/api/config/import', data='')
assert r.status_code == 400
def test_import_invalid_json_returns_400(self):
r = requests.post(
f"{API_BASE}/api/config/import",
data='{{bad json',
headers={'Content-Type': 'application/json'},
)
r = post('/api/config/import', data='{{bad json')
assert r.status_code == 400
def test_import_valid_empty_config_does_not_crash(self):
+1
View File
@@ -258,6 +258,7 @@ class TestValidation:
r = post('/api/peers', json={
'name': 'bad-svc-peer',
'public_key': 'dummykey==',
'password': 'ValidPass123!',
'service_access': ['invalid_service'],
})
assert r.status_code == 400
+1 -5
View File
@@ -178,11 +178,7 @@ class TestDhcpReservations:
assert 'error' in r.json()
def test_add_dhcp_reservation_empty_body_returns_400(self):
r = requests.post(
f"{API_BASE}/api/dhcp/reservations",
data='',
headers={'Content-Type': 'application/json'},
)
r = post('/api/dhcp/reservations', data='')
assert r.status_code == 400
def test_delete_dhcp_reservation_missing_mac_returns_400(self):
+3 -3
View File
@@ -45,6 +45,6 @@ class TestWebUIServing:
# Verify the API is accessible (CORS / proxy config working)
r = requests.get(f"{WEBUI_BASE.rstrip('/')}/api/status".replace(
f':{80}', '').replace('///', '//'))
# The webui container proxies /api → cell-api, so this should work
# If not proxied, it might 404 — either way it shouldn't be a connection error
assert r.status_code in (200, 404, 301, 302)
# The webui container proxies /api → cell-api, so this should work.
# 401 means the API is reachable but requires auth — that's fine here.
assert r.status_code in (200, 401, 404, 301, 302)