Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/conversationStore/node/conversationStore.spec.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
7
import { IChatSessionService } from '../../../platform/chat/common/chatSessionService';
8
import { Emitter } from '../../../util/vs/base/common/event';
9
import { Conversation, Turn } from '../../prompt/common/conversation';
10
import { ConversationStore } from './conversationStore';
11
12
function createConversation(sessionId: string): Conversation {
13
return new Conversation(sessionId, [new Turn('turn-1', { message: 'test', type: 'user' })]);
14
}
15
16
describe('ConversationStore', () => {
17
let disposeChatSession: Emitter<string>;
18
let store: ConversationStore;
19
20
beforeEach(() => {
21
vi.useFakeTimers();
22
disposeChatSession = new Emitter<string>();
23
const chatSessionService: IChatSessionService = {
24
_serviceBrand: undefined,
25
onDidDisposeChatSession: disposeChatSession.event,
26
};
27
store = new ConversationStore(chatSessionService);
28
});
29
30
afterEach(() => {
31
store.dispose();
32
disposeChatSession.dispose();
33
vi.useRealTimers();
34
});
35
36
test('basic add and get', () => {
37
const conv = createConversation('session-1');
38
store.addConversation('resp-1', conv);
39
expect(store.getConversation('resp-1')).toBe(conv);
40
expect(store.lastConversation).toBe(conv);
41
});
42
43
test('cleans up session conversations after timeout', () => {
44
const conv = createConversation('session-1');
45
store.addConversation('resp-1', conv);
46
47
disposeChatSession.fire('session-1');
48
49
vi.advanceTimersByTime(10 * 60 * 1000);
50
expect(store.getConversation('resp-1')).toBeUndefined();
51
});
52
53
test('accessing conversation cancels cleanup', () => {
54
const conv = createConversation('session-1');
55
store.addConversation('resp-1', conv);
56
57
disposeChatSession.fire('session-1');
58
59
// Access before timeout — cancels cleanup entirely
60
vi.advanceTimersByTime(7 * 60 * 1000);
61
expect(store.getConversation('resp-1')).toBe(conv);
62
63
// Advance well past the original timeout — should still exist
64
vi.advanceTimersByTime(30 * 60 * 1000);
65
expect(store.getConversation('resp-1')).toBe(conv);
66
});
67
68
test('accessing lastConversation cancels cleanup', () => {
69
const conv = createConversation('session-1');
70
store.addConversation('resp-1', conv);
71
72
disposeChatSession.fire('session-1');
73
74
vi.advanceTimersByTime(7 * 60 * 1000);
75
expect(store.lastConversation).toBe(conv);
76
77
vi.advanceTimersByTime(30 * 60 * 1000);
78
expect(store.lastConversation).toBe(conv);
79
});
80
81
test('adding conversation for pending-cleanup session cancels cleanup', () => {
82
const conv1 = createConversation('session-1');
83
store.addConversation('resp-1', conv1);
84
85
disposeChatSession.fire('session-1');
86
vi.advanceTimersByTime(7 * 60 * 1000);
87
88
// Late write for the same session — cancels cleanup
89
const conv2 = createConversation('session-1');
90
store.addConversation('resp-2', conv2);
91
92
// Advance well past the original timeout — both should survive
93
vi.advanceTimersByTime(30 * 60 * 1000);
94
expect(store.getConversation('resp-1')).toBe(conv1);
95
expect(store.getConversation('resp-2')).toBe(conv2);
96
});
97
98
test('does not clean up sessions that were not disposed', () => {
99
const conv = createConversation('session-1');
100
store.addConversation('resp-1', conv);
101
102
vi.advanceTimersByTime(30 * 60 * 1000);
103
expect(store.getConversation('resp-1')).toBe(conv);
104
});
105
106
test('only cleans up the disposed session, not others', () => {
107
const conv1 = createConversation('session-1');
108
const conv2 = createConversation('session-2');
109
store.addConversation('resp-1', conv1);
110
store.addConversation('resp-2', conv2);
111
112
disposeChatSession.fire('session-1');
113
vi.advanceTimersByTime(10 * 60 * 1000);
114
115
expect(store.getConversation('resp-1')).toBeUndefined();
116
expect(store.getConversation('resp-2')).toBe(conv2);
117
});
118
});
119
120