Files
Genarrative/src/components/platform-entry/PlatformProfilePrimitives.test.tsx
T
kdletters ba000111d7 收口原生能力可信边界
H5 原生能力只信任真实 host.getRuntime 回包

移除桌面壳未声明网络事件白名单

补齐原生壳能力门控测试和共享决策记录
2026-06-21 18:08:02 +08:00

151 lines
4.2 KiB
TypeScript

/* @vitest-environment jsdom */
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Settings } from 'lucide-react';
import { beforeEach, describe, expect, test, vi } from 'vitest';
import {
ICP_RECORD_NUMBER,
ICP_RECORD_URL,
LEGAL_DOCUMENTS,
} from '../common/legalDocuments';
import {
ProfileLegalSection,
ProfileSettingsRow,
ProfileShortcutButton,
ProfileStatCard,
} from './PlatformProfilePrimitives';
vi.mock('../../services/host-bridge/hostBridge', () => ({
getHostRuntime: vi.fn(() => ({
kind: 'browser',
clientType: null,
clientRuntime: null,
hostShell: null,
hostPlatform: null,
hostVersion: null,
hostCapabilities: [],
nativeRuntimeTrusted: false,
miniProgramEnv: null,
})),
openHostExternalUrl: vi.fn(async () => false),
}));
import {
getHostRuntime,
openHostExternalUrl,
} from '../../services/host-bridge/hostBridge';
function TestIcon({ className }: { className?: string }) {
return <span className={className}>I</span>;
}
beforeEach(() => {
vi.mocked(getHostRuntime).mockReturnValue({
kind: 'browser',
clientType: null,
clientRuntime: null,
hostShell: null,
hostPlatform: null,
hostVersion: null,
hostCapabilities: [],
nativeRuntimeTrusted: false,
miniProgramEnv: null,
});
vi.mocked(openHostExternalUrl).mockResolvedValue(false);
});
describe('PlatformProfilePrimitives', () => {
test('ProfileStatCard reports its dashboard card key on click', async () => {
const user = userEvent.setup();
const onClick = vi.fn();
render(
<ProfileStatCard
cardKey="wallet"
label="泥点余额"
value="88"
icon={TestIcon}
onClick={onClick}
/>,
);
await user.click(screen.getByRole('button', { name: /泥点余额\s*88/u }));
expect(onClick).toHaveBeenCalledWith('wallet');
});
test('ProfileShortcutButton keeps shortcut label and sub label visible', () => {
render(
<ProfileShortcutButton
label="玩家社区"
subLabel="交流心得"
icon={TestIcon}
onClick={vi.fn()}
/>,
);
const button = screen.getByRole('button', { name: /玩家社区/u });
expect(button.className).toContain('platform-profile-shortcut-button');
expect(screen.getByText('交流心得')).toBeTruthy();
});
test('ProfileSettingsRow and ProfileLegalSection keep their click affordances', async () => {
const user = userEvent.setup();
const onSettingsClick = vi.fn();
const onOpenDocument = vi.fn();
const firstLegalDocument = LEGAL_DOCUMENTS[0];
if (!firstLegalDocument) {
throw new Error('expected legal documents fixtures');
}
render(
<>
<ProfileSettingsRow
label="通用设置"
icon={Settings}
onClick={onSettingsClick}
/>
<ProfileLegalSection onOpenDocument={onOpenDocument} />
</>,
);
const settingsButton = screen.getByRole('button', { name: /通用设置/u });
expect(settingsButton.className).toContain('platform-navigable-list-item');
await user.click(settingsButton);
expect(onSettingsClick).toHaveBeenCalledTimes(1);
await user.click(
screen.getByRole('button', { name: firstLegalDocument.title }),
);
expect(onOpenDocument).toHaveBeenCalledWith(firstLegalDocument.id);
expect(screen.getByText(ICP_RECORD_NUMBER)).toBeTruthy();
});
test('ProfileLegalSection 在原生 App 中通过宿主打开备案外链', async () => {
const user = userEvent.setup();
vi.mocked(getHostRuntime).mockReturnValue({
kind: 'native_app',
clientType: 'native_app',
clientRuntime: 'native_app',
hostShell: 'expo_mobile',
hostPlatform: 'ios',
hostVersion: '0.1.0',
hostCapabilities: ['app.openExternalUrl'],
nativeRuntimeTrusted: true,
miniProgramEnv: null,
});
vi.mocked(openHostExternalUrl).mockResolvedValue(true);
render(<ProfileLegalSection onOpenDocument={vi.fn()} />);
await user.click(screen.getByRole('link', { name: ICP_RECORD_NUMBER }));
expect(openHostExternalUrl).toHaveBeenCalledWith({
url: ICP_RECORD_URL,
});
});
});