feat: add integration test suite (66 tests covering live API + services + UI)
Tests cover health, config, all 12 containers, WireGuard, DNS/DHCP/NTP, services status, peer CRUD with iptables rule verification, service_access enforcement (full/restricted/no-access), and WebUI smoke tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
"""
|
||||
WebUI smoke tests — verify the React app is served correctly.
|
||||
|
||||
These don't test UI interactions (that requires Playwright).
|
||||
They verify the static serving layer is working and the JS bundle loads.
|
||||
|
||||
Run with: pytest tests/integration/test_webui.py -v
|
||||
"""
|
||||
import requests
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
from conftest import WEBUI_BASE
|
||||
|
||||
|
||||
def get(path, **kw):
|
||||
return requests.get(f"{WEBUI_BASE}{path}", **kw)
|
||||
|
||||
|
||||
class TestWebUIServing:
|
||||
def test_root_returns_200(self):
|
||||
r = get('/')
|
||||
assert r.status_code == 200
|
||||
|
||||
def test_root_is_html(self):
|
||||
r = get('/')
|
||||
assert 'text/html' in r.headers.get('Content-Type', '')
|
||||
|
||||
def test_root_contains_react_mount(self):
|
||||
r = get('/')
|
||||
assert '<div id="root">' in r.text, "React mount point not found in index.html"
|
||||
|
||||
def test_root_references_js_bundle(self):
|
||||
r = get('/')
|
||||
assert '.js' in r.text, "No JS bundle reference found in index.html"
|
||||
|
||||
def test_spa_routing_fallback(self):
|
||||
# SPA routes that don't exist as files should still return index.html
|
||||
for path in ('/peers', '/settings', '/wireguard', '/network'):
|
||||
r = get(path)
|
||||
assert r.status_code == 200, f"SPA route {path} returned {r.status_code}"
|
||||
assert 'text/html' in r.headers.get('Content-Type', ''), \
|
||||
f"SPA route {path} didn't return HTML"
|
||||
|
||||
def test_api_reachable_from_webui_origin(self):
|
||||
# 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)
|
||||
Reference in New Issue
Block a user