refine Semi UI platform shell and states
This commit is contained in:
@@ -12,11 +12,15 @@ const auth = vi.hoisted(() => ({
|
||||
session: { name: 'test-user', username: 'test-user', role: 'viewer' as const } as any,
|
||||
logout: vi.fn()
|
||||
}));
|
||||
const apiMocks = vi.hoisted(() => ({
|
||||
changePassword: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('../routing/routeModules', () => routing);
|
||||
vi.mock('../auth/AuthGate', () => ({
|
||||
usePlatformSession: () => ({ session: auth.session, logout: auth.logout })
|
||||
}));
|
||||
vi.mock('../../api/client', () => ({ api: { changePassword: apiMocks.changePassword } }));
|
||||
|
||||
import { AppShell } from './AppShell';
|
||||
|
||||
@@ -25,6 +29,7 @@ afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
vi.clearAllMocks();
|
||||
auth.session = { name: 'test-user', username: 'test-user', role: 'viewer' };
|
||||
apiMocks.changePassword.mockReset();
|
||||
});
|
||||
|
||||
test('renders only explicitly assigned customer menus', () => {
|
||||
@@ -91,6 +96,8 @@ test('opens contextual help for the active module and closes it without navigati
|
||||
fireEvent.click(help);
|
||||
|
||||
expect(screen.getByRole('dialog', { name: '全局监控' })).toHaveTextContent('筛选会自动生效');
|
||||
expect(document.querySelector('.v2-help-overview.semi-card')).toBeInTheDocument();
|
||||
expect(screen.getByText('建议操作')).toBeInTheDocument();
|
||||
expect(help).toHaveAttribute('aria-expanded', 'true');
|
||||
fireEvent.click(screen.getByLabelText('关闭帮助'));
|
||||
expect(help).toHaveAttribute('aria-expanded', 'false');
|
||||
@@ -108,6 +115,7 @@ test('uses one Semi account menu for identity, password and logout actions', asy
|
||||
fireEvent.click(trigger);
|
||||
|
||||
expect(await screen.findByText('@test-user')).toBeInTheDocument();
|
||||
expect(screen.getByText('当前登录账号')).toBeInTheDocument();
|
||||
await waitFor(() => expect(screen.getByRole('button', { name: '账号菜单,test-user' })).toHaveAttribute('aria-expanded', 'true'));
|
||||
fireEvent.click(screen.getByText('修改登录密码'));
|
||||
|
||||
@@ -119,6 +127,35 @@ test('uses one Semi account menu for identity, password and logout actions', asy
|
||||
expect(auth.logout).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('validates password policy while typing and submits only a complete secure change', async () => {
|
||||
apiMocks.changePassword.mockResolvedValue({ changed: true });
|
||||
render(<MemoryRouter future={ROUTER_FUTURE} initialEntries={['/monitor']}>
|
||||
<Routes><Route element={<AppShell />}><Route path="*" element={<span>页面内容</span>} /></Route></Routes>
|
||||
</MemoryRouter>);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '账号菜单,test-user' }));
|
||||
fireEvent.click(await screen.findByText('修改登录密码'));
|
||||
|
||||
const submit = screen.getByRole('button', { name: '确认修改' });
|
||||
expect(submit).toBeDisabled();
|
||||
expect(document.querySelector('.v2-password-dialog > .semi-banner-warning')).toHaveTextContent('当前设备和其他设备上的旧会话都会失效');
|
||||
|
||||
fireEvent.change(screen.getByLabelText('当前密码'), { target: { value: 'CurrentPass!1' } });
|
||||
fireEvent.change(screen.getByLabelText('新密码'), { target: { value: 'StrongPass!1' } });
|
||||
expect(screen.getByLabelText('新密码安全规则').querySelectorAll('.is-valid')).toHaveLength(2);
|
||||
fireEvent.change(screen.getByLabelText('确认新密码'), { target: { value: 'different' } });
|
||||
expect(screen.getByRole('status')).toHaveTextContent('两次输入的新密码不一致');
|
||||
expect(submit).toBeDisabled();
|
||||
|
||||
fireEvent.change(screen.getByLabelText('确认新密码'), { target: { value: 'StrongPass!1' } });
|
||||
expect(screen.getByRole('status')).toHaveTextContent('两次输入一致');
|
||||
expect(submit).toBeEnabled();
|
||||
fireEvent.click(submit);
|
||||
|
||||
await waitFor(() => expect(apiMocks.changePassword).toHaveBeenCalledWith({ currentPassword: 'CurrentPass!1', newPassword: 'StrongPass!1' }));
|
||||
expect(auth.logout).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('uses the compact mobile navigation and opens secondary modules in a Semi SideSheet', () => {
|
||||
vi.spyOn(window, 'matchMedia').mockReturnValue({
|
||||
matches: true,
|
||||
|
||||
Reference in New Issue
Block a user