fix: apply hidden sessions filter to all sessions including remote/federated
This commit is contained in:
@@ -521,8 +521,8 @@ function buildStatusTileHTML(deviceName, statusText, statusClass) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns sessions with hidden session names removed.
|
* Returns sessions with hidden session names removed.
|
||||||
* Only hides LOCAL sessions (those with no remoteId) matching the
|
* Hides any session whose name appears in the hidden_sessions list,
|
||||||
* hidden_sessions list. Remote sessions with the same name remain visible.
|
* regardless of whether it is local or remote (federated).
|
||||||
* Consolidates the hidden-session filter used by all render paths.
|
* Consolidates the hidden-session filter used by all render paths.
|
||||||
* @param {object[]} sessions
|
* @param {object[]} sessions
|
||||||
* @returns {object[]}
|
* @returns {object[]}
|
||||||
@@ -530,7 +530,7 @@ function buildStatusTileHTML(deviceName, statusText, statusClass) {
|
|||||||
function getVisibleSessions(sessions) {
|
function getVisibleSessions(sessions) {
|
||||||
var hidden = (_serverSettings && _serverSettings.hidden_sessions) || [];
|
var hidden = (_serverSettings && _serverSettings.hidden_sessions) || [];
|
||||||
return (sessions || []).filter(function(s) {
|
return (sessions || []).filter(function(s) {
|
||||||
if (hidden.length > 0 && s.remoteId == null && hidden.includes(s.name)) {
|
if (hidden.length > 0 && hidden.includes(s.name)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -2442,26 +2442,21 @@ test('getVisibleSessions exported and filters hidden sessions', () => {
|
|||||||
app._setServerSettings(null);
|
app._setServerSettings(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getVisibleSessions hides local sessions by name but not remote sessions with same name', () => {
|
test('getVisibleSessions hides remote sessions with matching name (federation-aware)', () => {
|
||||||
// Set server settings with a session name that exists both locally and remotely
|
// hidden_sessions syncs across federation nodes, so the filter must apply to
|
||||||
|
// ALL sessions regardless of remoteId — both local and federated.
|
||||||
app._setServerSettings({ hidden_sessions: ['shared-name'] });
|
app._setServerSettings({ hidden_sessions: ['shared-name'] });
|
||||||
|
|
||||||
const sessions = [
|
const sessions = [
|
||||||
{ name: 'shared-name' }, // local (no remoteId) — should be hidden
|
{ name: 'shared-name' }, // local (no remoteId) — should be hidden
|
||||||
{ name: 'shared-name', remoteId: 1 }, // remote — should remain visible
|
{ name: 'shared-name', remoteId: 1 }, // remote — should ALSO be hidden
|
||||||
{ name: 'another' }, // local, not in hidden list — should remain
|
{ name: 'another' }, // local, not in hidden list — should remain
|
||||||
];
|
];
|
||||||
|
|
||||||
const result = app.getVisibleSessions(sessions);
|
const result = app.getVisibleSessions(sessions);
|
||||||
assert.strictEqual(result.length, 2, 'should show 2 sessions (remote + another)');
|
assert.strictEqual(result.length, 1, 'should show only 1 session (another); both local and remote shared-name are hidden');
|
||||||
// The remote one should survive
|
|
||||||
const remote = result.find((s) => s.remoteId === 1);
|
|
||||||
assert.ok(remote, 'remote session with same name should not be hidden');
|
|
||||||
assert.strictEqual(remote.name, 'shared-name', 'remote session name should be shared-name');
|
|
||||||
// The local one should be hidden
|
|
||||||
assert.ok(!result.some((s) => !s.remoteId && s.name === 'shared-name'), 'local session with hidden name should be removed');
|
|
||||||
// another should remain
|
|
||||||
assert.ok(result.some((s) => s.name === 'another'), 'another should remain visible');
|
assert.ok(result.some((s) => s.name === 'another'), 'another should remain visible');
|
||||||
|
assert.ok(!result.some((s) => s.name === 'shared-name'), 'all sessions named shared-name (local or remote) should be hidden');
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
app._setServerSettings(null);
|
app._setServerSettings(null);
|
||||||
@@ -4622,23 +4617,26 @@ test('getDisplaySettings reads display keys from _serverSettings with DISPLAY_DE
|
|||||||
|
|
||||||
// --- getVisibleSessions: remoteId=0 falsy-zero bug fix ---
|
// --- getVisibleSessions: remoteId=0 falsy-zero bug fix ---
|
||||||
|
|
||||||
test('getVisibleSessions does NOT hide sessions with remoteId 0 whose name is in hidden_sessions', () => {
|
test('getVisibleSessions hides remote sessions with remoteId=0 when name is in hidden_sessions', () => {
|
||||||
|
// The filter no longer guards on remoteId — hidden_sessions applies to all sessions,
|
||||||
|
// local and federated alike (settings now sync across nodes).
|
||||||
app._setServerSettings({ hidden_sessions: ['work'] });
|
app._setServerSettings({ hidden_sessions: ['work'] });
|
||||||
const sessions = [{ name: 'work', remoteId: 0 }];
|
const sessions = [{ name: 'work', remoteId: 0 }];
|
||||||
const visible = app.getVisibleSessions(sessions);
|
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');
|
assert.strictEqual(visible.length, 0, 'session with remoteId=0 must be hidden when its name is in hidden_sessions');
|
||||||
app._setServerSettings(null);
|
app._setServerSettings(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getVisibleSessions hides local session (remoteId null) but keeps remote session (remoteId 0) with same name', () => {
|
test('getVisibleSessions hides all sessions (local and remoteId=0) with names in hidden_sessions', () => {
|
||||||
|
// Both the local session (remoteId=null) and the remote session (remoteId=0)
|
||||||
|
// should be hidden when hidden_sessions syncs across federation nodes.
|
||||||
app._setServerSettings({ hidden_sessions: ['work'] });
|
app._setServerSettings({ hidden_sessions: ['work'] });
|
||||||
const sessions = [
|
const sessions = [
|
||||||
{ name: 'work', remoteId: null },
|
{ name: 'work', remoteId: null },
|
||||||
{ name: 'work', remoteId: 0 },
|
{ name: 'work', remoteId: 0 },
|
||||||
];
|
];
|
||||||
const visible = app.getVisibleSessions(sessions);
|
const visible = app.getVisibleSessions(sessions);
|
||||||
assert.strictEqual(visible.length, 1, 'only the remote session (remoteId=0) should be visible');
|
assert.strictEqual(visible.length, 0, 'both local and remote sessions named "work" should be hidden');
|
||||||
assert.strictEqual(visible[0].remoteId, 0, 'the visible session must be the remote one with remoteId=0');
|
|
||||||
app._setServerSettings(null);
|
app._setServerSettings(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2715,9 +2715,13 @@ def test_bind_sidebar_click_away_calls_patch_server_setting() -> None:
|
|||||||
# ─── task-1: getVisibleSessions falsy-0 bug fix ────────────────────────────
|
# ─── task-1: getVisibleSessions falsy-0 bug fix ────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
def test_get_visible_sessions_uses_null_check_not_falsy() -> None:
|
def test_get_visible_sessions_has_no_remote_id_filter() -> None:
|
||||||
"""getVisibleSessions must use s.remoteId == null (not !s.remoteId) to avoid
|
"""getVisibleSessions must not check s.remoteId at all.
|
||||||
treating remoteId=0 (first remote instance) as falsy and incorrectly hiding it."""
|
|
||||||
|
After federation settings sync, hidden_sessions applies to both local and
|
||||||
|
remote sessions. The filter must check session name only, with no remoteId
|
||||||
|
guard. Must also not use !s.remoteId which would treat remoteId=0 as falsy.
|
||||||
|
"""
|
||||||
match = re.search(
|
match = re.search(
|
||||||
r"function getVisibleSessions\s*\(\w+\)\s*\{(.*?)(?=\n(?:function|//|window\.))",
|
r"function getVisibleSessions\s*\(\w+\)\s*\{(.*?)(?=\n(?:function|//|window\.))",
|
||||||
_JS,
|
_JS,
|
||||||
@@ -2727,11 +2731,11 @@ def test_get_visible_sessions_uses_null_check_not_falsy() -> None:
|
|||||||
body = match.group(1)
|
body = match.group(1)
|
||||||
assert "!s.remoteId" not in body, (
|
assert "!s.remoteId" not in body, (
|
||||||
"getVisibleSessions must NOT use '!s.remoteId' — this treats remoteId=0 as falsy, "
|
"getVisibleSessions must NOT use '!s.remoteId' — this treats remoteId=0 as falsy, "
|
||||||
"hiding the first remote instance. Use 's.remoteId == null' instead."
|
"hiding the first remote instance."
|
||||||
)
|
)
|
||||||
assert "s.remoteId == null" in body or "s.remoteId === null" in body, (
|
assert "s.remoteId" not in body, (
|
||||||
"getVisibleSessions must use 's.remoteId == null' (or '=== null') to correctly treat "
|
"getVisibleSessions must NOT reference s.remoteId at all — the filter applies to "
|
||||||
"remoteId=0 as a real remote while matching null/undefined as local sessions."
|
"all sessions regardless of origin (local or federated)."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user