fix(ui): preserve upstream behavior after performance rebase

This commit is contained in:
c_w_xiaohei
2026-08-26 00:42:36 +08:00
parent 9b9d7069c7
commit 532bdab5e8
34 changed files with 752 additions and 361 deletions
+93
View File
@@ -548,6 +548,99 @@ describe('updateDesktopSettings', () => {
});
});
test('does not broadcast a stale project selection over a newer pending update', async () => {
const firstSave = deferred<SettingsPayload>();
const savedChanges: Array<Partial<SettingsPayload>> = [];
registerSettingsSave(async (changes) => {
savedChanges.push(changes);
if (savedChanges.length === 1) return firstSave.promise;
return changes as SettingsPayload;
});
const syncedSettings: SettingsPayload[] = [];
const handleSettingsSynced = (event: Event) => {
syncedSettings.push((event as CustomEvent<SettingsPayload>).detail);
};
getWindow().addEventListener('openchamber:settings-synced', handleSettingsSynced);
try {
const firstUpdate = updateDesktopSettings({ activeProjectId: 'project-a' });
await delay(250);
const secondUpdate = updateDesktopSettings({ activeProjectId: 'project-b' });
firstSave.resolve({ activeProjectId: 'project-a' });
await firstUpdate;
expect(syncedSettings.at(-1)?.activeProjectId).toBe('project-b');
await secondUpdate;
} finally {
getWindow().removeEventListener('openchamber:settings-synced', handleSettingsSynced);
}
});
test('does not broadcast a stale loaded project selection over a newer pending update', async () => {
const loadedSettings = deferred<{ settings: SettingsPayload; source: 'web' | 'vscode' }>();
registerSettingsApi(async (changes) => changes as SettingsPayload, () => loadedSettings.promise);
invalidateSettingsCache();
const syncedSettings: SettingsPayload[] = [];
const handleSettingsSynced = (event: Event) => {
syncedSettings.push((event as CustomEvent<SettingsPayload>).detail);
};
getWindow().addEventListener('openchamber:settings-synced', handleSettingsSynced);
try {
const sync = syncDesktopSettings();
const update = updateDesktopSettings({ activeProjectId: 'project-b' });
loadedSettings.resolve({
settings: {
activeProjectId: 'project-a',
draftStartersCraftGoalAdded: true,
draftStartersScheduleTaskAdded: true,
},
source: 'web',
});
await sync;
expect(syncedSettings.at(-1)?.activeProjectId).toBe('project-b');
await update;
} finally {
getWindow().removeEventListener('openchamber:settings-synced', handleSettingsSynced);
}
});
test('does not broadcast a stale load after a newer project update has saved', async () => {
const loadedSettings = deferred<{ settings: SettingsPayload; source: 'web' | 'vscode' }>();
registerSettingsApi(async (changes) => changes as SettingsPayload, () => loadedSettings.promise);
invalidateSettingsCache();
const syncedSettings: SettingsPayload[] = [];
const handleSettingsSynced = (event: Event) => {
syncedSettings.push((event as CustomEvent<SettingsPayload>).detail);
};
getWindow().addEventListener('openchamber:settings-synced', handleSettingsSynced);
try {
const sync = syncDesktopSettings();
const update = updateDesktopSettings({ activeProjectId: 'project-b' });
await update;
loadedSettings.resolve({
settings: {
activeProjectId: 'project-a',
draftStartersCraftGoalAdded: true,
draftStartersScheduleTaskAdded: true,
},
source: 'web',
});
await sync;
expect(syncedSettings.at(-1)?.activeProjectId).toBe('project-b');
} finally {
getWindow().removeEventListener('openchamber:settings-synced', handleSettingsSynced);
}
});
test('applies model selector settings from server settings', async () => {
getWindow();
const settings = {