mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(pubsub): repair browser pure p2p publishing
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
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';
|
||||
|
||||
(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(() => ({
|
||||
account: undefined as Record<string, any> | undefined,
|
||||
accounts: [] as Record<string, any>[] | undefined,
|
||||
createAccountMock: vi.fn().mockResolvedValue(undefined),
|
||||
setAccountMock: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
vi.mock('@bitsocial/bitsocial-react-hooks', () => ({
|
||||
createAccount: () => testState.createAccountMock(),
|
||||
setAccount: (account: unknown) => testState.setAccountMock(account),
|
||||
useAccount: () => testState.account,
|
||||
useAccounts: () => ({ accounts: testState.accounts }),
|
||||
}));
|
||||
|
||||
let container: HTMLDivElement;
|
||||
const originalLocation = window.location;
|
||||
let reloadMock: ReturnType<typeof vi.fn>;
|
||||
let root: Root;
|
||||
|
||||
const loadHook = async () => (await import('../use-browser-pure-p2p-account-upgrade')).useBrowserPureP2PAccountUpgrade;
|
||||
|
||||
const TestComponent = ({ useUpgrade }: { useUpgrade: () => void }) => {
|
||||
useUpgrade();
|
||||
return null;
|
||||
};
|
||||
|
||||
const renderHook = async () => {
|
||||
const useUpgrade = await loadHook();
|
||||
await act(async () => {
|
||||
root.render(createElement(TestComponent, { useUpgrade }));
|
||||
await Promise.resolve();
|
||||
await Promise.resolve();
|
||||
});
|
||||
};
|
||||
|
||||
describe('useBrowserPureP2PAccountUpgrade', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
vi.clearAllMocks();
|
||||
localStorage.clear();
|
||||
testState.account = undefined;
|
||||
testState.accounts = [];
|
||||
testState.createAccountMock.mockReset().mockResolvedValue(undefined);
|
||||
testState.setAccountMock.mockReset().mockResolvedValue(undefined);
|
||||
reloadMock = vi.fn();
|
||||
Object.defineProperty(window, 'location', {
|
||||
configurable: true,
|
||||
value: {
|
||||
...originalLocation,
|
||||
hostname: '5chan.app',
|
||||
reload: reloadMock,
|
||||
},
|
||||
});
|
||||
window.electronApi = undefined;
|
||||
window.isElectron = false;
|
||||
container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
root = createRoot(container);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
if (root) {
|
||||
act(() => root.unmount());
|
||||
}
|
||||
container?.remove();
|
||||
Object.defineProperty(window, 'location', {
|
||||
configurable: true,
|
||||
value: originalLocation,
|
||||
});
|
||||
window.BITSOCIAL_REACT_HOOKS_ACCOUNTS_STORE_INITIALIZING = undefined;
|
||||
window.electronApi = undefined;
|
||||
window.isElectron = false;
|
||||
});
|
||||
|
||||
it('upgrades stale gateway browser accounts and reloads after saving', async () => {
|
||||
testState.account = {
|
||||
id: 'account-1',
|
||||
name: 'Account 1',
|
||||
pkcOptions: {
|
||||
httpRoutersOptions: ['https://router.old.example'],
|
||||
ipfsGatewayUrls: ['https://gateway.old.example'],
|
||||
pubsubKuboRpcClientsOptions: ['https://pubsub.old.example/api/v0'],
|
||||
},
|
||||
};
|
||||
testState.accounts = [testState.account];
|
||||
|
||||
await renderHook();
|
||||
|
||||
expect(testState.setAccountMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
id: 'account-1',
|
||||
pkcOptions: expect.objectContaining({
|
||||
ipfsGatewayUrls: undefined,
|
||||
libp2pJsClientsOptions: [{ key: 'libp2pjs' }],
|
||||
pkcRpcClientsOptions: undefined,
|
||||
pubsubKuboRpcClientsOptions: undefined,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect(reloadMock).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('does not upgrade browser full-node accounts', async () => {
|
||||
testState.account = {
|
||||
id: 'account-1',
|
||||
name: 'Account 1',
|
||||
pkcOptions: {
|
||||
pkcRpcClientsOptions: ['ws://node.example/key'],
|
||||
},
|
||||
};
|
||||
testState.accounts = [testState.account];
|
||||
|
||||
await renderHook();
|
||||
|
||||
expect(testState.setAccountMock).not.toHaveBeenCalled();
|
||||
expect(reloadMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('recovers a missing browser account after the hooks store finishes initializing', async () => {
|
||||
vi.useFakeTimers();
|
||||
window.BITSOCIAL_REACT_HOOKS_ACCOUNTS_STORE_INITIALIZING = true;
|
||||
|
||||
await renderHook();
|
||||
|
||||
await act(async () => {
|
||||
await vi.advanceTimersByTimeAsync(1000);
|
||||
});
|
||||
expect(testState.createAccountMock).not.toHaveBeenCalled();
|
||||
|
||||
window.BITSOCIAL_REACT_HOOKS_ACCOUNTS_STORE_INITIALIZING = false;
|
||||
await act(async () => {
|
||||
await vi.advanceTimersByTimeAsync(1000);
|
||||
await Promise.resolve();
|
||||
});
|
||||
|
||||
expect(testState.createAccountMock).toHaveBeenCalledOnce();
|
||||
expect(reloadMock).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('treats temporarily missing accounts as empty while recovering', async () => {
|
||||
vi.useFakeTimers();
|
||||
testState.accounts = undefined;
|
||||
window.BITSOCIAL_REACT_HOOKS_ACCOUNTS_STORE_INITIALIZING = false;
|
||||
|
||||
await renderHook();
|
||||
|
||||
await act(async () => {
|
||||
await vi.advanceTimersByTimeAsync(1000);
|
||||
await Promise.resolve();
|
||||
});
|
||||
|
||||
expect(testState.createAccountMock).toHaveBeenCalledOnce();
|
||||
expect(reloadMock).toHaveBeenCalledOnce();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user