feat: support subpath mount via reverse proxy — v0.50.67 (PR #588 by @vcavichini)
Squash-merges feature from PR #588 by @vcavichini. Dynamic <base href> injection + api() helper slash-stripping enables deploying hermes-webui behind a reverse proxy at any subpath without configuration. Also fixes pre-existing bug: api/upload was using location.origin instead of location.href (closes #596). Co-authored-by: vcavichini <vcavichini@users.noreply.github.com>
This commit is contained in:
@@ -47,8 +47,8 @@ class TestMediaRenderMdStash(unittest.TestCase):
|
||||
"restore pass must produce download link for non-image files")
|
||||
|
||||
def test_media_api_url_pattern(self):
|
||||
self.assertIn("/api/media?path=", UI_JS,
|
||||
"renderMd must build /api/media?path=... URL for local files")
|
||||
self.assertIn("api/media?path=", UI_JS,
|
||||
"renderMd must build api/media?path=... URL for local files")
|
||||
|
||||
def test_media_stash_uses_null_byte_token(self):
|
||||
self.assertIn("\\x00D", UI_JS,
|
||||
|
||||
@@ -13,7 +13,7 @@ def test_index_contains_onboarding_overlay_markup():
|
||||
assert 'id="onboardingOverlay"' in html
|
||||
assert 'id="onboardingBody"' in html
|
||||
assert 'id="onboardingNextBtn"' in html
|
||||
assert 'src="/static/onboarding.js"' in html
|
||||
assert 'src="static/onboarding.js"' in html
|
||||
|
||||
|
||||
def test_onboarding_css_rules_exist():
|
||||
|
||||
@@ -94,7 +94,7 @@ def test_cancel_button_in_html(cleanup_test_sessions):
|
||||
def test_cancel_function_in_boot_js(cleanup_test_sessions):
|
||||
src, _ = get_text("/static/boot.js")
|
||||
assert "async function cancelStream(" in src
|
||||
assert "/api/chat/cancel" in src
|
||||
assert "api/chat/cancel" in src
|
||||
|
||||
# ── Cron history ───────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ def test_boot_js_browser_unsupported_guard_uses_fallback_capabilities():
|
||||
def test_boot_js_media_recorder_fallback_posts_to_transcribe_api():
|
||||
"""Desktop fallback must send recorded audio to /api/transcribe for transcription."""
|
||||
js, _ = get_text("/static/boot.js")
|
||||
assert '/api/transcribe' in js
|
||||
assert 'api/transcribe' in js
|
||||
assert 'fetch(' in js
|
||||
|
||||
|
||||
|
||||
@@ -67,20 +67,20 @@ def test_boot_js_served(cleanup_test_sessions):
|
||||
def test_app_js_no_longer_referenced_in_html(cleanup_test_sessions):
|
||||
"""index.html must not reference the old monolithic app.js."""
|
||||
html = get_text("/")
|
||||
assert 'src="/static/app.js"' not in html
|
||||
assert 'src="static/app.js"' not in html
|
||||
# All 6 modules must be present
|
||||
for module in ["ui.js", "workspace.js", "sessions.js", "messages.js", "panels.js", "boot.js"]:
|
||||
assert f'src="/static/{module}"' in html, f"Missing {module} in index.html"
|
||||
assert f'src="static/{module}"' in html, f"Missing {module} in index.html"
|
||||
|
||||
def test_module_load_order_correct(cleanup_test_sessions):
|
||||
"""ui.js must appear before sessions.js which must appear before boot.js."""
|
||||
html = get_text("/")
|
||||
ui_pos = html.find('src="/static/ui.js"')
|
||||
ws_pos = html.find('src="/static/workspace.js"')
|
||||
sess_pos = html.find('src="/static/sessions.js"')
|
||||
msg_pos = html.find('src="/static/messages.js"')
|
||||
panels_pos = html.find('src="/static/panels.js"')
|
||||
boot_pos = html.find('src="/static/boot.js"')
|
||||
ui_pos = html.find('src="static/ui.js"')
|
||||
ws_pos = html.find('src="static/workspace.js"')
|
||||
sess_pos = html.find('src="static/sessions.js"')
|
||||
msg_pos = html.find('src="static/messages.js"')
|
||||
panels_pos = html.find('src="static/panels.js"')
|
||||
boot_pos = html.find('src="static/boot.js"')
|
||||
assert ui_pos < ws_pos < sess_pos < msg_pos < panels_pos < boot_pos
|
||||
|
||||
def test_no_duplicate_function_definitions(cleanup_test_sessions):
|
||||
|
||||
Reference in New Issue
Block a user