feat(web): localize and redesign operations console

This commit is contained in:
chick
2026-07-18 22:22:41 +08:00
parent d575ab4d9d
commit abfd07f8a3
34 changed files with 1536 additions and 1058 deletions
@@ -82,25 +82,21 @@ describe('Notifications isolated safe read module', () => {
const pending = deferredSource();
render(<NotificationsModule instance={owner} dataSource={pending.source} />);
expect(screen.getByRole('status', { name: 'Notifications loading status' })).toBeTruthy();
expect(screen.getByRole('status', { name: '通知加载状态' })).toBeTruthy();
expect(pending.load).toHaveBeenCalledWith('alpha', expect.any(AbortSignal));
pending.resolve(snapshot);
const channels = await screen.findByRole('region', { name: 'Channel aggregate' });
expect(within(channels).getByText('healthy')).toBeTruthy();
const channels = await screen.findByRole('region', { name: '渠道汇总' });
expect(within(channels).getByText('正常', { selector: 'dd' })).toBeTruthy();
expect(within(channels).getByText('5')).toBeTruthy();
expect(
within(screen.getByRole('region', { name: 'Queue aggregate' })).getByText('18'),
).toBeTruthy();
expect(
within(screen.getByRole('region', { name: 'Log aggregate' })).getByText('30'),
).toBeTruthy();
expect(screen.getByText(/Observed 2026-07-17T12:00:00Z/)).toBeTruthy();
expect(within(screen.getByRole('region', { name: '队列汇总' })).getByText('18')).toBeTruthy();
expect(within(screen.getByRole('region', { name: '日志汇总' })).getByText('30')).toBeTruthy();
expect(screen.getByText(/观测时间:2026-07-17T12:00:00Z/)).toBeTruthy();
});
it('never exposes polymorphic config, endpoints, destinations, tokens, phone numbers, payloads, raw logs, or actions', async () => {
render(<NotificationsModule instance={owner} dataSource={{ load: async () => snapshot }} />);
expect(await screen.findByText(/aggregate counts and status only/i)).toBeTruthy();
expect(await screen.findByText(/仅显示汇总计数和状态/i)).toBeTruthy();
const text = document.body.textContent ?? '';
for (const secret of [
@@ -124,8 +120,8 @@ describe('Notifications isolated safe read module', () => {
it('fails closed without an injected source or authenticated owner', async () => {
const load = vi.fn<NotificationsDataSource['load']>().mockResolvedValue(snapshot);
const { rerender } = render(<NotificationsModule instance={owner} />);
expect(screen.getByRole('status', { name: 'Notifications unavailable' }).textContent).toMatch(
/no safe notifications read data source.*uncontracted production endpoint/i,
expect(screen.getByRole('status', { name: '通知不可用' }).textContent).toMatch(
/没有可用的安全通知只读数据源.*未签订契约的生产端点/i,
);
rerender(
@@ -134,7 +130,7 @@ describe('Notifications isolated safe read module', () => {
dataSource={{ load }}
/>,
);
expect(screen.getByRole('alert').textContent).toMatch(/authentication is required/i);
expect(screen.getByRole('alert').textContent).toMatch(/需要先完成认证/i);
expect(load).not.toHaveBeenCalled();
});
@@ -160,8 +156,8 @@ describe('Notifications isolated safe read module', () => {
...snapshot,
channels: { ...snapshot.channels, status: 'degraded', total: 9 },
});
expect(await screen.findByText('degraded')).toBeTruthy();
expect(screen.queryByText('healthy')).toBeNull();
expect(await screen.findByText('功能受限', { selector: 'dd' })).toBeTruthy();
expect(screen.queryByText('正常', { selector: 'dd' })).toBeNull();
});
it('uses fixed errors and retains only same-owner last-good data across refresh failure and retry', async () => {
@@ -175,18 +171,16 @@ describe('Notifications isolated safe read module', () => {
const { rerender } = render(
<NotificationsModule instance={owner} dataSource={source} refreshSignal={0} />,
);
expect(await screen.findByText('healthy')).toBeTruthy();
expect(await screen.findByText('正常', { selector: 'dd' })).toBeTruthy();
rerender(<NotificationsModule instance={owner} dataSource={source} refreshSignal={1} />);
const alert = await screen.findByRole('alert');
expect(alert.textContent).toMatch(/refresh failed; showing the last known notifications data/i);
expect(alert.textContent).toMatch(/刷新失败,正在显示上次已知的通知数据/i);
expect(alert.textContent).not.toContain('secret endpoint');
expect(screen.getByText('healthy')).toBeTruthy();
await user.click(screen.getByRole('button', { name: 'Retry loading Notifications' }));
expect(screen.getByText('正常', { selector: 'dd' })).toBeTruthy();
await user.click(screen.getByRole('button', { name: '重试加载通知数据' }));
expect(
await within(screen.getByRole('region', { name: 'Channel aggregate' })).findByText(
'available',
),
await within(screen.getByRole('region', { name: '渠道汇总' })).findByText('可用'),
).toBeTruthy();
});
@@ -204,15 +198,13 @@ describe('Notifications isolated safe read module', () => {
logs: { status: { token: 'nested-secret' }, total: Number.MAX_SAFE_INTEGER + 1, error: 3 },
};
render(<NotificationsModule instance={owner} dataSource={{ load: async () => unsafe }} />);
const logs = await screen.findByRole('region', { name: 'Log aggregate' });
const logs = await screen.findByRole('region', { name: '日志汇总' });
expect(within(logs).getByText('3')).toBeTruthy();
expect(
within(screen.getByRole('region', { name: 'Channel aggregate' })).getByText('2'),
).toBeTruthy();
expect(within(screen.getByRole('region', { name: '渠道汇总' })).getByText('2')).toBeTruthy();
expect(document.body.textContent).not.toMatch(
/api-token|channel-secret|private payload|nested-secret|Infinity|1\.5|-1/,
);
expect(screen.queryByText(/^Observed /)).toBeNull();
expect(screen.queryByText(/^观测时间:/)).toBeNull();
unsafe.channels.disabled = 99;
expect(screen.queryByText('99')).toBeNull();
});
@@ -225,7 +217,7 @@ describe('Notifications isolated safe read module', () => {
/>,
);
const alert = await screen.findByRole('alert');
expect(alert.textContent).toContain('Notifications data could not be loaded.');
expect(alert.textContent).toContain('无法加载通知数据。');
expect(alert.textContent).not.toContain('private token');
});
@@ -241,7 +233,7 @@ describe('Notifications isolated safe read module', () => {
/>,
);
const alert = await screen.findByRole('alert');
expect(alert.textContent).toContain('Notifications data could not be loaded.');
expect(alert.textContent).toContain('无法加载通知数据。');
expect(alert.textContent).not.toContain('private notification token');
});
});