waybetter-for-x/apps/desktop/tests/accountSwitcher.test.ts
2026-10-01 06:01:13 +07:00

104 lines
6.3 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
accountAction as accountActionCore, accountStartUrl as accountStartUrlCore, addAccountProfile, focusedAccount, moveFocus, setDefaultAccount, tabsByAccount, type PaneInfo,
} from '../../../waybetter/packages/shell/src/frame/accountModel.ts';
import { isXUrl } from '../src/shell/paneModel.ts';
import { LOGIN_URL, LOGOUT_URL, normalizeProfiles, type ProfileSettings } from '../src/shell/profileModel.ts';
// The framework's switcher rules with X's pages (as src/shell/site.tsx gives them to the shell).
const accountAction = (settings: ProfileSettings, panes: readonly PaneInfo[], active: string | null | undefined, id: string, options: { force?: boolean; homeUrl: string }) =>
accountActionCore(settings, panes, active, id, { ...options, loginUrl: LOGIN_URL, isSiteUrl: isXUrl });
const accountStartUrl = (profile: ProfileSettings['profiles'][number], homeUrl: string) => accountStartUrlCore(profile, { homeUrl, loginUrl: LOGIN_URL });
const HOME = 'https://x.com/home';
const settings: ProfileSettings = normalizeProfiles({
active: 'default',
profiles: [
{ id: 'default', name: 'Main', color: '#1d9bf0', account: { handle: 'CRTkafa', name: 'CRT kafa', signedIn: true } },
{ id: 'pwork1', name: 'Work', color: '#7856ff', account: { handle: 'playfishies', name: 'Fishies', signedIn: true } },
{ id: 'pout01', name: 'Old', color: '#f91880', account: { handle: 'oldone', name: 'Old', signedIn: false } },
{ id: 'pnew01', name: 'New account', color: '#00ba7c' },
],
});
const pane = (id: string, profile: string | undefined, visible: boolean, extra: Partial<PaneInfo> = {}): PaneInfo =>
({ id, kind: 'web', profile, url: 'https://x.com/home', visible, ...extra });
test('an account without a visible pane opens its home feed in a new pane beside', () => {
const panes = [pane('a', 'default', true), pane('b', 'pwork1', false)];
assert.deepEqual(accountAction(settings, panes, 'a', 'pwork1', { homeUrl: HOME }),
{ type: 'open', url: HOME, profile: 'pwork1', where: 'beside' });
});
test('a visible pane of the account is focused instead of opening a duplicate', () => {
const panes = [pane('a', 'default', true), pane('b', 'pwork1', true), pane('c', 'pwork1', false)];
assert.deepEqual(accountAction(settings, panes, 'a', 'pwork1', { homeUrl: HOME }), { type: 'focus', paneId: 'b' });
// Already focused: stays there.
assert.deepEqual(accountAction(settings, panes, 'b', 'pwork1', { homeUrl: HOME }), { type: 'focus', paneId: 'b' });
// An X pane wins over another site of the same account.
const mixed = [pane('g', 'pwork1', true, { url: 'https://github.com/' }), pane('x', 'pwork1', true)];
assert.deepEqual(accountAction(settings, mixed, null, 'pwork1', { homeUrl: HOME }), { type: 'focus', paneId: 'x' });
});
test('a start page or the panel is not the account’s pane; old tabs without a profile are the default one', () => {
const panes = [pane('s', 'pwork1', true, { kind: 'start', url: undefined }), pane('old', undefined, true)];
assert.equal(accountAction(settings, panes, 's', 'pwork1', { homeUrl: HOME }).type, 'open');
assert.deepEqual(accountAction(settings, panes, 's', 'default', { homeUrl: HOME }), { type: 'focus', paneId: 'old' });
});
test('modifier click / "Open in new tab" always opens a tab', () => {
const panes = [pane('a', 'default', true)];
assert.deepEqual(accountAction(settings, panes, 'a', 'default', { homeUrl: HOME, force: true }),
{ type: 'open', url: HOME, profile: 'default', where: 'tab' });
});
test('signed-out and never-signed-in accounts open X’s sign-in', () => {
assert.deepEqual(accountAction(settings, [], null, 'pout01', { homeUrl: HOME }), { type: 'open', url: LOGIN_URL, profile: 'pout01', where: 'beside' });
assert.equal(accountStartUrl(settings.profiles[3]!, HOME), LOGIN_URL);
assert.equal(accountStartUrl(settings.profiles[1]!, 'https://x.com/notifications'), 'https://x.com/notifications');
assert.equal(LOGOUT_URL, 'https://x.com/logout');
});
test('unknown account ids fall back to the default account', () => {
assert.deepEqual(accountAction(settings, [], null, 'pgone', { homeUrl: HOME }), { type: 'open', url: HOME, profile: 'default', where: 'beside' });
});
test('the focused pane decides which account is highlighted', () => {
const panes = [pane('a', 'default', true), pane('b', 'pwork1', true), { id: 'better-twttr', kind: 'panel', visible: true } as PaneInfo];
assert.equal(focusedAccount(settings, panes, 'b').id, 'pwork1');
assert.equal(focusedAccount(settings, panes, 'a').id, 'default');
// No pane or the panel: the default account.
assert.equal(focusedAccount({ ...settings, active: 'pwork1' }, panes, 'better-twttr').id, 'pwork1');
assert.equal(focusedAccount({ ...settings, active: 'pwork1' }, panes, null).id, 'pwork1');
});
test('"Use for new tabs" is the only thing that changes the default; add account keeps it', () => {
assert.equal(setDefaultAccount(settings, 'pwork1').active, 'pwork1');
assert.equal(setDefaultAccount(settings, 'nope'), settings);
assert.equal(setDefaultAccount(settings, 'default'), settings);
const added = addAccountProfile(settings, 'pfresh1');
assert.equal(added.profile, 'pfresh1');
assert.equal(added.settings.active, 'default');
assert.equal(added.settings.profiles.length, settings.profiles.length + 1);
// What profiles_set receives still normalizes (profiles.json compatibility).
assert.deepEqual(normalizeProfiles(added.settings), added.settings);
});
test('tabs are counted per account (web tabs only)', () => {
const panes = [pane('a', 'default', true), pane('b', undefined, false), pane('c', 'pwork1', true), pane('s', 'pwork1', true, { kind: 'start' })];
const byAccount = tabsByAccount(settings, panes);
assert.deepEqual(byAccount.get('default'), ['a', 'b']);
assert.deepEqual(byAccount.get('pwork1'), ['c']);
assert.equal(byAccount.get('pnew01'), undefined);
});
test('menu arrow keys wrap and Home/End jump', () => {
assert.equal(moveFocus(-1, 'ArrowDown', 5), 0);
assert.equal(moveFocus(-1, 'ArrowUp', 5), 4);
assert.equal(moveFocus(4, 'ArrowDown', 5), 0);
assert.equal(moveFocus(0, 'ArrowUp', 5), 4);
assert.equal(moveFocus(2, 'Home', 5), 0);
assert.equal(moveFocus(2, 'End', 5), 4);
assert.equal(moveFocus(2, 'x', 5), 2);
assert.equal(moveFocus(0, 'ArrowDown', 0), -1);
});