mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
test: expand markdown and post menu coverage
Adds focused regression coverage for quote previews, markdown link rendering, embed toggles, and desktop/mobile post-menu actions. It also fixes the undefined feed-state crash in use-state-string.ts and removes unnecessary runtime imports with import type.
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
import * as React from 'react';
|
||||
import { createElement } from 'react';
|
||||
import { createRoot, type Root } from 'react-dom/client';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import useStateString, { useFeedStateString } from '../use-state-string';
|
||||
|
||||
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
||||
const act = (React as { act?: (cb: () => void | Promise<void>) => void | Promise<void> }).act as (cb: () => void | Promise<void>) => void | Promise<void>;
|
||||
|
||||
const testState = vi.hoisted(() => ({
|
||||
clientsStates: {} as Record<string, string[]>,
|
||||
subplebbit: undefined as
|
||||
| {
|
||||
publishingState?: string;
|
||||
state?: string;
|
||||
updatingState?: string;
|
||||
}
|
||||
| undefined,
|
||||
subplebbitsStates: {} as Record<string, { clientUrls: string[]; subplebbitAddresses: string[] }>,
|
||||
}));
|
||||
|
||||
vi.mock('@bitsocialhq/bitsocial-react-hooks', () => ({
|
||||
useClientsStates: () => ({
|
||||
states: testState.clientsStates,
|
||||
}),
|
||||
useSubplebbit: () => testState.subplebbit,
|
||||
useSubplebbitsStates: () => ({
|
||||
states: testState.subplebbitsStates,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('lodash/debounce', () => ({
|
||||
default: <T extends (...args: any[]) => unknown>(fn: T) => {
|
||||
const wrapped = ((...args: Parameters<T>) => fn(...args)) as T & { cancel: () => void };
|
||||
wrapped.cancel = () => undefined;
|
||||
return wrapped;
|
||||
},
|
||||
}));
|
||||
|
||||
let container: HTMLDivElement;
|
||||
let root: Root;
|
||||
let latestValue: string | undefined;
|
||||
|
||||
const StateStringHarness = ({
|
||||
value,
|
||||
}: {
|
||||
value: {
|
||||
publishingState?: string;
|
||||
state?: string;
|
||||
updatingState?: string;
|
||||
};
|
||||
}) => {
|
||||
latestValue = useStateString(value);
|
||||
return null;
|
||||
};
|
||||
|
||||
const FeedStateStringHarness = ({ addresses }: { addresses?: string[] }) => {
|
||||
latestValue = useFeedStateString(addresses);
|
||||
return null;
|
||||
};
|
||||
|
||||
describe('use-state-string', () => {
|
||||
beforeEach(() => {
|
||||
latestValue = undefined;
|
||||
testState.clientsStates = {};
|
||||
testState.subplebbit = undefined;
|
||||
testState.subplebbitsStates = {};
|
||||
container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
root = createRoot(container);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
act(() => root.unmount());
|
||||
container.remove();
|
||||
});
|
||||
|
||||
it('formats client state strings with normalized hostnames', () => {
|
||||
testState.clientsStates = {
|
||||
'fetching-ipns': ['https://rpc.example.com/path', 'https://ipfs.io/api'],
|
||||
'resolving-address': ['https://ens.example.com'],
|
||||
};
|
||||
|
||||
act(() => {
|
||||
root.render(createElement(StateStringHarness, { value: { state: 'updating' } }));
|
||||
});
|
||||
|
||||
expect(latestValue).toBe('Fetching IPNS from rpc.example.com, ipfs.io, resolving address from ens.example.com');
|
||||
});
|
||||
|
||||
it('falls back to publishing and updating states when no client states are available', () => {
|
||||
act(() => {
|
||||
root.render(createElement(StateStringHarness, { value: { publishingState: 'fetching-ipfs', state: 'publishing' } }));
|
||||
});
|
||||
expect(latestValue).toBe('Downloading thread');
|
||||
|
||||
act(() => {
|
||||
root.render(createElement(StateStringHarness, { value: { state: 'updating', updatingState: 'fetching-ipns' } }));
|
||||
});
|
||||
expect(latestValue).toBe('Downloading board');
|
||||
});
|
||||
|
||||
it('sanitizes single-board feed state strings to board wording', () => {
|
||||
testState.subplebbit = {
|
||||
state: 'updating',
|
||||
updatingState: 'fetching-ipfs',
|
||||
};
|
||||
|
||||
act(() => {
|
||||
root.render(createElement(FeedStateStringHarness, { addresses: ['music-posting.eth'] }));
|
||||
});
|
||||
|
||||
expect(latestValue).toBe('Downloading board');
|
||||
});
|
||||
|
||||
it('aggregates multi-board feed states across address resolution, threads, and pages', () => {
|
||||
testState.subplebbitsStates = {
|
||||
'fetching-ipfs': {
|
||||
clientUrls: ['https://ipfs.io'],
|
||||
subplebbitAddresses: ['music-posting.eth'],
|
||||
},
|
||||
'fetching-ipns': {
|
||||
clientUrls: ['https://gateway.example.com'],
|
||||
subplebbitAddresses: ['music-posting.eth', 'tech-posting.eth'],
|
||||
},
|
||||
'page-1': {
|
||||
clientUrls: ['https://gateway.example.com', 'https://ipfs.io'],
|
||||
subplebbitAddresses: ['music-posting.eth'],
|
||||
},
|
||||
'resolving-address': {
|
||||
clientUrls: ['https://ens.example.com'],
|
||||
subplebbitAddresses: ['music-posting.eth', 'tech-posting.eth'],
|
||||
},
|
||||
};
|
||||
|
||||
act(() => {
|
||||
root.render(createElement(FeedStateStringHarness, { addresses: ['music-posting.eth', 'tech-posting.eth'] }));
|
||||
});
|
||||
|
||||
expect(latestValue).toBe('Resolving 2 addresses from ens.example.com, downloading 2 boards, 1 threads, 1 page from gateway.example.com, ipfs.io');
|
||||
});
|
||||
});
|
||||
@@ -68,7 +68,7 @@ const useStateString = (commentOrSubplebbit: CommentOrSubplebbit): string | unde
|
||||
if (commentOrSubplebbit?.publishingState && commentOrSubplebbit?.publishingState !== 'stopped' && commentOrSubplebbit?.publishingState !== 'succeeded') {
|
||||
stateString = commentOrSubplebbit.publishingState;
|
||||
} else if (commentOrSubplebbit?.updatingState !== 'stopped' && commentOrSubplebbit?.updatingState !== 'succeeded') {
|
||||
stateString = commentOrSubplebbit.updatingState;
|
||||
stateString = commentOrSubplebbit?.updatingState;
|
||||
}
|
||||
if (stateString) {
|
||||
stateString = stateString
|
||||
|
||||
Reference in New Issue
Block a user