diff --git a/frontend/index.html b/frontend/index.html index c5ad8f2..a054101 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -195,7 +195,7 @@ textarea { resize: vertical; min-height: 120px; } async function load() { setStatus('Loading…'); try { - const res = await fetch('/api/v1/context', { headers: { Accept: 'application/json' } }); + const res = await fetch('api/v1/context', { headers: { Accept: 'application/json' } }); if (!res.ok) throw new Error('HTTP ' + res.status); const data = await res.json(); liveMode = true; @@ -264,7 +264,7 @@ textarea { resize: vertical; min-height: 120px; } async function loadEventStream() { setEventStreamStatus('Updating…'); try { - const res = await fetch('/api/v1/events', { headers: { Accept: 'application/json' } }); + const res = await fetch('api/v1/events', { headers: { Accept: 'application/json' } }); if (!res.ok) throw new Error('HTTP ' + res.status); paintEventStream(await res.json()); setEventStreamStatus('Updated ' + fmt(new Date())); @@ -275,7 +275,7 @@ textarea { resize: vertical; min-height: 120px; } async function tickWidgets() { try { - const res = await fetch('/api/v1/context', { headers: { Accept: 'application/json' } }); + const res = await fetch('api/v1/context', { headers: { Accept: 'application/json' } }); const data = await res.json(); qs('#layout-hint').innerHTML = '
Active view
' + escapeHtml(data.view || 'dashboard') + '
Deltas
' + (data.deltas||[]).length + '
'; } catch (e) { @@ -364,7 +364,7 @@ textarea { resize: vertical; min-height: 120px; } async function updateRepoMix() { const el = qs('#repo-mix'); try { - const res = await fetch('/api/v1/context', { headers: { Accept: 'application/json' } }); + const res = await fetch('api/v1/context', { headers: { Accept: 'application/json' } }); const data = await res.json(); const repos = data.repos || []; const issues = (data.issues||[]).filter(i=>i.state==='open'); diff --git a/tests/test_api_paths.py b/tests/test_api_paths.py new file mode 100644 index 0000000..6bdc3c7 --- /dev/null +++ b/tests/test_api_paths.py @@ -0,0 +1,20 @@ +import re +from pathlib import Path +from urllib.parse import urljoin + + +DASHBOARD_HTML = Path(__file__).parent.parent / "frontend" / "index.html" + + +def test_api_requests_resolve_inside_dashboard_subpath(): + html = DASHBOARD_HTML.read_text() + api_paths = re.findall(r"fetch\(['\"]([^'\"]*api/v1/[^'\"]*)['\"]", html) + + assert api_paths + assert { + urljoin("https://forge.alexanderwhitestone.com/dashboard/", path) + for path in api_paths + } == { + "https://forge.alexanderwhitestone.com/dashboard/api/v1/context", + "https://forge.alexanderwhitestone.com/dashboard/api/v1/events", + }