feat(web): fuse Hub device modules into instance panels with SMS aggregation

- Consolidate cellular, eSIM, network and device module interactions.

- Add aggregate SMS workflows and identity-aware action controls.

- Extend SMSC privacy handling and module action icons.
This commit is contained in:
chick
2026-09-07 00:45:38 +08:00
parent 864e1bd90c
commit 6d251dab7b
17 changed files with 565 additions and 31 deletions
@@ -5,7 +5,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest';
import type { ReactElement } from 'react';
import type { InstanceContext } from '../app-shell.js';
import { SensitiveRevealProvider } from '../privacy/sensitive-reveal.js';
import { ConfigurationModule, SimModule } from './device-module-panels.js';
import { ConfigurationModule, SimModule, VowifiModule } from './device-module-panels.js';
import type { InstanceModuleSnapshot } from './instance-module-api-data-source.js';
afterEach(() => {
@@ -205,4 +205,59 @@ describe('DeviceModulePanel', () => {
expect(alert.textContent).toContain('无法加载');
expect(screen.getByRole('button', { name: '重试' })).toBeTruthy();
});
it('aggregates WiFi Calling SMS deliveries into China-day counters', async () => {
// Anchor the fixture to the current China day rather than the test runner's local timezone.
const chinaDayStartUtc = new Date(Date.now() + 8 * 3_600_000);
chinaDayStartUtc.setUTCHours(0, 0, 0, 0);
const chinaDayBase = chinaDayStartUtc.getTime() - 8 * 3_600_000;
const reader = {
read: vi.fn(async () =>
snapshot({
module: 'vowifi',
sections: [
{
key: 'smsDeliveries',
path: '/vowifi/sms/delivery?limit=20',
state: 'ok',
status: 200,
data: {
deliveries: [
{
created_at: new Date(chinaDayBase + 8 * 3_600_000).toISOString(),
direction: 'incoming',
sender: '10010',
},
{
created_at: new Date(chinaDayBase + 9 * 3_600_000).toISOString(),
direction: 'outgoing',
state: 'delivered',
},
{
created_at: new Date(chinaDayBase + 10 * 3_600_000).toISOString(),
direction: 'outgoing',
state: 'failed',
},
{
created_at: '2020-01-01T15:59:59.000Z',
direction: 'outgoing',
state: 'delivered',
},
],
},
},
],
}),
),
};
renderWithPrivacy(<VowifiModule instance={instance} reader={reader} />);
const summary = await screen.findByRole('region', { name: '今日短信统计' });
expect(summary.textContent).toContain('今日接收');
expect(summary.textContent).toContain('2 条');
expect(summary.textContent).toContain('今日发送');
expect(summary.textContent).toContain('2 条');
expect(summary.textContent).toContain('1 / 2');
expect(summary.textContent).not.toContain('10010');
});
});