feat: replace Code conversation archive with deletion
This commit is contained in:
1 parent
140f6be8db
commit
bf101c1e52
19 files changed
+1001
-292
No files matched your search
@@ -79,6 +79,61 @@ function deferred<T>() {
|
||||
}
|
||||
|
||||
describe('coding workspace store', () => {
|
||||
it('deletes only the target and rejects stale list and metadata resurrection', async () => {
|
||||
const first = conversation('conversation-deleted', 'agent-a');
|
||||
const second = conversation('conversation-kept', 'agent-a');
|
||||
const stale = deferred<CodingConversationMetadata[]>();
|
||||
const removeConversation = vi.fn().mockResolvedValue(undefined);
|
||||
const listConversations = vi.fn().mockResolvedValueOnce([first, second])
|
||||
.mockReturnValueOnce(stale.promise).mockResolvedValue([second]);
|
||||
const store = createCodingWorkspaceStore({
|
||||
listProjects: async () => ({ projects: [project], activeProjectId: project.id }),
|
||||
getConfig: async () => ({ project, config: config([agent('agent-a')]) }),
|
||||
listConversations, removeConversation,
|
||||
});
|
||||
await store.getState().load();
|
||||
const refresh = store.getState().refreshConversations(project.id);
|
||||
await vi.waitFor(() => expect(listConversations).toHaveBeenCalledTimes(2));
|
||||
await store.getState().removeConversation(first.id);
|
||||
stale.resolve([first, second]);
|
||||
await refresh;
|
||||
store.getState().upsertConversation(project.id, first);
|
||||
expect(removeConversation).toHaveBeenCalledWith(first.id);
|
||||
expect(store.getState().conversations).toEqual([second]);
|
||||
});
|
||||
|
||||
it('keeps a conversation available when deletion fails', async () => {
|
||||
const first = conversation('conversation-delete-failed', 'agent-a');
|
||||
const store = createCodingWorkspaceStore({
|
||||
listProjects: async () => ({ projects: [project], activeProjectId: project.id }),
|
||||
getConfig: async () => ({ project, config: config([agent('agent-a')]) }),
|
||||
listConversations: async () => [first],
|
||||
removeConversation: async () => { throw new Error('delete failed'); },
|
||||
});
|
||||
await store.getState().load();
|
||||
await expect(store.getState().removeConversation(first.id)).rejects.toThrow('delete failed');
|
||||
expect(store.getState().conversations).toEqual([first]);
|
||||
expect(store.getState().conversationErrorsByProjectId[project.id][first.id]).toBe('delete failed');
|
||||
});
|
||||
|
||||
it('does not overwrite another project after a pending deletion completes', async () => {
|
||||
const first = conversation('conversation-old-project', 'agent-a');
|
||||
const other = conversation('conversation-new-project', 'agent-b');
|
||||
const deletion = deferred<void>();
|
||||
const store = createCodingWorkspaceStore({
|
||||
listProjects: async () => ({ projects: [project], activeProjectId: project.id }),
|
||||
getConfig: async () => ({ project, config: config([agent('agent-a')]) }),
|
||||
listConversations: async () => [first],
|
||||
removeConversation: () => deletion.promise,
|
||||
});
|
||||
await store.getState().load();
|
||||
const pending = store.getState().removeConversation(first.id);
|
||||
store.setState({ activeProjectId: 'other-project', conversations: [other] });
|
||||
deletion.resolve();
|
||||
await pending;
|
||||
expect(store.getState().conversations).toEqual([other]);
|
||||
});
|
||||
|
||||
it('discards a stale list read and refreshes after a manual rename', async () => {
|
||||
const old = conversation('conversation-a', 'agent-a');
|
||||
const stale = deferred<CodingConversationMetadata[]>();
|
||||
|
||||
Reference in new issue
Block a user