mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
test: expand honest whole-repo coverage
Adds broad coverage across stores, hooks, and runtime utilities while switching `vitest.config.ts` to an explicit whole-repo include list. This turns the coverage report into a real repo-wide baseline instead of an imported-file subset.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
const testState = vi.hoisted(() => {
|
||||
const i18next = {
|
||||
init: vi.fn(),
|
||||
use: vi.fn(),
|
||||
};
|
||||
i18next.use.mockImplementation(() => i18next);
|
||||
|
||||
return {
|
||||
backendPlugin: { name: 'backend-plugin' },
|
||||
detectorPlugin: { name: 'detector-plugin' },
|
||||
i18next,
|
||||
reactPlugin: { name: 'react-plugin' },
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('i18next', () => ({
|
||||
default: testState.i18next,
|
||||
}));
|
||||
|
||||
vi.mock('i18next-http-backend', () => ({
|
||||
default: testState.backendPlugin,
|
||||
}));
|
||||
|
||||
vi.mock('i18next-browser-languagedetector', () => ({
|
||||
default: testState.detectorPlugin,
|
||||
}));
|
||||
|
||||
vi.mock('react-i18next', () => ({
|
||||
initReactI18next: testState.reactPlugin,
|
||||
}));
|
||||
|
||||
describe('init-translations', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
testState.i18next.use.mockClear();
|
||||
testState.i18next.init.mockClear();
|
||||
testState.i18next.use.mockImplementation(() => testState.i18next);
|
||||
});
|
||||
|
||||
it('initializes i18next with the backend, detector, react plugin, and supported languages', async () => {
|
||||
await import('../init-translations');
|
||||
|
||||
expect(testState.i18next.use).toHaveBeenNthCalledWith(1, testState.backendPlugin);
|
||||
expect(testState.i18next.use).toHaveBeenNthCalledWith(2, testState.detectorPlugin);
|
||||
expect(testState.i18next.use).toHaveBeenNthCalledWith(3, testState.reactPlugin);
|
||||
expect(testState.i18next.init).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
fallbackLng: 'en',
|
||||
ns: ['default'],
|
||||
defaultNS: 'default',
|
||||
backend: { loadPath: './translations/{{lng}}/{{ns}}.json' },
|
||||
}),
|
||||
);
|
||||
expect(testState.i18next.init.mock.calls[0]?.[0]?.supportedLngs).toContain('en');
|
||||
expect(testState.i18next.init.mock.calls[0]?.[0]?.supportedLngs).toContain('ja');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
describe('snow', () => {
|
||||
beforeEach(() => {
|
||||
document.head.innerHTML = '';
|
||||
document.body.innerHTML = '';
|
||||
vi.restoreAllMocks();
|
||||
vi.useRealTimers();
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
it('creates and removes a deterministic snow field', async () => {
|
||||
const mathRandomSpy = vi.spyOn(Math, 'random').mockReturnValue(0.5);
|
||||
const { initSnow, removeSnow } = await import('../snow');
|
||||
|
||||
initSnow({ flakeCount: 3 });
|
||||
|
||||
const snowfield = document.getElementById('js-snowfield');
|
||||
expect(snowfield).toBeTruthy();
|
||||
expect(snowfield?.children).toHaveLength(2);
|
||||
expect(document.head.querySelector('style')?.textContent).toContain('fall-1');
|
||||
|
||||
removeSnow();
|
||||
expect(document.getElementById('js-snowfield')).toBeNull();
|
||||
|
||||
mathRandomSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('prefers the special theme store and otherwise falls back to christmas dates', async () => {
|
||||
const useSpecialThemeStore = (await import('../../stores/use-special-theme-store')).default;
|
||||
const { shouldShowSnow } = await import('../snow');
|
||||
|
||||
useSpecialThemeStore.setState({ isEnabled: true });
|
||||
expect(shouldShowSnow()).toBe(true);
|
||||
|
||||
useSpecialThemeStore.setState({ isEnabled: false });
|
||||
expect(shouldShowSnow()).toBe(false);
|
||||
|
||||
useSpecialThemeStore.setState({ isEnabled: null });
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date('2024-12-24T00:00:00Z'));
|
||||
expect(shouldShowSnow()).toBe(true);
|
||||
|
||||
vi.setSystemTime(new Date('2024-07-04T00:00:00Z'));
|
||||
expect(shouldShowSnow()).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
describe('update-favicon', () => {
|
||||
beforeEach(() => {
|
||||
document.head.innerHTML = '';
|
||||
document.body.innerHTML = '';
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
it('creates a favicon link and replaces it only when the target icon changes', async () => {
|
||||
const { updateFavicon } = await import('../update-favicon');
|
||||
|
||||
updateFavicon(false);
|
||||
expect(document.querySelectorAll('link[rel="icon"]')).toHaveLength(1);
|
||||
expect(document.querySelector('link[rel="icon"]')?.getAttribute('href')).toBe('/favicon.ico');
|
||||
|
||||
updateFavicon(false);
|
||||
expect(document.querySelectorAll('link[rel="icon"]')).toHaveLength(1);
|
||||
|
||||
updateFavicon(true);
|
||||
expect(document.querySelectorAll('link[rel="icon"]')).toHaveLength(1);
|
||||
expect(document.querySelector('link[rel="icon"]')?.getAttribute('href')).toBe('/favicon2.ico');
|
||||
});
|
||||
|
||||
it('marks only non-special, non-routing aggregate sfw boards as sfw', async () => {
|
||||
const { isSfwBoard } = await import('../update-favicon');
|
||||
|
||||
expect(
|
||||
isSfwBoard({
|
||||
pathname: '/',
|
||||
isSpecialTheme: false,
|
||||
isInAllView: false,
|
||||
isInSubscriptionsView: false,
|
||||
isInModView: false,
|
||||
subplebbitAddress: 'music.eth',
|
||||
directories: [{ address: 'music.eth', nsfw: false }],
|
||||
}),
|
||||
).toBe(false);
|
||||
|
||||
expect(
|
||||
isSfwBoard({
|
||||
pathname: '/music.eth',
|
||||
isSpecialTheme: false,
|
||||
isInAllView: false,
|
||||
isInSubscriptionsView: false,
|
||||
isInModView: false,
|
||||
subplebbitAddress: 'music.eth',
|
||||
directories: [
|
||||
{ address: 'music.eth', nsfw: false },
|
||||
{ address: 'flash.eth', nsfw: true },
|
||||
],
|
||||
}),
|
||||
).toBe(true);
|
||||
|
||||
expect(
|
||||
isSfwBoard({
|
||||
pathname: '/flash.eth',
|
||||
isSpecialTheme: false,
|
||||
isInAllView: false,
|
||||
isInSubscriptionsView: false,
|
||||
isInModView: false,
|
||||
subplebbitAddress: 'flash.eth',
|
||||
directories: [{ address: 'flash.eth', nsfw: true }],
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user