@@ -11,12 +11,15 @@ import { ChatDatabase, EMPTY_CONVERSATION_LIST_ID } from './tools/chatDb/chatDb'
11
11
import { Tab } from './tools/chatDb/util'
12
12
import { ConversationItemGroup , OpenTabParams , OpenTabResult } from '@aws/language-server-runtimes-types'
13
13
import { InitializeParams } from '@aws/language-server-runtimes/protocol'
14
+ import { ChatHistoryActionType } from '../../shared/telemetry/types'
15
+ import { TelemetryService } from '../../shared/telemetry/telemetryService'
14
16
15
17
describe ( 'TabBarController' , ( ) => {
16
18
let testFeatures : TestFeatures
17
19
let chatHistoryDb : ChatDatabase
18
20
let tabBarController : TabBarController
19
21
let clock : sinon . SinonFakeTimers
22
+ let telemetryService : TelemetryService
20
23
21
24
beforeEach ( ( ) => {
22
25
testFeatures = new TestFeatures ( )
@@ -29,9 +32,17 @@ describe('TabBarController', () => {
29
32
setHistoryIdMapping : sinon . stub ( ) ,
30
33
getOpenTabs : sinon . stub ( ) . returns ( [ ] ) ,
31
34
updateTabOpenState : sinon . stub ( ) ,
35
+ getDatabaseFileSize : sinon . stub ( ) ,
36
+ getLoadTime : sinon . stub ( ) ,
32
37
} as unknown as ChatDatabase
33
38
34
- tabBarController = new TabBarController ( testFeatures , chatHistoryDb )
39
+ telemetryService = {
40
+ emitChatHistoryAction : sinon . stub ( ) ,
41
+ emitExportTab : sinon . stub ( ) ,
42
+ emitLoadHistory : sinon . stub ( ) ,
43
+ } as any
44
+
45
+ tabBarController = new TabBarController ( testFeatures , chatHistoryDb , telemetryService )
35
46
clock = sinon . useFakeTimers ( )
36
47
} )
37
48
@@ -56,7 +67,7 @@ describe('TabBarController', () => {
56
67
57
68
it ( 'should perform debounced search when search filter is provided' , async ( ) => {
58
69
const mockSearchResults = [ { id : 'result1' } ]
59
- ; ( chatHistoryDb . searchMessages as sinon . SinonStub ) . returns ( mockSearchResults )
70
+ ; ( chatHistoryDb . searchMessages as sinon . SinonStub ) . returns ( { results : mockSearchResults , searchTime : 100 } )
60
71
61
72
const promise = tabBarController . onListConversations ( { filter : { search : 'test query' } } )
62
73
@@ -67,11 +78,27 @@ describe('TabBarController', () => {
67
78
68
79
assert . deepStrictEqual ( result . list , mockSearchResults )
69
80
sinon . assert . calledWith ( chatHistoryDb . searchMessages as sinon . SinonStub , 'test query' )
81
+ sinon . assert . calledWith ( telemetryService . emitChatHistoryAction as sinon . SinonStub , {
82
+ action : ChatHistoryActionType . Search ,
83
+ languageServerVersion : testFeatures . runtime . serverInfo . version ,
84
+ amazonqHistoryFileSize : undefined ,
85
+ amazonqTimeToSearchHistory : 100 ,
86
+ result : 'Succeeded' ,
87
+ } )
70
88
} )
71
89
72
90
it ( 'should clear previous timeout when multiple search requests are made' , async ( ) => {
73
91
const clearTimeoutSpy = sinon . spy ( global , 'clearTimeout' )
74
92
93
+ // Setup mock return values for searchMessages
94
+ const mockSearchResults1 = [ { id : 'result1' } ]
95
+ const mockSearchResults2 = [ { id : 'result2' } ]
96
+ ; ( chatHistoryDb . searchMessages as sinon . SinonStub )
97
+ . onFirstCall ( )
98
+ . returns ( { results : mockSearchResults1 , searchTime : 100 } )
99
+ . onSecondCall ( )
100
+ . returns ( { results : mockSearchResults2 , searchTime : 100 } )
101
+
75
102
// First search request
76
103
const promise1 = tabBarController . onListConversations ( { filter : { search : 'first query' } } )
77
104
@@ -158,7 +185,7 @@ describe('TabBarController', () => {
158
185
items : [ { id : 'history1' } , { id : 'history2' } ] ,
159
186
} ,
160
187
]
161
- ; ( chatHistoryDb . searchMessages as sinon . SinonStub ) . returns ( mockSearchResults )
188
+ ; ( chatHistoryDb . searchMessages as sinon . SinonStub ) . returns ( { results : mockSearchResults , searchTime : 100 } )
162
189
163
190
const promise = tabBarController . onListConversations ( {
164
191
filter : {
@@ -186,7 +213,7 @@ describe('TabBarController', () => {
186
213
const mockSearchResults : ConversationItemGroup [ ] = [
187
214
{ items : [ { id : 'empty' , description : 'No matches found' } ] } ,
188
215
]
189
- ; ( chatHistoryDb . searchMessages as sinon . SinonStub ) . returns ( mockSearchResults )
216
+ ; ( chatHistoryDb . searchMessages as sinon . SinonStub ) . returns ( { results : mockSearchResults , searchTime : 100 } )
190
217
191
218
const promise = tabBarController . onListConversations ( {
192
219
filter : {
@@ -218,6 +245,11 @@ describe('TabBarController', () => {
218
245
await tabBarController . onConversationClick ( { id : historyId } )
219
246
220
247
sinon . assert . calledWith ( openTabStub , { tabId : openTabId } )
248
+ sinon . assert . calledWith ( telemetryService . emitChatHistoryAction as sinon . SinonStub , {
249
+ action : ChatHistoryActionType . Open ,
250
+ languageServerVersion : testFeatures . runtime . serverInfo . version ,
251
+ result : 'Succeeded' ,
252
+ } )
221
253
} )
222
254
223
255
it ( 'should restore tab when conversation is not already open' , async ( ) => {
@@ -242,6 +274,11 @@ describe('TabBarController', () => {
242
274
const result = await tabBarController . onConversationClick ( { id : historyId , action : 'delete' } )
243
275
244
276
sinon . assert . calledWith ( chatHistoryDb . deleteHistory as sinon . SinonStub , historyId )
277
+ sinon . assert . calledWith ( telemetryService . emitChatHistoryAction as sinon . SinonStub , {
278
+ action : ChatHistoryActionType . Delete ,
279
+ languageServerVersion : testFeatures . runtime . serverInfo . version ,
280
+ result : 'Succeeded' ,
281
+ } )
245
282
assert . strictEqual ( result . success , true )
246
283
} )
247
284
@@ -313,6 +350,13 @@ describe('TabBarController', () => {
313
350
// Write serialized content to file
314
351
sinon . assert . calledWith ( fsWriteFileStub , '/testworkspace/test.md' , 'Test Serialized Content' )
315
352
353
+ sinon . assert . calledWith ( telemetryService . emitChatHistoryAction as sinon . SinonStub , {
354
+ action : ChatHistoryActionType . Export ,
355
+ languageServerVersion : testFeatures . runtime . serverInfo . version ,
356
+ filenameExt : 'markdown' ,
357
+ result : 'Succeeded' ,
358
+ } )
359
+
316
360
assert . strictEqual ( result . success , true )
317
361
} )
318
362
@@ -381,6 +425,12 @@ describe('TabBarController', () => {
381
425
// Write serialized content to file
382
426
sinon . assert . calledWith ( fsWriteFileStub , '/testworkspace/test.md' , 'Test Serialized Content' )
383
427
428
+ sinon . assert . calledWith ( telemetryService . emitExportTab as sinon . SinonStub , {
429
+ filenameExt : 'markdown' ,
430
+ languageServerVersion : testFeatures . runtime . serverInfo . version ,
431
+ result : 'Succeeded' ,
432
+ } )
433
+
384
434
assert . strictEqual ( result . success , true )
385
435
} )
386
436
} )
@@ -436,6 +486,13 @@ describe('TabBarController', () => {
436
486
sinon . assert . calledTwice ( restoreTabStub )
437
487
sinon . assert . calledWith ( restoreTabStub . firstCall , mockTabs [ 0 ] )
438
488
sinon . assert . calledWith ( restoreTabStub . secondCall , mockTabs [ 1 ] )
489
+ sinon . assert . calledWith ( telemetryService . emitLoadHistory as sinon . SinonStub , {
490
+ openTabCount : 2 ,
491
+ amazonqTimeToLoadHistory : - 1 ,
492
+ amazonqHistoryFileSize : - 1 ,
493
+ languageServerVersion : testFeatures . runtime . serverInfo . version ,
494
+ result : 'Succeeded' ,
495
+ } )
439
496
} )
440
497
441
498
it ( 'should only load chats once' , async ( ) => {
@@ -448,6 +505,14 @@ describe('TabBarController', () => {
448
505
await tabBarController . loadChats ( ) // Second call should be ignored
449
506
450
507
sinon . assert . calledOnce ( restoreTabStub )
508
+ sinon . assert . calledOnce ( telemetryService . emitLoadHistory as sinon . SinonStub )
509
+ sinon . assert . calledWith ( telemetryService . emitLoadHistory as sinon . SinonStub , {
510
+ openTabCount : 1 ,
511
+ amazonqTimeToLoadHistory : - 1 ,
512
+ amazonqHistoryFileSize : - 1 ,
513
+ languageServerVersion : testFeatures . runtime . serverInfo . version ,
514
+ result : 'Succeeded' ,
515
+ } )
451
516
} )
452
517
453
518
it ( 'should not restore tabs with empty conversations' , async ( ) => {
0 commit comments