mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
chore(repo): remove dead code and useless tests (#3375)
This commit is contained in:
1 parent
7e177a1c90
commit
1cd62eb661
1391 files changed
+783
-120415
No files matched your search
@@ -3,19 +3,7 @@
|
||||
|
||||
import {readFileSync} from 'node:fs';
|
||||
import {resolve} from 'node:path';
|
||||
import {NagbarToneKind} from '@app/features/app/components/layout/NagbarTones';
|
||||
import {WELCOME_ROTATION} from '@app/features/app/components/setup/SetupWizardWelcomeRotation';
|
||||
import {
|
||||
AuthShellHintKind,
|
||||
recordAuthShellHint,
|
||||
resolveAuthShellPlaceholder,
|
||||
} from '@app/features/app/components/skeleton/AuthShellHint';
|
||||
import {SHELL_HINT_NAGBAR_TONE_ORDER, SHELL_HINT_VERSION} from '@app/features/app/components/skeleton/ShellHint';
|
||||
import {
|
||||
LEGACY_SHELL_HINT_NAGBAR_TONE_ORDER,
|
||||
LEGACY_SHELL_HINT_SEED_VERSION,
|
||||
legacyShellHintSeed,
|
||||
} from '@fluxer/desktop_ipc/src/LegacyShellHintSeed';
|
||||
import {SHELL_HINT_VERSION} from '@app/features/app/components/skeleton/ShellHint';
|
||||
import {createElement, type ReactNode} from 'react';
|
||||
import {createRoot} from 'react-dom/client';
|
||||
import {afterEach, expect, test, vi} from 'vitest';
|
||||
@@ -170,203 +158,6 @@ afterEach(async () => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
test('a desktop hint paints the boot shell', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
const shell = runBootScript(desktopDMHint());
|
||||
|
||||
expect(shell).not.toBeNull();
|
||||
expect(shell?.dataset.mobile).toBe('0');
|
||||
expect(shell?.dataset.userArea).toBe('1');
|
||||
expect(shell?.firstElementChild?.className).toBe('fluxer-boot-app');
|
||||
});
|
||||
|
||||
test('the boot shell is parsed in an inert template so the render-blocking expectation outlives it', () => {
|
||||
setViewportWidth(1400);
|
||||
const descriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
|
||||
const rootWrites: Array<string> = [];
|
||||
const innerHTML = vi.spyOn(Element.prototype, 'innerHTML', 'set').mockImplementation(function (
|
||||
this: Element,
|
||||
value: string,
|
||||
) {
|
||||
if (this.id === 'root') {
|
||||
rootWrites.push(value);
|
||||
}
|
||||
descriptor?.set?.call(this, value);
|
||||
});
|
||||
const createElement = vi.spyOn(document, 'createElement');
|
||||
try {
|
||||
const shell = runBootScript(desktopDMHint());
|
||||
|
||||
expect(shell?.querySelector('svg')).not.toBeNull();
|
||||
expect(shell?.parentElement?.id).toBe('root');
|
||||
expect(rootWrites).toEqual([]);
|
||||
expect(createElement.mock.calls.map(([tagName]) => tagName)).toContain('template');
|
||||
} finally {
|
||||
createElement.mockRestore();
|
||||
innerHTML.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
function railGuildSlots(shell: HTMLElement | null): number {
|
||||
return shell?.querySelectorAll('.fluxer-boot-rail-items > .fluxer-boot-slot').length ?? 0;
|
||||
}
|
||||
|
||||
test('a hint written for another account is ignored and the default shell paints instead', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
const shell = runBootScript(desktopDMHint({a: 'https://two.example/api::200', ri: [[0, 0]]}));
|
||||
|
||||
expect(shell?.dataset.hint).toBe('default');
|
||||
expect(railGuildSlots(shell)).toBe(6);
|
||||
});
|
||||
|
||||
test('a signed-in boot without a hint paints the generic friends shell at the DM root', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
const shell = runBootScript(null);
|
||||
|
||||
expect(shell?.dataset.hint).toBe('default');
|
||||
expect(shell?.dataset.userArea).toBe('1');
|
||||
expect(railGuildSlots(shell)).toBe(6);
|
||||
expect(shell?.querySelector('.fluxer-boot-dsb')).not.toBeNull();
|
||||
expect(shell?.querySelector('.fluxer-boot-friends')).not.toBeNull();
|
||||
});
|
||||
|
||||
test('a signed-in boot without a hint paints a guild chat shell with the member list on a channel route', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
const shell = runBootScript(null, '/channels/100/200');
|
||||
|
||||
expect(shell?.dataset.hint).toBe('default');
|
||||
expect(shell?.querySelector('.fluxer-boot-gsb')).not.toBeNull();
|
||||
expect(shell?.querySelector('.fluxer-boot-chat')).not.toBeNull();
|
||||
expect(shell?.querySelector('.fluxer-boot-member-list')).not.toBeNull();
|
||||
expect(shell?.querySelector('.fluxer-boot-composer')).not.toBeNull();
|
||||
});
|
||||
|
||||
test('a signed-in boot without a hint paints the mobile channel list with a bottom nav on a phone', () => {
|
||||
setViewportWidth(390);
|
||||
|
||||
const shell = runBootScript(null, '/channels/@me');
|
||||
|
||||
expect(shell?.dataset.mobile).toBe('1');
|
||||
expect(shell?.dataset.bottomNav).toBe('1');
|
||||
expect(shell?.querySelector('.fluxer-boot-dsb')).not.toBeNull();
|
||||
});
|
||||
|
||||
test('a signed-in boot never paints a shell on a route the app renders without guild chrome', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
expect(runBootScript(null, '/notifications')).toBeNull();
|
||||
expect(runBootScript(null, '/channels/@discover')).toBeNull();
|
||||
});
|
||||
|
||||
test('a days-old hint for the same account and route still paints as remembered', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
const shell = runBootScript(desktopDMHint({t: Date.now() - 3 * 86_400_000}));
|
||||
|
||||
expect(shell?.dataset.hint).toBe('hint');
|
||||
expect(railGuildSlots(shell)).toBe(4);
|
||||
});
|
||||
|
||||
test('a hint for another route keeps its rail and global chrome but resolves the route it lands on', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
const shell = runBootScript(desktopDMHint({nr: [[0, 0, 1]]}), '/channels/100/200');
|
||||
|
||||
expect(shell?.dataset.hint).toBe('derived');
|
||||
expect(railGuildSlots(shell)).toBe(4);
|
||||
expect(shell?.querySelectorAll('.fluxer-boot-nagbar')).toHaveLength(1);
|
||||
expect(shell?.querySelector('.fluxer-boot-gsb')).not.toBeNull();
|
||||
expect(shell?.querySelector('.fluxer-boot-dsb')).toBeNull();
|
||||
});
|
||||
|
||||
test('a hint seeded from the legacy desktop client paints its rail, nagbars and sidebar on the first boot', () => {
|
||||
setViewportWidth(1400);
|
||||
const seed = legacyShellHintSeed(
|
||||
{
|
||||
SkeletonLayoutMemory: JSON.stringify({
|
||||
version: 9,
|
||||
chrome: {
|
||||
dmSidebar: {
|
||||
isMobile: false,
|
||||
friendsVisible: true,
|
||||
personalNotesVisible: true,
|
||||
premiumVisible: false,
|
||||
sectionVisible: true,
|
||||
channelRowCount: 2,
|
||||
channelSubtextFlags: [true, false],
|
||||
},
|
||||
guildRail: {
|
||||
inlineDmRowCount: 0,
|
||||
inlineDmUnreadFlags: [],
|
||||
selectedInlineDmRowIndex: -1,
|
||||
outageVisible: false,
|
||||
fluxerVisible: true,
|
||||
favoritesVisible: true,
|
||||
discoveryVisible: true,
|
||||
addGuildVisible: true,
|
||||
downloadVisible: false,
|
||||
helpVisible: true,
|
||||
selectedItemIndex: -1,
|
||||
organizedItems: [
|
||||
{kind: 'guild', indicator: 'none'},
|
||||
{kind: 'guild', indicator: 'unread'},
|
||||
],
|
||||
scrollTopPx: 0,
|
||||
},
|
||||
},
|
||||
nagbar: {
|
||||
rows: [
|
||||
{tone: NagbarToneKind.ALERT, hasActions: true, dismissible: false},
|
||||
{tone: NagbarToneKind.BRAND, hasActions: true, dismissible: true},
|
||||
],
|
||||
},
|
||||
}),
|
||||
'fluxer:ui:sidebar-width': '306',
|
||||
},
|
||||
ACCOUNT_KEY,
|
||||
Date.now(),
|
||||
);
|
||||
const hint = JSON.parse(seed ?? '');
|
||||
expect(hint.v).toBe(SHELL_HINT_VERSION);
|
||||
expect(LEGACY_SHELL_HINT_SEED_VERSION).toBe(SHELL_HINT_VERSION);
|
||||
|
||||
const shell = runBootScript(hint);
|
||||
|
||||
expect(shell?.dataset.hint).toBe('hint');
|
||||
expect(railGuildSlots(shell)).toBe(2);
|
||||
expect(shell?.querySelectorAll('.fluxer-boot-nagbar')).toHaveLength(2);
|
||||
expect(shell?.querySelector('.fluxer-boot-dsb')).not.toBeNull();
|
||||
expect(shell?.querySelector('.fluxer-boot-friends')).not.toBeNull();
|
||||
expect(shell?.firstElementChild?.getAttribute('style')).toContain('--layout-sidebar-width:19.125rem');
|
||||
|
||||
const guild = runBootScript(hint, '/channels/100/200');
|
||||
|
||||
expect(guild?.dataset.hint).toBe('derived');
|
||||
expect(railGuildSlots(guild)).toBe(2);
|
||||
expect(guild?.querySelectorAll('.fluxer-boot-nagbar')).toHaveLength(2);
|
||||
});
|
||||
|
||||
test('the legacy seed encodes nagbar tones in the order the boot shell decodes them', () => {
|
||||
expect(LEGACY_SHELL_HINT_NAGBAR_TONE_ORDER).toEqual(SHELL_HINT_NAGBAR_TONE_ORDER);
|
||||
});
|
||||
|
||||
test('the DM root paints the remembered route because the app restores it on boot', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
const shell = runBootScript(
|
||||
desktopDMHint({p: '/channels/100/200', sv: 'guild', ck: 'chat', cb: 0, cid: '200', ch: 0}),
|
||||
'/channels/@me',
|
||||
);
|
||||
|
||||
expect(shell?.dataset.hint).toBe('hint');
|
||||
expect(shell?.querySelector('.fluxer-boot-gsb')).not.toBeNull();
|
||||
expect(shell?.querySelector('.fluxer-boot-chat')).not.toBeNull();
|
||||
});
|
||||
|
||||
test('a document script that never loads drops the boot shell because nothing else can mount the app', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
@@ -423,191 +214,3 @@ test('React clearing its own container is what removes the boot shell', async ()
|
||||
|
||||
expect(container.querySelector('#fluxer-boot-shell')).toBeNull();
|
||||
});
|
||||
|
||||
test('the zoom script syncs --custom-zoom with the persisted preboot mirror before paint', () => {
|
||||
const chunk = html.split(/<script[^>]*>/u).find((part) => part.includes('zoom-preboot'));
|
||||
expect(chunk).toBeDefined();
|
||||
const script = (chunk ?? '').split('</script>')[0];
|
||||
expect(script).toContain('zoom-preboot');
|
||||
const run = (mirror: string | null): string => {
|
||||
document.documentElement.style.removeProperty('--custom-zoom');
|
||||
if (mirror === null) {
|
||||
localStorage.removeItem('fluxer:accessibility:zoom-preboot');
|
||||
} else {
|
||||
localStorage.setItem('fluxer:accessibility:zoom-preboot', mirror);
|
||||
}
|
||||
new Function(script)();
|
||||
return document.documentElement.style.getPropertyValue('--custom-zoom');
|
||||
};
|
||||
expect(run('125')).toBe('125');
|
||||
expect(run('75')).toBe('75');
|
||||
expect(run(null)).toBe('');
|
||||
expect(run('9999')).toBe('');
|
||||
expect(run('not-a-number')).toBe('');
|
||||
localStorage.removeItem('fluxer:accessibility:zoom-preboot');
|
||||
});
|
||||
|
||||
function runSignedOutBootScript(pathname: string, storage: Readonly<Record<string, string>> = {}): HTMLElement | null {
|
||||
return runBootScript(null, pathname, {signedIn: false, storage});
|
||||
}
|
||||
|
||||
function setNativePlatform(native: boolean): void {
|
||||
document.documentElement.classList.toggle('platform-native', native);
|
||||
}
|
||||
|
||||
test('a signed-out boot paints the sign-in card at its final size instead of a flat background', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
const shell = runSignedOutBootScript('/login');
|
||||
|
||||
expect(shell?.dataset.auth).toBe('card');
|
||||
expect(shell?.dataset.hint).toBe('default');
|
||||
expect(shell?.dataset.height).toBe('214');
|
||||
expect(shell?.querySelector<HTMLElement>('.fluxer-boot-auth-card')?.style.height).toBe('13.375rem');
|
||||
expect(shell?.querySelectorAll('.fluxer-boot-auth-list > .fluxer-boot-block')).toHaveLength(2);
|
||||
});
|
||||
|
||||
test('a signed-out boot on an app route paints the sign-in card the app redirects to', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
expect(runSignedOutBootScript('/channels/@me')?.dataset.category).toBe('login');
|
||||
expect(runSignedOutBootScript('/channels/100/200')?.dataset.category).toBe('login');
|
||||
});
|
||||
|
||||
test('a signed-out boot sizes the register card and the phone layout from their own defaults', () => {
|
||||
setViewportWidth(1400);
|
||||
expect(runSignedOutBootScript('/register')?.dataset.height).toBe('674');
|
||||
|
||||
setViewportWidth(390);
|
||||
const mobile = runSignedOutBootScript('/register');
|
||||
expect(mobile?.dataset.mobile).toBe('1');
|
||||
expect(mobile?.dataset.height).toBe('592');
|
||||
expect(mobile?.querySelector('.fluxer-boot-auth-mmain')).not.toBeNull();
|
||||
});
|
||||
|
||||
test('a remembered auth card size wins over the default', () => {
|
||||
setViewportWidth(1400);
|
||||
recordAuthShellHint({pathname: '/login', mobile: false, kind: AuthShellHintKind.CARD, heightPx: 388, widthPx: 512});
|
||||
const storage = {'fluxer:ui:auth-shell-hint': localStorage.getItem('fluxer:ui:auth-shell-hint') ?? ''};
|
||||
|
||||
const shell = runSignedOutBootScript('/login', storage);
|
||||
|
||||
expect(shell?.dataset.hint).toBe('hint');
|
||||
expect(shell?.dataset.height).toBe('388');
|
||||
expect(shell?.querySelector<HTMLElement>('.fluxer-boot-auth-card')?.style.maxWidth).toBe('32rem');
|
||||
});
|
||||
|
||||
test('a remembered phone card is not used on a desktop-sized window', () => {
|
||||
setViewportWidth(1400);
|
||||
recordAuthShellHint({pathname: '/login', mobile: true, kind: AuthShellHintKind.CARD, heightPx: 500, widthPx: 342});
|
||||
const storage = {'fluxer:ui:auth-shell-hint': localStorage.getItem('fluxer:ui:auth-shell-hint') ?? ''};
|
||||
|
||||
expect(runSignedOutBootScript('/login', storage)?.dataset.height).toBe('214');
|
||||
});
|
||||
|
||||
test('a fresh desktop install paints the fullscreen welcome skeleton', () => {
|
||||
setViewportWidth(1400);
|
||||
setNativePlatform(true);
|
||||
try {
|
||||
const shell = runSignedOutBootScript('/login');
|
||||
|
||||
expect(shell?.dataset.auth).toBe('full');
|
||||
expect(shell?.querySelector('.fluxer-boot-auth-full')).not.toBeNull();
|
||||
expect(shell?.querySelector('.fluxer-boot-auth-wtext')?.textContent).toBe('Welcome');
|
||||
} finally {
|
||||
setNativePlatform(false);
|
||||
}
|
||||
});
|
||||
|
||||
test('the fullscreen welcome greets in the stored locale before the browser language', () => {
|
||||
setViewportWidth(1400);
|
||||
setNativePlatform(true);
|
||||
try {
|
||||
const shell = runSignedOutBootScript('/login', {locale: 'de'});
|
||||
|
||||
expect(shell?.querySelector('.fluxer-boot-auth-wtext')?.textContent).toBe('Willkommen');
|
||||
} finally {
|
||||
setNativePlatform(false);
|
||||
}
|
||||
});
|
||||
|
||||
test('the boot welcome words match the welcome rotation', () => {
|
||||
const table = /var t=(\{[^}]*\});/u.exec(readBootScript());
|
||||
expect(table).not.toBeNull();
|
||||
const words = new Function(`return ${table?.[1] ?? '{}'}`)() as Record<string, string>;
|
||||
|
||||
expect(words).toEqual(Object.fromEntries(WELCOME_ROTATION.map((entry) => [entry.code, entry.text])));
|
||||
});
|
||||
|
||||
test('a shell that stamps a stored session paints the app shell even before the preboot mirror exists', () => {
|
||||
setViewportWidth(1400);
|
||||
document.documentElement.setAttribute('data-boot-session', '1');
|
||||
try {
|
||||
const shell = runSignedOutBootScript('/channels/@me');
|
||||
|
||||
expect(shell?.dataset.hint).toBe('default');
|
||||
expect(shell?.dataset.auth).toBeUndefined();
|
||||
} finally {
|
||||
document.documentElement.removeAttribute('data-boot-session');
|
||||
}
|
||||
});
|
||||
|
||||
test('a session an older client stored paints the app shell before the preboot mirror exists', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
const shell = runSignedOutBootScript('/channels/200/300', {token: 'legacy-token', userId: '100'});
|
||||
|
||||
expect(shell?.dataset.hint).toBe('default');
|
||||
expect(shell?.dataset.auth).toBeUndefined();
|
||||
});
|
||||
|
||||
test('a half or emptied older session still paints the sign-in card', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
expect(runSignedOutBootScript('/channels/@me', {token: 'legacy-token'})?.dataset.auth).toBe('card');
|
||||
expect(runSignedOutBootScript('/channels/@me', {token: 'null', userId: '100'})?.dataset.auth).toBe('card');
|
||||
expect(
|
||||
runSignedOutBootScript('/channels/@me', {
|
||||
token: 'legacy-token',
|
||||
userId: '100',
|
||||
'fluxer:gateway:preboot:session': '0',
|
||||
})?.dataset.auth,
|
||||
).toBe('card');
|
||||
});
|
||||
|
||||
test('a signed-out boot leaves routes without an auth card alone', () => {
|
||||
setViewportWidth(1400);
|
||||
|
||||
expect(runSignedOutBootScript('/oauth2/authorize')).toBeNull();
|
||||
});
|
||||
|
||||
test.each([
|
||||
{pathname: '/login', width: 1400, native: false},
|
||||
{pathname: '/login', width: 390, native: false},
|
||||
{pathname: '/login', width: 1400, native: true},
|
||||
{pathname: '/register', width: 1400, native: false},
|
||||
{pathname: '/register', width: 390, native: false},
|
||||
{pathname: '/forgot', width: 1400, native: false},
|
||||
{pathname: '/invite/abc', width: 390, native: false},
|
||||
])(
|
||||
'the inline auth skeleton picks what the app placeholder picks for $pathname at $width px',
|
||||
({pathname, width, native}) => {
|
||||
setViewportWidth(width);
|
||||
setNativePlatform(native);
|
||||
try {
|
||||
const shell = runSignedOutBootScript(pathname);
|
||||
const placeholder = resolveAuthShellPlaceholder(pathname, {
|
||||
mobile: width < 640,
|
||||
native,
|
||||
passkeyLikely: false,
|
||||
});
|
||||
|
||||
expect(shell?.dataset.category).toBe(placeholder?.category);
|
||||
expect(shell?.dataset.auth).toBe(placeholder?.kind);
|
||||
expect(shell?.dataset.hint).toBe(placeholder?.source);
|
||||
expect(Number(shell?.dataset.height)).toBe(placeholder?.heightPx);
|
||||
} finally {
|
||||
setNativePlatform(false);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -1,152 +0,0 @@
|
||||
// @vitest-environment happy-dom
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {readFileSync} from 'node:fs';
|
||||
import {resolve} from 'node:path';
|
||||
import {FriendsSkeleton} from '@app/features/app/components/skeleton/FriendsSkeleton';
|
||||
import {SHELL_HINT_VERSION} from '@app/features/app/components/skeleton/ShellHint';
|
||||
import {
|
||||
type RememberedSkeletonActiveNowCard,
|
||||
type RememberedSkeletonFriendsLayout,
|
||||
SKELETON_DEFAULT_FRIENDS_LAYOUT,
|
||||
} from '@app/features/app/components/skeleton/SkeletonLayoutMemory';
|
||||
import {act, createElement, type ReactNode} from 'react';
|
||||
import {createRoot} from 'react-dom/client';
|
||||
import {afterEach, expect, test, vi} from 'vitest';
|
||||
|
||||
vi.mock('@lingui/core/macro', () => {
|
||||
const descriptor = (value: unknown): unknown => (typeof value === 'string' ? {message: value} : value);
|
||||
return {msg: descriptor, t: descriptor, plural: () => '', select: () => '', selectOrdinal: () => ''};
|
||||
});
|
||||
vi.mock('@lingui/react/macro', () => ({
|
||||
Trans: ({children}: {children?: ReactNode}) => children ?? null,
|
||||
useLingui: () => ({i18n: {_: (descriptor: {message?: string}) => descriptor.message ?? ''}}),
|
||||
}));
|
||||
|
||||
const memory = vi.hoisted(() => ({friends: null as RememberedSkeletonFriendsLayout | null}));
|
||||
|
||||
vi.mock('@app/features/app/components/skeleton/SkeletonLayoutMemory', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@app/features/app/components/skeleton/SkeletonLayoutMemory')>();
|
||||
return {...actual, getRememberedSkeletonFriendsLayout: () => memory.friends};
|
||||
});
|
||||
|
||||
const ACCOUNT_KEY = 'https://one.example/api::100';
|
||||
const html = readFileSync(resolve(process.cwd(), 'index.html'), 'utf8');
|
||||
|
||||
function readBootScript(): string {
|
||||
const body = html.slice(html.indexOf('<div id="root"></div>'));
|
||||
return /<script[^>]*>([\s\S]*?)<\/script>/u.exec(body)?.[1] ?? '';
|
||||
}
|
||||
|
||||
function friendsHint(extra: Record<string, unknown>): Record<string, unknown> {
|
||||
return {
|
||||
v: SHELL_HINT_VERSION,
|
||||
t: Date.now(),
|
||||
p: '/channels/@me',
|
||||
a: ACCOUNT_KEY,
|
||||
mo: 0,
|
||||
ua: 0,
|
||||
sv: 'dm',
|
||||
ck: 'other',
|
||||
cb: 1,
|
||||
...extra,
|
||||
};
|
||||
}
|
||||
|
||||
function bootSidebar(hint: Record<string, unknown> | null): Element | null {
|
||||
document.body.innerHTML = '<div id="root"></div>';
|
||||
window.history.pushState({}, '', '/channels/@me');
|
||||
localStorage.clear();
|
||||
localStorage.setItem('fluxer:gateway:preboot:session', '1');
|
||||
localStorage.setItem('fluxer:auth:active-account-key', ACCOUNT_KEY);
|
||||
if (hint != null) {
|
||||
localStorage.setItem('fluxer:ui:shell-hint', JSON.stringify(hint));
|
||||
}
|
||||
new Function(readBootScript())();
|
||||
const shell = document.querySelector('#fluxer-boot-shell');
|
||||
expect(shell?.querySelector('.fluxer-boot-friends')).not.toBeNull();
|
||||
return shell?.querySelector('.fluxer-boot-fr-side') ?? null;
|
||||
}
|
||||
|
||||
async function reactSidebar(friends: RememberedSkeletonFriendsLayout | null): Promise<Element | null> {
|
||||
memory.friends = friends;
|
||||
const container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
const root = createRoot(container);
|
||||
await act(async () => root.render(createElement(FriendsSkeleton)));
|
||||
const sidebar = container.querySelector('flx-app-friends-skeleton-sidebar');
|
||||
const copy = sidebar?.cloneNode(true) as Element | undefined;
|
||||
await act(async () => root.unmount());
|
||||
return copy ?? null;
|
||||
}
|
||||
|
||||
function bootGeometry(sidebar: Element | null): Array<string> {
|
||||
return Array.from(sidebar?.querySelectorAll('.fluxer-boot-block') ?? []).map((block) => {
|
||||
const style = block.getAttribute('style') ?? '';
|
||||
const width = /width:([^;]+);/.exec(style)?.[1];
|
||||
const height = /height:([^;]+);/.exec(style)?.[1];
|
||||
return `${width}x${height}`;
|
||||
});
|
||||
}
|
||||
|
||||
function reactGeometry(sidebar: Element | null): Array<string> {
|
||||
return Array.from(sidebar?.querySelectorAll('flx-skeleton-line, flx-skeleton-block') ?? []).map((block) => {
|
||||
const style = (block as HTMLElement).style;
|
||||
return `${style.getPropertyValue('--skeleton-width')}x${style.getPropertyValue('--skeleton-height')}`;
|
||||
});
|
||||
}
|
||||
|
||||
function layoutWith(activeNowVisible: boolean, cards: ReadonlyArray<RememberedSkeletonActiveNowCard>) {
|
||||
return {...SKELETON_DEFAULT_FRIENDS_LAYOUT, activeNowVisible, activeNowCards: cards};
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
memory.friends = null;
|
||||
localStorage.clear();
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
test('with nobody active the boot shell paints the same empty state React paints', async () => {
|
||||
const boot = bootSidebar(friendsHint({fa: 1, fn: []}));
|
||||
const react = await reactSidebar(layoutWith(true, []));
|
||||
|
||||
expect(boot?.querySelector('.fluxer-boot-fr-empty')).not.toBeNull();
|
||||
expect(boot?.querySelector('.fluxer-boot-fr-card')).toBeNull();
|
||||
expect(bootGeometry(boot)).toEqual(reactGeometry(react));
|
||||
});
|
||||
|
||||
test('remembered cards paint with the same count and geometry as the React skeleton', async () => {
|
||||
const cards = [
|
||||
{participantCount: 0, streaming: false},
|
||||
{participantCount: 3, streaming: true},
|
||||
{participantCount: 7, streaming: false},
|
||||
];
|
||||
const boot = bootSidebar(
|
||||
friendsHint({
|
||||
fa: 1,
|
||||
fn: [
|
||||
[0, 0],
|
||||
[3, 1],
|
||||
[7, 0],
|
||||
],
|
||||
}),
|
||||
);
|
||||
const react = await reactSidebar(layoutWith(true, cards));
|
||||
|
||||
expect(boot?.querySelectorAll('.fluxer-boot-fr-card')).toHaveLength(3);
|
||||
expect(bootGeometry(boot)).toEqual(reactGeometry(react));
|
||||
});
|
||||
|
||||
test('a hidden active now column paints no sidebar in either skeleton', async () => {
|
||||
expect(bootSidebar(friendsHint({fa: 0, fn: []}))).toBeNull();
|
||||
expect(await reactSidebar(layoutWith(false, []))).toBeNull();
|
||||
});
|
||||
|
||||
test('without any remembered layout neither skeleton invents activity cards', async () => {
|
||||
const boot = bootSidebar(null);
|
||||
const react = await reactSidebar(null);
|
||||
|
||||
expect(boot?.querySelector('.fluxer-boot-fr-card')).toBeNull();
|
||||
expect(react?.querySelector('flx-app-friends-skeleton-active-card')).toBeNull();
|
||||
expect(bootGeometry(boot)).toEqual(reactGeometry(react));
|
||||
});
|
||||
@@ -79,7 +79,6 @@ export const Routes = {
|
||||
isDMRoute: (pathname: string) => pathname.startsWith('/channels/@me'),
|
||||
isFavoritesRoute: (pathname: string) => pathname.startsWith('/channels/@favorites'),
|
||||
isDiscoverRoute: (pathname: string) => pathname.startsWith('/channels/@discover'),
|
||||
isPlutoniumRoute: (pathname: string) => pathname === '/channels/@premium',
|
||||
isChannelRoute: (pathname: string) => pathname.startsWith('/channels/') && !pathname.startsWith('/channels/@premium'),
|
||||
isGuildChannelRoute: (pathname: string) =>
|
||||
pathname.startsWith('/channels/') &&
|
||||
|
||||
Reference in new issue
Block a user