diff --git a/muxplex/frontend/app.js b/muxplex/frontend/app.js index 8393a27..5a503b2 100644 --- a/muxplex/frontend/app.js +++ b/muxplex/frontend/app.js @@ -530,7 +530,7 @@ function buildStatusTileHTML(deviceName, statusText, statusClass) { function getVisibleSessions(sessions) { var hidden = (_serverSettings && _serverSettings.hidden_sessions) || []; return (sessions || []).filter(function(s) { - if (hidden.length > 0 && !s.remoteId && hidden.includes(s.name)) { + if (hidden.length > 0 && s.remoteId == null && hidden.includes(s.name)) { return false; } return true; diff --git a/muxplex/frontend/tests/test_app.mjs b/muxplex/frontend/tests/test_app.mjs index 00bb39e..536d8bb 100644 --- a/muxplex/frontend/tests/test_app.mjs +++ b/muxplex/frontend/tests/test_app.mjs @@ -4619,3 +4619,25 @@ test('getDisplaySettings reads display keys from _serverSettings with DISPLAY_DE assert.ok(!('unknownKey' in ds), 'getDisplaySettings must not include keys not in DISPLAY_DEFAULTS'); app._setServerSettings(null); }); + +// --- getVisibleSessions: remoteId=0 falsy-zero bug fix --- + +test('getVisibleSessions does NOT hide sessions with remoteId 0 whose name is in hidden_sessions', () => { + app._setServerSettings({ hidden_sessions: ['work'] }); + const sessions = [{ name: 'work', remoteId: 0 }]; + const visible = app.getVisibleSessions(sessions); + assert.strictEqual(visible.length, 1, 'session with remoteId=0 must NOT be hidden even if name is in hidden_sessions'); + app._setServerSettings(null); +}); + +test('getVisibleSessions hides local session (remoteId null) but keeps remote session (remoteId 0) with same name', () => { + app._setServerSettings({ hidden_sessions: ['work'] }); + const sessions = [ + { name: 'work', remoteId: null }, + { name: 'work', remoteId: 0 }, + ]; + const visible = app.getVisibleSessions(sessions); + assert.strictEqual(visible.length, 1, 'only the remote session (remoteId=0) should be visible'); + assert.strictEqual(visible[0].remoteId, 0, 'the visible session must be the remote one with remoteId=0'); + app._setServerSettings(null); +}); diff --git a/muxplex/tests/test_frontend_js.py b/muxplex/tests/test_frontend_js.py index 528f714..866121e 100644 --- a/muxplex/tests/test_frontend_js.py +++ b/muxplex/tests/test_frontend_js.py @@ -2710,3 +2710,26 @@ def test_bind_sidebar_click_away_calls_patch_server_setting() -> None: assert "patchServerSetting" in body, ( "bindSidebarClickAway must call patchServerSetting to persist collapsed state" ) + + +# ─── task-1: getVisibleSessions falsy-0 bug fix ──────────────────────────── + + +def test_get_visible_sessions_uses_null_check_not_falsy() -> None: + """getVisibleSessions must use s.remoteId == null (not !s.remoteId) to avoid + treating remoteId=0 (first remote instance) as falsy and incorrectly hiding it.""" + match = re.search( + r"function getVisibleSessions\s*\(\w+\)\s*\{(.*?)(?=\n(?:function|//|window\.))", + _JS, + re.DOTALL, + ) + assert match, "getVisibleSessions function not found in app.js" + body = match.group(1) + assert "!s.remoteId" not in body, ( + "getVisibleSessions must NOT use '!s.remoteId' — this treats remoteId=0 as falsy, " + "hiding the first remote instance. Use 's.remoteId == null' instead." + ) + assert "s.remoteId == null" in body or "s.remoteId === null" in body, ( + "getVisibleSessions must use 's.remoteId == null' (or '=== null') to correctly treat " + "remoteId=0 as a real remote while matching null/undefined as local sessions." + )