feat: update getVisibleSessions to only hide local sessions by name
- Replace getVisibleSessions filter logic: only hide sessions where sourceUrl is empty/absent AND name matches hidden_sessions list - Remote sessions with the same name as a hidden local session now remain visible (task-7 spec requirement) - Export getVisibleSessions in module.exports so tests can access it Tests added: - 'getVisibleSessions exported and filters hidden sessions': verifies export and that local hidden sessions are filtered - 'getVisibleSessions hides local sessions by name but not remote sessions with same name': verifies remote sessions survive All 155 tests pass.
This commit is contained in:
+10
-2
@@ -520,13 +520,20 @@ function buildSidebarHTML(session, currentSession) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns sessions with hidden session names removed.
|
* Returns sessions with hidden session names removed.
|
||||||
|
* Only hides LOCAL sessions (those with empty/absent sourceUrl) matching the
|
||||||
|
* hidden_sessions list. Remote sessions with the same name remain visible.
|
||||||
* 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[]}
|
||||||
*/
|
*/
|
||||||
function getVisibleSessions(sessions) {
|
function getVisibleSessions(sessions) {
|
||||||
const hidden = (_serverSettings && _serverSettings.hidden_sessions) || [];
|
var hidden = (_serverSettings && _serverSettings.hidden_sessions) || [];
|
||||||
return (sessions || []).filter((s) => !hidden.includes(s.name));
|
return (sessions || []).filter(function(s) {
|
||||||
|
if (hidden.length > 0 && (!s.sourceUrl) && hidden.includes(s.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1821,6 +1828,7 @@ if (typeof module !== 'undefined' && module.exports) {
|
|||||||
escapeHtml,
|
escapeHtml,
|
||||||
buildTileHTML,
|
buildTileHTML,
|
||||||
buildSidebarHTML,
|
buildSidebarHTML,
|
||||||
|
getVisibleSessions,
|
||||||
renderSidebar,
|
renderSidebar,
|
||||||
initSidebar,
|
initSidebar,
|
||||||
toggleSidebar,
|
toggleSidebar,
|
||||||
|
|||||||
@@ -2285,6 +2285,59 @@ test('pollSessions sets auth_required on 401 response', async () => {
|
|||||||
app._setSources([]);
|
app._setSources([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- getVisibleSessions (task-7) ---
|
||||||
|
|
||||||
|
test('getVisibleSessions exported and filters hidden sessions', () => {
|
||||||
|
// Verify getVisibleSessions is exported as a function
|
||||||
|
assert.strictEqual(typeof app.getVisibleSessions, 'function', 'getVisibleSessions should be exported as a function');
|
||||||
|
|
||||||
|
// Set up server settings with hidden_sessions
|
||||||
|
app._setServerSettings({ hidden_sessions: ['secret', 'hidden-local'] });
|
||||||
|
|
||||||
|
// Local sessions (no sourceUrl) matching hidden list should be filtered
|
||||||
|
const sessions = [
|
||||||
|
{ name: 'visible', sourceUrl: '' },
|
||||||
|
{ name: 'secret', sourceUrl: '' }, // local, should be hidden
|
||||||
|
{ name: 'hidden-local', sourceUrl: '' }, // local, should be hidden
|
||||||
|
{ name: 'other', sourceUrl: '' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const result = app.getVisibleSessions(sessions);
|
||||||
|
assert.strictEqual(result.length, 2, 'should hide 2 local sessions matching the hidden list');
|
||||||
|
assert.ok(result.some((s) => s.name === 'visible'), 'visible should remain');
|
||||||
|
assert.ok(result.some((s) => s.name === 'other'), 'other should remain');
|
||||||
|
assert.ok(!result.some((s) => s.name === 'secret'), 'secret (local) should be hidden');
|
||||||
|
assert.ok(!result.some((s) => s.name === 'hidden-local'), 'hidden-local should be hidden');
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
app._setServerSettings(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getVisibleSessions hides local sessions by name but not remote sessions with same name', () => {
|
||||||
|
// Set server settings with a session name that exists both locally and remotely
|
||||||
|
app._setServerSettings({ hidden_sessions: ['shared-name'] });
|
||||||
|
|
||||||
|
const sessions = [
|
||||||
|
{ name: 'shared-name', sourceUrl: '' }, // local — should be hidden
|
||||||
|
{ name: 'shared-name', sourceUrl: 'https://remote.example.com' }, // remote — should remain visible
|
||||||
|
{ name: 'another', sourceUrl: '' }, // local, not in hidden list — should remain
|
||||||
|
];
|
||||||
|
|
||||||
|
const result = app.getVisibleSessions(sessions);
|
||||||
|
assert.strictEqual(result.length, 2, 'should show 2 sessions (remote + another)');
|
||||||
|
// The remote one should survive
|
||||||
|
const remote = result.find((s) => s.sourceUrl === 'https://remote.example.com');
|
||||||
|
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.sourceUrl === '' && 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');
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
app._setServerSettings(null);
|
||||||
|
});
|
||||||
|
|
||||||
test('pollSessions sets unreachable and applies exponential backoff on network error', async () => {
|
test('pollSessions sets unreachable and applies exponential backoff on network error', async () => {
|
||||||
const mockStatusEl = { textContent: '', className: '' };
|
const mockStatusEl = { textContent: '', className: '' };
|
||||||
const mockGrid = { innerHTML: '' };
|
const mockGrid = { innerHTML: '' };
|
||||||
|
|||||||
Reference in New Issue
Block a user