@@ -25,20 +25,25 @@ import { FileSystem } from '../../shared/fs/fs'
25
25
import { ReadmeBuilder } from './mockContent'
26
26
import * as path from 'path'
27
27
describe ( `Controller - Doc Generation` , ( ) => {
28
- const tabID = '123'
29
- const conversationID = '456'
30
- const uploadID = '789'
28
+ const firstTabID = '123'
29
+ const firstConversationID = '123'
30
+ const firstUploadID = '123'
31
+
32
+ const secondTabID = '456'
33
+ const secondConversationID = '456'
34
+ const secondUploadID = '456'
31
35
32
36
let controllerSetup : ControllerSetup
33
37
let session : Session
34
38
let sendDocTelemetrySpy : sinon . SinonStub
39
+ let sendDocTelemetrySpyForSecondTab : sinon . SinonStub
35
40
let mockGetCodeGeneration : sinon . SinonStub
36
41
let getSessionStub : sinon . SinonStub
37
42
let modifiedReadme : string
38
43
const generatedReadme = ReadmeBuilder . createBaseReadme ( )
39
44
let sandbox : sinon . SinonSandbox
40
45
41
- const getFilePaths = ( controllerSetup : ControllerSetup ) : NewFileInfo [ ] => [
46
+ const getFilePaths = ( controllerSetup : ControllerSetup , uploadID : string ) : NewFileInfo [ ] => [
42
47
{
43
48
zipFilePath : path . normalize ( 'README.md' ) ,
44
49
relativePath : path . normalize ( 'README.md' ) ,
@@ -50,7 +55,12 @@ describe(`Controller - Doc Generation`, () => {
50
55
} ,
51
56
]
52
57
53
- async function createCodeGenState ( sandbox : sinon . SinonSandbox ) {
58
+ async function createCodeGenState (
59
+ sandbox : sinon . SinonSandbox ,
60
+ tabID : string ,
61
+ conversationID : string ,
62
+ uploadID : string
63
+ ) {
54
64
mockGetCodeGeneration = sandbox . stub ( ) . resolves ( { codeGenerationStatus : { status : 'Complete' } } )
55
65
56
66
const workspaceFolders = [ controllerSetup . workspaceFolder ] as CurrentWsFolders
@@ -69,7 +79,15 @@ describe(`Controller - Doc Generation`, () => {
69
79
workspaceFolders,
70
80
}
71
81
72
- const codeGenState = new DocCodeGenState ( testConfig , getFilePaths ( controllerSetup ) , [ ] , [ ] , tabID , 0 , { } )
82
+ const codeGenState = new DocCodeGenState (
83
+ testConfig ,
84
+ getFilePaths ( controllerSetup , uploadID ) ,
85
+ [ ] ,
86
+ [ ] ,
87
+ tabID ,
88
+ 0 ,
89
+ { }
90
+ )
73
91
return createSession ( {
74
92
messenger : controllerSetup . messenger ,
75
93
sessionState : codeGenState ,
@@ -80,7 +98,7 @@ describe(`Controller - Doc Generation`, () => {
80
98
sandbox,
81
99
} )
82
100
}
83
- async function fireFollowUps ( followUpTypes : FollowUpTypes [ ] , stub : sinon . SinonStub ) {
101
+ async function fireFollowUps ( followUpTypes : FollowUpTypes [ ] , stub : sinon . SinonStub , tabID : string ) {
84
102
for ( const type of followUpTypes ) {
85
103
controllerSetup . emitters . followUpClicked . fire ( {
86
104
tabID,
@@ -97,7 +115,9 @@ describe(`Controller - Doc Generation`, () => {
97
115
async function performAction (
98
116
action : 'generate' | 'update' | 'makeChanges' | 'accept' | 'edit' ,
99
117
getSessionStub : sinon . SinonStub ,
100
- message ?: string
118
+ message ?: string ,
119
+ tabID = firstTabID ,
120
+ conversationID = firstConversationID
101
121
) {
102
122
const sequences = {
103
123
generate : FollowUpSequences . generateReadme ,
@@ -107,7 +127,7 @@ describe(`Controller - Doc Generation`, () => {
107
127
accept : FollowUpSequences . acceptContent ,
108
128
}
109
129
110
- await fireFollowUps ( sequences [ action ] , getSessionStub )
130
+ await fireFollowUps ( sequences [ action ] , getSessionStub , tabID )
111
131
112
132
if ( ( action === 'makeChanges' || action === 'edit' ) && message ) {
113
133
controllerSetup . emitters . processHumanChatMessage . fire ( {
@@ -119,14 +139,14 @@ describe(`Controller - Doc Generation`, () => {
119
139
}
120
140
}
121
141
122
- async function setupTest ( sandbox : sinon . SinonSandbox ) {
142
+ async function setupTest ( sandbox : sinon . SinonSandbox , isMultiTabs ?: boolean ) {
123
143
controllerSetup = await createController ( sandbox )
124
- session = await createCodeGenState ( sandbox )
144
+ session = await createCodeGenState ( sandbox , firstTabID , firstConversationID , firstUploadID )
125
145
sendDocTelemetrySpy = sandbox . stub ( session , 'sendDocTelemetryEvent' ) . resolves ( )
126
146
sandbox . stub ( session , 'preloader' ) . resolves ( )
127
147
sandbox . stub ( session , 'send' ) . resolves ( )
128
148
Object . defineProperty ( session , '_conversationId' , {
129
- value : conversationID ,
149
+ value : firstConversationID ,
130
150
writable : true ,
131
151
configurable : true ,
132
152
} )
@@ -137,7 +157,30 @@ describe(`Controller - Doc Generation`, () => {
137
157
amazonQ : 'connected' ,
138
158
} )
139
159
sandbox . stub ( FileSystem . prototype , 'exists' ) . resolves ( false )
140
- getSessionStub = sandbox . stub ( controllerSetup . sessionStorage , 'getSession' ) . resolves ( session )
160
+ if ( isMultiTabs ) {
161
+ const secondSession = await createCodeGenState ( sandbox , secondTabID , secondConversationID , secondUploadID )
162
+ sendDocTelemetrySpyForSecondTab = sandbox . stub ( secondSession , 'sendDocTelemetryEvent' ) . resolves ( )
163
+ sandbox . stub ( secondSession , 'preloader' ) . resolves ( )
164
+ sandbox . stub ( secondSession , 'send' ) . resolves ( )
165
+ Object . defineProperty ( secondSession , '_conversationId' , {
166
+ value : secondConversationID ,
167
+ writable : true ,
168
+ configurable : true ,
169
+ } )
170
+ getSessionStub = sandbox
171
+ . stub ( controllerSetup . sessionStorage , 'getSession' )
172
+ . callsFake ( async ( tabId : string ) : Promise < Session > => {
173
+ if ( tabId === firstTabID ) {
174
+ return session
175
+ }
176
+ if ( tabId === secondTabID ) {
177
+ return secondSession
178
+ }
179
+ throw new Error ( `Unknown tab ID: ${ tabId } ` )
180
+ } )
181
+ } else {
182
+ getSessionStub = sandbox . stub ( controllerSetup . sessionStorage , 'getSession' ) . resolves ( session )
183
+ }
141
184
modifiedReadme = ReadmeBuilder . createReadmeWithRepoStructure ( )
142
185
sandbox
143
186
. stub ( vscode . workspace , 'openTextDocument' )
@@ -158,6 +201,7 @@ describe(`Controller - Doc Generation`, () => {
158
201
159
202
const retryTest = async (
160
203
testMethod : ( ) => Promise < void > ,
204
+ isMultiTabs ?: boolean ,
161
205
maxRetries : number = 3 ,
162
206
delayMs : number = 1000
163
207
) : Promise < void > => {
@@ -166,7 +210,7 @@ describe(`Controller - Doc Generation`, () => {
166
210
for ( let attempt = 1 ; attempt <= maxRetries + 1 ; attempt ++ ) {
167
211
sandbox = sinon . createSandbox ( )
168
212
try {
169
- await setupTest ( sandbox )
213
+ await setupTest ( sandbox , isMultiTabs )
170
214
await testMethod ( )
171
215
sandbox . restore ( )
172
216
return
@@ -199,7 +243,7 @@ describe(`Controller - Doc Generation`, () => {
199
243
type : 'generation' ,
200
244
...EventMetrics . INITIAL_README ,
201
245
interactionType : 'GENERATE_README' ,
202
- conversationId : conversationID ,
246
+ conversationId : firstConversationID ,
203
247
} )
204
248
205
249
await assertTelemetry ( {
@@ -217,7 +261,7 @@ describe(`Controller - Doc Generation`, () => {
217
261
type : 'generation' ,
218
262
...EventMetrics . INITIAL_README ,
219
263
interactionType : 'GENERATE_README' ,
220
- conversationId : conversationID ,
264
+ conversationId : firstConversationID ,
221
265
} )
222
266
223
267
await assertTelemetry ( {
@@ -227,14 +271,14 @@ describe(`Controller - Doc Generation`, () => {
227
271
sandbox,
228
272
} )
229
273
230
- await updateFilePaths ( session , modifiedReadme , uploadID , docScheme , controllerSetup . workspaceFolder )
274
+ await updateFilePaths ( session , modifiedReadme , firstUploadID , docScheme , controllerSetup . workspaceFolder )
231
275
await performAction ( 'makeChanges' , getSessionStub , 'add repository structure section' )
232
276
233
277
const secondExpectedEvent = createExpectedEvent ( {
234
278
type : 'generation' ,
235
279
...EventMetrics . REPO_STRUCTURE ,
236
280
interactionType : 'GENERATE_README' ,
237
- conversationId : conversationID ,
281
+ conversationId : firstConversationID ,
238
282
} )
239
283
240
284
await assertTelemetry ( {
@@ -255,7 +299,7 @@ describe(`Controller - Doc Generation`, () => {
255
299
type : 'acceptance' ,
256
300
...EventMetrics . INITIAL_README ,
257
301
interactionType : 'GENERATE_README' ,
258
- conversationId : conversationID ,
302
+ conversationId : firstConversationID ,
259
303
} )
260
304
261
305
await performAction ( 'accept' , getSessionStub )
@@ -276,7 +320,7 @@ describe(`Controller - Doc Generation`, () => {
276
320
type : 'generation' ,
277
321
...EventMetrics . REPO_STRUCTURE ,
278
322
interactionType : 'UPDATE_README' ,
279
- conversationId : conversationID ,
323
+ conversationId : firstConversationID ,
280
324
} )
281
325
282
326
await assertTelemetry ( {
@@ -293,15 +337,15 @@ describe(`Controller - Doc Generation`, () => {
293
337
await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) )
294
338
295
339
modifiedReadme = ReadmeBuilder . createReadmeWithDataFlow ( )
296
- await updateFilePaths ( session , modifiedReadme , uploadID , docScheme , controllerSetup . workspaceFolder )
340
+ await updateFilePaths ( session , modifiedReadme , firstUploadID , docScheme , controllerSetup . workspaceFolder )
297
341
298
342
await performAction ( 'makeChanges' , getSessionStub , 'add data flow section' )
299
343
300
344
const expectedEvent = createExpectedEvent ( {
301
345
type : 'generation' ,
302
346
...EventMetrics . DATA_FLOW ,
303
347
interactionType : 'UPDATE_README' ,
304
- conversationId : conversationID ,
348
+ conversationId : firstConversationID ,
305
349
callIndex : 1 ,
306
350
} )
307
351
@@ -324,7 +368,7 @@ describe(`Controller - Doc Generation`, () => {
324
368
type : 'acceptance' ,
325
369
...EventMetrics . REPO_STRUCTURE ,
326
370
interactionType : 'UPDATE_README' ,
327
- conversationId : conversationID ,
371
+ conversationId : firstConversationID ,
328
372
} )
329
373
330
374
await performAction ( 'accept' , getSessionStub )
@@ -346,7 +390,7 @@ describe(`Controller - Doc Generation`, () => {
346
390
type : 'generation' ,
347
391
...EventMetrics . REPO_STRUCTURE ,
348
392
interactionType : 'EDIT_README' ,
349
- conversationId : conversationID ,
393
+ conversationId : firstConversationID ,
350
394
} )
351
395
352
396
await assertTelemetry ( {
@@ -366,7 +410,7 @@ describe(`Controller - Doc Generation`, () => {
366
410
type : 'acceptance' ,
367
411
...EventMetrics . REPO_STRUCTURE ,
368
412
interactionType : 'EDIT_README' ,
369
- conversationId : conversationID ,
413
+ conversationId : firstConversationID ,
370
414
} )
371
415
372
416
await performAction ( 'accept' , getSessionStub )
@@ -379,4 +423,40 @@ describe(`Controller - Doc Generation`, () => {
379
423
} )
380
424
} )
381
425
} )
426
+ it ( 'should emit separate telemetry events when executing /doc in different tabs' , async ( ) => {
427
+ await retryTest ( async ( ) => {
428
+ const firstSession = await getSessionStub ( firstTabID )
429
+ const secondSession = await getSessionStub ( secondTabID )
430
+ await performAction ( 'generate' , firstSession )
431
+ await performAction ( 'update' , secondSession , undefined , secondTabID , secondConversationID )
432
+
433
+ const expectedEvent = createExpectedEvent ( {
434
+ type : 'generation' ,
435
+ ...EventMetrics . INITIAL_README ,
436
+ interactionType : 'GENERATE_README' ,
437
+ conversationId : firstConversationID ,
438
+ } )
439
+
440
+ await assertTelemetry ( {
441
+ spy : sendDocTelemetrySpy ,
442
+ expectedEvent,
443
+ type : 'generation' ,
444
+ sandbox,
445
+ } )
446
+
447
+ const expectedEventForSecondTab = createExpectedEvent ( {
448
+ type : 'generation' ,
449
+ ...EventMetrics . REPO_STRUCTURE ,
450
+ interactionType : 'UPDATE_README' ,
451
+ conversationId : secondConversationID ,
452
+ } )
453
+
454
+ await assertTelemetry ( {
455
+ spy : sendDocTelemetrySpyForSecondTab ,
456
+ expectedEvent : expectedEventForSecondTab ,
457
+ type : 'generation' ,
458
+ sandbox,
459
+ } )
460
+ } , true )
461
+ } )
382
462
} )
0 commit comments