模型选择保存期间禁用选项,避免并发选择竞态
针对 review 提出的 P2:保存 select_game_creator_model 期间重新打开菜单再选一次会挂起两条 invoke,完成第一条即解锁发送导致显示/配置错乱 保存期间禁用下拉选项(可查看菜单,不可再选),保存完成后恢复;补充并发回归测试
This commit is contained in:
@@ -160,6 +160,7 @@ export function ConversationModelSelect({
|
||||
type="button"
|
||||
role="option"
|
||||
aria-selected={model.id === selected}
|
||||
disabled={disabled || busy}
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
void select(model.id);
|
||||
|
||||
@@ -137,3 +137,42 @@ test('marks the default model in the menu', async () => {
|
||||
const fastOption = screen.getByRole('option', { name: '快速' });
|
||||
expect(within(fastOption).queryByText('默认')).toBeNull();
|
||||
});
|
||||
|
||||
test('keeps model options disabled while a selection save is in flight', async () => {
|
||||
let resolveSave: ((value: unknown) => void) | undefined;
|
||||
invoke.mockImplementation(async (command, input) => {
|
||||
if (command === 'select_game_creator_model') {
|
||||
return new Promise((resolve) => {
|
||||
resolveSave = resolve;
|
||||
});
|
||||
}
|
||||
return { config: { selectedModelId: 'quality' } };
|
||||
});
|
||||
const onReady = vi.fn();
|
||||
render(<ConversationModelSelect disabled={false} onReady={onReady} />);
|
||||
await screen.findByRole('button', { name: '对话模型' });
|
||||
await waitFor(() => expect(onReady).toHaveBeenLastCalledWith(true));
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '对话模型' }));
|
||||
await screen.findByRole('option', { name: '快速' });
|
||||
fireEvent.click(screen.getByRole('option', { name: '快速' }));
|
||||
|
||||
// 保存期间重新打开菜单:可以查看,但选项应禁用,避免并发选择。
|
||||
fireEvent.click(screen.getByRole('button', { name: '对话模型' }));
|
||||
expect(screen.getByRole('option', { name: '快速' })).toHaveProperty(
|
||||
'disabled',
|
||||
true,
|
||||
);
|
||||
expect(screen.getByRole('option', { name: /高质量/ })).toHaveProperty(
|
||||
'disabled',
|
||||
true,
|
||||
);
|
||||
expect(onReady).toHaveBeenLastCalledWith(false);
|
||||
|
||||
resolveSave?.({ config: { selectedModelId: 'fast' } });
|
||||
await waitFor(() => expect(onReady).toHaveBeenLastCalledWith(true));
|
||||
expect(screen.getByRole('option', { name: '快速' })).toHaveProperty(
|
||||
'disabled',
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user