fix(cloud-agents): 移除微信本人配对入口

This commit is contained in:
2026-09-13 23:24:08 +08:00
parent 4ca1f89a7e
commit 8c1b161d0e
8 changed files with 100 additions and 38 deletions

View File

@@ -85,9 +85,10 @@ test('own WeChat conversation approval and generated PPT delivery in the desktop
await expect.poll(async () => app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string; input: unknown }[] }).cloudChannelFixtureCalls.some(call => call.operation === 'wechatBindVerification'))).toBe(true);
if (await page.getByRole('button', { name: '关闭二维码', exact: true }).count()) await page.getByRole('button', { name: '关闭二维码', exact: true }).click();
await page.getByRole('button', { name: '使用权限', exact: true }).click();
await page.getByRole('button', { name: '生成本人配对码', exact: true }).click();
await expect(page.getByText('TEST1234', { exact: true })).toBeVisible();
await page.getByRole('button', { name: '隐藏', exact: true }).click();
await expect(page.getByText('使用绑定时扫码的微信,直接发送消息即可。', { exact: true })).toBeVisible();
await expect(page.getByRole('button', { name: '生成本人配对码', exact: true })).toHaveCount(0);
expect(await app.evaluate(() => (globalThis as typeof globalThis & { cloudChannelFixtureCalls: { operation: string }[] }).cloudChannelFixtureCalls.some(call => call.operation === 'createChannelPairing'))).toBe(false);
await page.screenshot({ path: testInfo.outputPath('wechat-access-without-pairing.png') });
await page.getByRole('button', { name: '连接微信', exact: true }).click();
await page.screenshot({ path: testInfo.outputPath('wechat-publication.png') });
await app.evaluate(({ BrowserWindow }) => { const win = BrowserWindow.getAllWindows()[0]; win.setMinimumSize(800, 600); win.setSize(980, 680); });

View File

