fix(feishu): feishu configuration loss (#795)
Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Haze <hazeone@users.noreply.github.com>
This commit is contained in:
@@ -104,6 +104,10 @@ export function ChannelConfigModal({
|
||||
: showAccountIdEditor
|
||||
? accountIdInput.trim()
|
||||
: (accountId ?? (agentId ? (agentId === 'main' ? 'default' : agentId) : undefined));
|
||||
const shouldLoadExistingConfig = Boolean(
|
||||
selectedType && allowExistingConfig && configuredTypes.includes(selectedType)
|
||||
);
|
||||
const accountIdForConfigLoad = shouldLoadExistingConfig ? resolvedAccountId : undefined;
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedType(initialSelectedType);
|
||||
@@ -124,7 +128,6 @@ export function ChannelConfigModal({
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldLoadExistingConfig = allowExistingConfig && configuredTypes.includes(selectedType);
|
||||
if (!shouldLoadExistingConfig) {
|
||||
setConfigValues({});
|
||||
setIsExistingConfig(false);
|
||||
@@ -147,7 +150,7 @@ export function ChannelConfigModal({
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const accountParam = resolvedAccountId ? `?accountId=${encodeURIComponent(resolvedAccountId)}` : '';
|
||||
const accountParam = accountIdForConfigLoad ? `?accountId=${encodeURIComponent(accountIdForConfigLoad)}` : '';
|
||||
const result = await hostApiFetch<{ success: boolean; values?: Record<string, string> }>(
|
||||
`/api/channels/config/${encodeURIComponent(selectedType)}${accountParam}`
|
||||
);
|
||||
@@ -173,7 +176,7 @@ export function ChannelConfigModal({
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [allowExistingConfig, configuredTypes, initialConfigValues, resolvedAccountId, selectedType, showChannelName]);
|
||||
}, [accountIdForConfigLoad, initialConfigValues, selectedType, shouldLoadExistingConfig, showChannelName]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedType && !loadingConfig && showChannelName && firstInputRef.current) {
|
||||
|
||||
82
tests/e2e/channels-account-id-persistence.spec.ts
Normal file
82
tests/e2e/channels-account-id-persistence.spec.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { completeSetup, expect, installIpcMocks, test } from './fixtures/electron';
|
||||
|
||||
function stableStringify(value: unknown): string {
|
||||
if (value == null || typeof value !== 'object') return JSON.stringify(value);
|
||||
if (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(',')}]`;
|
||||
const entries = Object.entries(value as Record<string, unknown>)
|
||||
.sort(([left], [right]) => left.localeCompare(right))
|
||||
.map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`);
|
||||
return `{${entries.join(',')}}`;
|
||||
}
|
||||
|
||||
test.describe('Channels account editor behavior', () => {
|
||||
test('keeps Feishu credentials when account ID is changed', async ({ electronApp, page }) => {
|
||||
await installIpcMocks(electronApp, {
|
||||
gatewayStatus: { state: 'running', port: 18789, pid: 12345 },
|
||||
hostApi: {
|
||||
[stableStringify(['/api/channels/accounts', 'GET'])]: {
|
||||
ok: true,
|
||||
data: {
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: {
|
||||
success: true,
|
||||
channels: [
|
||||
{
|
||||
channelType: 'feishu',
|
||||
defaultAccountId: 'default',
|
||||
status: 'connected',
|
||||
accounts: [
|
||||
{
|
||||
accountId: 'default',
|
||||
name: 'Primary Account',
|
||||
configured: true,
|
||||
status: 'connected',
|
||||
isDefault: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
[stableStringify(['/api/agents', 'GET'])]: {
|
||||
ok: true,
|
||||
data: {
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: {
|
||||
success: true,
|
||||
agents: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await completeSetup(page);
|
||||
await page.getByTestId('sidebar-nav-channels').click();
|
||||
await expect(page.getByTestId('channels-page')).toBeVisible();
|
||||
|
||||
const addAccountButton = page.locator('button').filter({
|
||||
hasText: /Add Account|添加账号|アカウントを追加/,
|
||||
}).first();
|
||||
await expect(addAccountButton).toBeVisible();
|
||||
await addAccountButton.click();
|
||||
|
||||
const appIdInput = page.locator('input#appId');
|
||||
const appSecretInput = page.locator('input#appSecret');
|
||||
const accountIdInput = page.locator('input#account-id');
|
||||
|
||||
await expect(appIdInput).toBeVisible();
|
||||
await expect(appSecretInput).toBeVisible();
|
||||
await expect(accountIdInput).toBeVisible();
|
||||
|
||||
await appIdInput.fill('cli_test_app');
|
||||
await appSecretInput.fill('secret_test_value');
|
||||
await accountIdInput.fill('feishu-renamed-account');
|
||||
|
||||
await expect(appIdInput).toHaveValue('cli_test_app');
|
||||
await expect(appSecretInput).toHaveValue('secret_test_value');
|
||||
});
|
||||
});
|
||||
@@ -270,4 +270,27 @@ describe('Channels page status refresh', () => {
|
||||
agentsDeferred.resolve({ success: true, agents: [] });
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps filled Feishu credentials when account ID is edited', async () => {
|
||||
subscribeHostEventMock.mockImplementation(() => vi.fn());
|
||||
|
||||
render(<Channels />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Feishu / Lark')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'account.add' }));
|
||||
|
||||
const appIdInput = await screen.findByPlaceholderText('channels:meta.feishu.fields.appId.placeholder');
|
||||
const appSecretInput = screen.getByPlaceholderText('channels:meta.feishu.fields.appSecret.placeholder');
|
||||
const accountIdInput = screen.getByLabelText('account.customIdLabel');
|
||||
|
||||
fireEvent.change(appIdInput, { target: { value: 'cli_test_app' } });
|
||||
fireEvent.change(appSecretInput, { target: { value: 'secret_test_value' } });
|
||||
fireEvent.change(accountIdInput, { target: { value: 'feishu-renamed-account' } });
|
||||
|
||||
expect(appIdInput).toHaveValue('cli_test_app');
|
||||
expect(appSecretInput).toHaveValue('secret_test_value');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user