223 lines
6.6 KiB
JavaScript
223 lines
6.6 KiB
JavaScript
'use strict';
|
|
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
const {
|
|
SAVED_TAB_SESSION_COLLAPSED_KEY,
|
|
SAVED_TAB_SESSION_ORDER_KEY,
|
|
applySavedTabSessionOrder,
|
|
detachSavedSessionTabToNewSession,
|
|
buildSavedSessionTabToken,
|
|
buildSavedTabSessionOrder,
|
|
buildSavedTabSessionOrderWithInsertedSession,
|
|
moveSavedSessionTabsByTokens,
|
|
normalizeSavedTabSessionCollapsedState,
|
|
normalizeSavedTabSessionOrder,
|
|
parseSavedSessionTabToken,
|
|
reorderSavedSessionTabsByTokens,
|
|
} = require('./session-manager.js');
|
|
|
|
test('session manager exposes the saved session order storage key', () => {
|
|
assert.equal(SAVED_TAB_SESSION_ORDER_KEY, 'savedTabSessionOrder');
|
|
});
|
|
|
|
test('session manager exposes the saved session collapsed storage key', () => {
|
|
assert.equal(SAVED_TAB_SESSION_COLLAPSED_KEY, 'savedTabSessionCollapsedState');
|
|
});
|
|
|
|
test('normalizeSavedTabSessionOrder keeps unique non-empty ids in order', () => {
|
|
assert.deepEqual(
|
|
normalizeSavedTabSessionOrder(['session-a', '', null, 'session-b', 'session-a']),
|
|
['session-a', 'session-b']
|
|
);
|
|
});
|
|
|
|
test('normalizeSavedTabSessionCollapsedState keeps only explicit true flags for known sessions', () => {
|
|
assert.deepEqual(
|
|
normalizeSavedTabSessionCollapsedState(
|
|
{
|
|
'session-a': true,
|
|
'session-b': false,
|
|
'': true,
|
|
'session-c': 'yes',
|
|
},
|
|
[
|
|
{ id: 'session-a' },
|
|
{ id: 'session-b' },
|
|
]
|
|
),
|
|
{ 'session-a': true }
|
|
);
|
|
});
|
|
|
|
test('applySavedTabSessionOrder sorts sessions by persisted ids and appends new ones', () => {
|
|
const ordered = applySavedTabSessionOrder(
|
|
[
|
|
{ id: 'session-c', name: 'C' },
|
|
{ id: 'session-a', name: 'A' },
|
|
{ id: 'session-b', name: 'B' },
|
|
],
|
|
['session-b', 'session-a']
|
|
);
|
|
|
|
assert.deepEqual(
|
|
ordered.map(session => session.id),
|
|
['session-b', 'session-a', 'session-c']
|
|
);
|
|
});
|
|
|
|
test('buildSavedTabSessionOrder reflects the current ordered session ids', () => {
|
|
assert.deepEqual(
|
|
buildSavedTabSessionOrder([
|
|
{ id: 'session-b' },
|
|
{ id: 'session-a' },
|
|
{ id: 'session-b' },
|
|
]),
|
|
['session-b', 'session-a']
|
|
);
|
|
});
|
|
|
|
test('saved session tab tokens round-trip session id and index', () => {
|
|
const token = buildSavedSessionTabToken('session-a', 2);
|
|
assert.equal(token, 'session-a::2');
|
|
assert.deepEqual(parseSavedSessionTabToken(token), { sessionId: 'session-a', tabIndex: 2 });
|
|
});
|
|
|
|
test('reorderSavedSessionTabsByTokens reorders tabs within one session', () => {
|
|
const reordered = reorderSavedSessionTabsByTokens(
|
|
{
|
|
id: 'session-a',
|
|
tabs: [{ title: 'A' }, { title: 'B' }, { title: 'C' }],
|
|
},
|
|
['session-a::2', 'session-a::0', 'session-a::1']
|
|
);
|
|
|
|
assert.deepEqual(reordered.map(tab => tab.title), ['C', 'A', 'B']);
|
|
});
|
|
|
|
test('moveSavedSessionTabsByTokens preserves target tabs when moving across sessions', () => {
|
|
const moved = moveSavedSessionTabsByTokens({
|
|
sourceSession: {
|
|
id: 'session-a',
|
|
tabs: [{ title: 'A' }, { title: 'A2' }],
|
|
},
|
|
targetSession: {
|
|
id: 'session-b',
|
|
tabs: [{ title: 'B' }],
|
|
},
|
|
sourceOrderTokens: ['session-a::1'],
|
|
targetOrderTokens: ['session-a::0', 'session-b::0'],
|
|
draggedToken: 'session-a::0',
|
|
});
|
|
|
|
assert.deepEqual(moved.sourceTabs.map(tab => tab.title), ['A2']);
|
|
assert.deepEqual(moved.targetTabs.map(tab => tab.title), ['A', 'B']);
|
|
});
|
|
|
|
test('buildSavedTabSessionOrderWithInsertedSession inserts new sessions at the top, bottom, or before a gap target', () => {
|
|
const sessions = [
|
|
{ id: 'session-a', name: 'A' },
|
|
{ id: 'session-b', name: 'B' },
|
|
{ id: 'session-c', name: 'C' },
|
|
];
|
|
|
|
assert.deepEqual(
|
|
buildSavedTabSessionOrderWithInsertedSession(sessions, 'session-new', {
|
|
placement: 'before',
|
|
}),
|
|
['session-new', 'session-a', 'session-b', 'session-c']
|
|
);
|
|
|
|
assert.deepEqual(
|
|
buildSavedTabSessionOrderWithInsertedSession(sessions, 'session-new', {
|
|
placement: 'after',
|
|
}),
|
|
['session-a', 'session-b', 'session-c', 'session-new']
|
|
);
|
|
|
|
assert.deepEqual(
|
|
buildSavedTabSessionOrderWithInsertedSession(sessions, 'session-new', {
|
|
placement: 'before',
|
|
insertBeforeSessionId: 'session-c',
|
|
}),
|
|
['session-a', 'session-b', 'session-new', 'session-c']
|
|
);
|
|
});
|
|
|
|
test('detachSavedSessionTabToNewSession inserts a new middle session and rebuilds the source tabs/groups', () => {
|
|
const result = detachSavedSessionTabToNewSession({
|
|
sessions: [
|
|
{
|
|
id: 'session-a',
|
|
name: 'Morning',
|
|
savedAt: '2026-05-22T08:00:00.000Z',
|
|
source: 'manual',
|
|
tabs: [
|
|
{ url: 'https://a.test', title: 'A', groupKey: 'group-a', groupLabel: 'Group A' },
|
|
{ url: 'https://b.test', title: 'B', groupKey: 'group-b', groupLabel: 'Group B' },
|
|
],
|
|
groups: [
|
|
{ key: 'group-a', label: 'Group A', manualGroupId: '', tabUrls: ['https://a.test'] },
|
|
{ key: 'group-b', label: 'Group B', manualGroupId: '', tabUrls: ['https://b.test'] },
|
|
],
|
|
},
|
|
{
|
|
id: 'session-c',
|
|
name: 'Later',
|
|
savedAt: '2026-05-22T08:10:00.000Z',
|
|
source: 'manual',
|
|
tabs: [{ url: 'https://c.test', title: 'C' }],
|
|
groups: [],
|
|
},
|
|
],
|
|
draggedToken: 'session-a::1',
|
|
placement: 'before',
|
|
insertBeforeSessionId: 'session-c',
|
|
now: '2026-05-22T09:30:00.000Z',
|
|
});
|
|
|
|
assert.deepEqual(result.orderIds, [
|
|
'session-a',
|
|
result.createdSession.id,
|
|
'session-c',
|
|
]);
|
|
assert.deepEqual(result.sessions[0].tabs.map(tab => tab.url), ['https://a.test']);
|
|
assert.deepEqual(result.sessions[0].groups.map(group => group.key), ['group-a']);
|
|
assert.equal(result.createdSession.name, 'B');
|
|
assert.deepEqual(result.createdSession.tabs.map(tab => tab.url), ['https://b.test']);
|
|
});
|
|
|
|
test('detachSavedSessionTabToNewSession deletes the source session when its last tab is moved out', () => {
|
|
const result = detachSavedSessionTabToNewSession({
|
|
sessions: [
|
|
{
|
|
id: 'session-a',
|
|
name: 'Solo',
|
|
savedAt: '2026-05-22T08:00:00.000Z',
|
|
source: 'manual',
|
|
tabs: [{ url: 'https://solo.test', title: 'Solo' }],
|
|
groups: [],
|
|
},
|
|
{
|
|
id: 'session-b',
|
|
name: 'Next',
|
|
savedAt: '2026-05-22T08:10:00.000Z',
|
|
source: 'manual',
|
|
tabs: [{ url: 'https://next.test', title: 'Next' }],
|
|
groups: [],
|
|
},
|
|
],
|
|
draggedToken: 'session-a::0',
|
|
placement: 'before',
|
|
insertBeforeSessionId: 'session-b',
|
|
now: '2026-05-22T09:30:00.000Z',
|
|
});
|
|
|
|
assert.equal(result.sourceSessionRemoved, true);
|
|
assert.deepEqual(
|
|
result.sessions.map(session => session.id),
|
|
[result.createdSession.id, 'session-b']
|
|
);
|
|
});
|