@@ -67,14 +67,31 @@ it('requires an explicit enable confirmation and sends the typed binding operati
expect(typeof input.operation_id).toBe('string');
});
it('uses the pairing code command and does not mutate when the access tab is opened', async () => {
it('uses the bound WeChat identity without offering or requesting a self pairing code', async () => {
render(<CloudChannelPanel slug={slug} publishedVersion={2} />);
await screen.findByRole('button', { name: '使用权限' });
fireEvent.click(screen.getByRole('button', { name: '使用权限' }));
fireEvent.click(await screen.findByRole('button', { name: '生成本人配对码' }));
await screen.findByText('ABC123');
expect(api.call.mock.calls.some(call => call[0] === 'channelPolicy')).toBe(false);
expect(api.call.mock.calls.find(call => call[0] === 'createChannelPairing')?.[1]).toEqual(expect.objectContaining({ kind: 'self', channel_account_id: 'wechat-1' }));
fireEvent.click(await screen.findByRole('button', { name: '使用权限' }));
await screen.findByText('使用绑定时扫码的微信,直接发送消息即可。');
expect(screen.queryByRole('button', { name: '生成本人配对码' })).toBeNull();
expect(screen.queryByRole('button', { name: '生成邀请码' })).toBeNull();
expect(api.call.mock.calls.some(call => ['createChannelPairing', 'channelPolicy'].includes(call[0]))).toBe(false);
});
it('still requires an explicit invitation for other contacts and copies the complete command', async () => {
const base = api.call.getMockImplementation()!;
api.call.mockImplementation(async (operation: string, input) => {
if (operation === 'channelBindings') return { items: [{ ...binding, access_mode: 'invited' }], available_accounts: [] };
if (operation === 'createChannelPairing') return { invitation_id: 'invite-a', binding_id: 'binding-1', provider_generation: 'provider-1', kind: 'invite', consumed: false, code: 'INVITE123' };
return base(operation, input);
});
const copy = vi.fn().mockResolvedValue(undefined);
Object.defineProperty(navigator, 'clipboard', { configurable: true, value: { writeText: copy } });
render(<CloudChannelPanel slug={slug} publishedVersion={2} />);
fireEvent.click(await screen.findByRole('button', { name: '使用权限' }));
fireEvent.click(await screen.findByRole('button', { name: '生成邀请码' }));
await screen.findByText('INVITE123');
fireEvent.click(screen.getByRole('button', { name: '复制邀请命令' }));
expect(copy).toHaveBeenCalledWith('邀请 INVITE123');
expect(api.call.mock.calls.find(call => call[0] === 'createChannelPairing')?.[1]).toEqual(expect.objectContaining({ kind: 'invite', channel_account_id: 'wechat-1' }));
});
it('looks up delivery by the result message ID before offering file retry', async () => {
@@ -151,7 +168,7 @@ it('drops an old QR session when switching bindings and ignores its late status'
const oldStatus = new Promise(resolve => { releaseOldStatus = resolve; });
let statusCalls = 0;
api.call.mockImplementation(async (operation: string, input: Record<string, unknown>) => {
if (operation === 'channelBindings') return { items: [binding, bindingB], available_accounts: [] };
if (operation === 'channelBindings') return { items: [{ ...binding, access_mode: 'invited' }, bindingB], available_accounts: [] };
if (operation === 'channelCallers') return { items: [] };
if (operation === 'channelActivity') return { items: [], next_offset: null };
if (operation === 'wechatBindStart') return { session_key: 'session-a', status: 'waiting', qrcode_url: 'https://provider.example/qr-a' };
@@ -181,16 +198,16 @@ it('clears the previous binding pairing, callers, and activity when switching ac
delivery: { state: 'known' }, timing: { created_at: '2026-09-13T00:00:00Z' },
};
api.call.mockImplementation(async (operation: string, input: Record<string, unknown>) => {
if (operation === 'channelBindings') return { items: [binding, bindingB], available_accounts: [] };
if (operation === 'channelBindings') return { items: [{ ...binding, access_mode: 'invited' }, bindingB], available_accounts: [] };
if (operation === 'channelCallers') return { items: input.channel_account_id === 'wechat-1' ? [callerA] : [] };
if (operation === 'channelActivity') return { items: input.channel_account_id === 'wechat-1' ? [activityA] : [], next_offset: null };
if (operation === 'createChannelPairing') return { binding_id: 'binding-1', provider_generation: 'provider-1', kind: 'self', consumed: false, code: 'PAIR-A' };
if (operation === 'createChannelPairing') return { binding_id: 'binding-1', provider_generation: 'provider-1', kind: 'invite', consumed: false, code: 'PAIR-A' };
throw new Error(`Unexpected operation ${operation}`);
});
render(<CloudChannelPanel slug={slug} publishedVersion={2} />);
fireEvent.click(await screen.findByRole('button', { name: '使用权限' }));
await screen.findByText('受邀联系人', { exact: true });
fireEvent.click(screen.getByRole('button', { name: '生成本人配对码' }));
fireEvent.click(screen.getByRole('button', { name: '生成邀请码' }));
await screen.findByText('PAIR-A');
fireEvent.click(screen.getByRole('button', { name: '活动记录' }));
await screen.findByText('词元 7');
@@ -198,7 +215,7 @@ it('clears the previous binding pairing, callers, and activity when switching ac
fireEvent.change(await screen.findByLabelText('当前渠道'), { target: { value: 'wechat-2' } });
await waitFor(() => expect(screen.queryByText('PAIR-A')).toBeNull());
fireEvent.click(screen.getByRole('button', { name: '使用权限' }));
await screen.findByText('还没有已配对的调用者。');
await screen.findByText('首次收到你的微信消息后,会在这里显示本人会话。');
expect(screen.queryByText('受邀联系人', { exact: true })).toBeNull();
fireEvent.click(screen.getByRole('button', { name: '活动记录' }));
await screen.findByText('还没有渠道活动。');