Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/test/context.spec.ts
13406 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 { beforeEach, describe, expect, it, vi } from 'vitest';
7
8
vi.mock('vscode', () => ({
9
commands: {
10
executeCommand: vi.fn().mockResolvedValue(undefined),
11
},
12
}));
13
14
import * as vscode from 'vscode';
15
import { registerCommandContext } from '../commands/context';
16
17
type Listener = (...args: unknown[]) => void;
18
19
/**
20
* A mock InProcHttpServer with controllable events and session ids.
21
*/
22
class MockHttpServerWithEvents {
23
private _connectListeners: Listener[] = [];
24
private _disconnectListeners: Listener[] = [];
25
private _connectedSessionIds: readonly string[] = [];
26
27
readonly onDidClientConnect = vi.fn((listener: Listener) => {
28
this._connectListeners.push(listener);
29
return { dispose: () => { this._connectListeners = this._connectListeners.filter(l => l !== listener); } };
30
});
31
32
readonly onDidClientDisconnect = vi.fn((listener: Listener) => {
33
this._disconnectListeners.push(listener);
34
return { dispose: () => { this._disconnectListeners = this._disconnectListeners.filter(l => l !== listener); } };
35
});
36
37
readonly getConnectedSessionIds = vi.fn((): readonly string[] => this._connectedSessionIds);
38
39
setConnectedSessionIds(ids: readonly string[]): void {
40
this._connectedSessionIds = ids;
41
}
42
43
fireConnect(): void {
44
for (const listener of this._connectListeners) {
45
listener();
46
}
47
}
48
49
fireDisconnect(): void {
50
for (const listener of this._disconnectListeners) {
51
listener();
52
}
53
}
54
}
55
56
describe('registerCommandContext', () => {
57
let mockServer: MockHttpServerWithEvents;
58
59
beforeEach(() => {
60
vi.mocked(vscode.commands.executeCommand).mockClear();
61
mockServer = new MockHttpServerWithEvents();
62
});
63
64
it('should set context to false when no sessions are connected initially', () => {
65
mockServer.setConnectedSessionIds([]);
66
registerCommandContext(mockServer as any);
67
68
expect(vscode.commands.executeCommand).toHaveBeenCalledWith(
69
'setContext',
70
'github.copilot.chat.copilotCLI.hasSession',
71
false,
72
);
73
});
74
75
it('should set context to true when sessions are connected initially', () => {
76
mockServer.setConnectedSessionIds(['session-1']);
77
registerCommandContext(mockServer as any);
78
79
expect(vscode.commands.executeCommand).toHaveBeenCalledWith(
80
'setContext',
81
'github.copilot.chat.copilotCLI.hasSession',
82
true,
83
);
84
});
85
86
it('should update context to true when a client connects', () => {
87
mockServer.setConnectedSessionIds([]);
88
registerCommandContext(mockServer as any);
89
vi.mocked(vscode.commands.executeCommand).mockClear();
90
91
mockServer.setConnectedSessionIds(['session-1']);
92
mockServer.fireConnect();
93
94
expect(vscode.commands.executeCommand).toHaveBeenCalledWith(
95
'setContext',
96
'github.copilot.chat.copilotCLI.hasSession',
97
true,
98
);
99
});
100
101
it('should update context to false when all clients disconnect', () => {
102
mockServer.setConnectedSessionIds(['session-1']);
103
registerCommandContext(mockServer as any);
104
vi.mocked(vscode.commands.executeCommand).mockClear();
105
106
mockServer.setConnectedSessionIds([]);
107
mockServer.fireDisconnect();
108
109
expect(vscode.commands.executeCommand).toHaveBeenCalledWith(
110
'setContext',
111
'github.copilot.chat.copilotCLI.hasSession',
112
false,
113
);
114
});
115
116
it('should remain true when one of multiple clients disconnects', () => {
117
mockServer.setConnectedSessionIds(['session-1', 'session-2']);
118
registerCommandContext(mockServer as any);
119
vi.mocked(vscode.commands.executeCommand).mockClear();
120
121
mockServer.setConnectedSessionIds(['session-2']);
122
mockServer.fireDisconnect();
123
124
expect(vscode.commands.executeCommand).toHaveBeenCalledWith(
125
'setContext',
126
'github.copilot.chat.copilotCLI.hasSession',
127
true,
128
);
129
});
130
131
it('should register listeners for both connect and disconnect events', () => {
132
mockServer.setConnectedSessionIds([]);
133
registerCommandContext(mockServer as any);
134
135
expect(mockServer.onDidClientConnect).toHaveBeenCalledOnce();
136
expect(mockServer.onDidClientDisconnect).toHaveBeenCalledOnce();
137
});
138
139
it('should return a disposable that cleans up event listeners', () => {
140
mockServer.setConnectedSessionIds([]);
141
const disposables = registerCommandContext(mockServer as any);
142
vi.mocked(vscode.commands.executeCommand).mockClear();
143
144
disposables.dispose();
145
146
// After disposing, firing events should not trigger context updates
147
mockServer.setConnectedSessionIds(['session-1']);
148
mockServer.fireConnect();
149
mockServer.fireDisconnect();
150
151
expect(vscode.commands.executeCommand).not.toHaveBeenCalled();
152
});
153
154
it('should handle multiple connect and disconnect events', () => {
155
mockServer.setConnectedSessionIds([]);
156
registerCommandContext(mockServer as any);
157
vi.mocked(vscode.commands.executeCommand).mockClear();
158
159
// First client connects
160
mockServer.setConnectedSessionIds(['session-1']);
161
mockServer.fireConnect();
162
expect(vscode.commands.executeCommand).toHaveBeenLastCalledWith(
163
'setContext',
164
'github.copilot.chat.copilotCLI.hasSession',
165
true,
166
);
167
168
// Second client connects
169
mockServer.setConnectedSessionIds(['session-1', 'session-2']);
170
mockServer.fireConnect();
171
expect(vscode.commands.executeCommand).toHaveBeenLastCalledWith(
172
'setContext',
173
'github.copilot.chat.copilotCLI.hasSession',
174
true,
175
);
176
177
// First client disconnects
178
mockServer.setConnectedSessionIds(['session-2']);
179
mockServer.fireDisconnect();
180
expect(vscode.commands.executeCommand).toHaveBeenLastCalledWith(
181
'setContext',
182
'github.copilot.chat.copilotCLI.hasSession',
183
true,
184
);
185
186
// Last client disconnects
187
mockServer.setConnectedSessionIds([]);
188
mockServer.fireDisconnect();
189
expect(vscode.commands.executeCommand).toHaveBeenLastCalledWith(
190
'setContext',
191
'github.copilot.chat.copilotCLI.hasSession',
192
false,
193
);
194
});
195
});
196
197