feat(web): prioritize SMS operations workspace
This commit is contained in:
@@ -7,6 +7,7 @@ import { AppShell, type InstanceContext } from './app-shell.js';
|
||||
import type { AuditDataSource } from './audit/audit-page.js';
|
||||
import type { EventStreamClient } from './events/event-stream-client.js';
|
||||
import { type FleetDataSource, type FleetSnapshot } from './fleet/fleet-page.js';
|
||||
import type { FleetMessagesDataSource } from './fleet/fleet-messages-api-data-source.js';
|
||||
import type { InstanceDataSource } from './instances/instance-api-data-source.js';
|
||||
import type { JobsDataSource } from './jobs/jobs-page.js';
|
||||
|
||||
@@ -116,10 +117,27 @@ describe('React AppShell and Fleet vertical slice', () => {
|
||||
delete: remove,
|
||||
};
|
||||
|
||||
const fleetMessagesDataSource: FleetMessagesDataSource = {
|
||||
load: vi.fn(async (instanceId) =>
|
||||
instanceId === 'bravo'
|
||||
? {
|
||||
latest: {
|
||||
id: 'sms-1',
|
||||
direction: 'incoming',
|
||||
phoneNumber: '13900139000',
|
||||
content: '这是一条用于聚合页展示的最新短信内容',
|
||||
timestamp: '2026-07-19T08:30:00.000Z',
|
||||
},
|
||||
}
|
||||
: {},
|
||||
),
|
||||
};
|
||||
|
||||
render(
|
||||
<AppShell
|
||||
pathname="/fleet"
|
||||
fleetDataSource={source(async () => snapshot)}
|
||||
fleetMessagesDataSource={fleetMessagesDataSource}
|
||||
instanceDataSource={instanceDataSource}
|
||||
/>,
|
||||
);
|
||||
@@ -139,8 +157,13 @@ describe('React AppShell and Fleet vertical slice', () => {
|
||||
expect(within(card).getByText('63.2%')).toBeTruthy();
|
||||
expect(within(card).getByText('46.7 °C')).toBeTruthy();
|
||||
expect(within(card).getByText('13800138000')).toBeTruthy();
|
||||
expect(within(card).getByRole('link', { name: '管理 Bravo' }).getAttribute('href')).toBe(
|
||||
'/instances/bravo/overview',
|
||||
expect(await within(card).findByText('收到')).toBeTruthy();
|
||||
expect(within(card).getByText('13900139000')).toBeTruthy();
|
||||
expect(within(card).getByText(/这是一条用于聚合页展示/)).toBeTruthy();
|
||||
expect(within(card).getByText(/2026/)).toBeTruthy();
|
||||
expect(within(card).queryByText('能力未知')).toBeNull();
|
||||
expect(within(card).getByRole('link', { name: '查看 Bravo 的短信' }).getAttribute('href')).toBe(
|
||||
'/instances/bravo/messages',
|
||||
);
|
||||
expect(within(card).getByRole('link', { name: '编辑 Bravo' }).getAttribute('href')).toBe(
|
||||
'/settings/instances/bravo',
|
||||
@@ -154,6 +177,20 @@ describe('React AppShell and Fleet vertical slice', () => {
|
||||
expect(within(card).getByRole('status').textContent).toContain('删除请求已提交');
|
||||
});
|
||||
|
||||
it('keeps message read failures separate from instance reachability and reports each once', async () => {
|
||||
const messages: FleetMessagesDataSource = { load: vi.fn().mockRejectedValue(new Error('no')) };
|
||||
render(
|
||||
<AppShell
|
||||
pathname="/fleet"
|
||||
fleetDataSource={source(async () => snapshot)}
|
||||
fleetMessagesDataSource={messages}
|
||||
/>,
|
||||
);
|
||||
const bravo = await screen.findByRole('article', { name: 'Bravo 实例概览' });
|
||||
expect(await within(bravo).findAllByText('短信暂不可用')).toHaveLength(1);
|
||||
expect(within(bravo).getByText('需要认证')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('keeps Jobs and Audit routes compatible without advertising them in global navigation', async () => {
|
||||
const jobsDataSource: JobsDataSource = { load: vi.fn().mockResolvedValue(emptyPage) };
|
||||
const { rerender } = render(
|
||||
@@ -204,7 +241,7 @@ describe('React AppShell and Fleet vertical slice', () => {
|
||||
|
||||
expect(screen.getByRole('status').textContent).toContain('正在加载实例');
|
||||
expect(await screen.findByText('Bravo')).toBeTruthy();
|
||||
expect(screen.getByRole('heading', { name: '概览' })).toBeTruthy();
|
||||
expect(screen.getByRole('heading', { name: '设备信息' })).toBeTruthy();
|
||||
expect(screen.getByRole('link', { name: '编辑实例' }).getAttribute('href')).toBe(
|
||||
'/settings/instances/bravo',
|
||||
);
|
||||
@@ -315,7 +352,7 @@ describe('React AppShell and Fleet vertical slice', () => {
|
||||
const { rerender } = render(
|
||||
<AppShell pathname="/instances/owner/messages" instance={instance} />,
|
||||
);
|
||||
expect(screen.getByRole('heading', { name: '消息' })).toBeTruthy();
|
||||
expect(screen.getByRole('heading', { name: '短信' })).toBeTruthy();
|
||||
expect(screen.getByText('Owner modem')).toBeTruthy();
|
||||
expect(screen.getByRole('link', { name: '打开源站' }).getAttribute('href')).toBe(
|
||||
'https://owner.example',
|
||||
|
||||
Reference in New Issue
Block a user