@@ -19,7 +19,7 @@ import configureStore from '../../redux/configureStore';
19
19
import SuggestAnomalyDetector from './SuggestAnomalyDetector' ;
20
20
import userEvent from '@testing-library/user-event' ;
21
21
import { HttpFetchOptionsWithPath } from '../../../../../src/core/public' ;
22
- import { getAssistantClient , getQueryService } from '../../services' ;
22
+ import { getAssistantClient , getQueryService , getUsageCollection } from '../../services' ;
23
23
24
24
const notifications = {
25
25
toasts : {
@@ -41,8 +41,10 @@ jest.mock('../../services', () => ({
41
41
} ,
42
42
} ) ,
43
43
getAssistantClient : jest . fn ( ) . mockReturnValue ( {
44
- executeAgentByName : jest . fn ( ) ,
45
- } )
44
+ agentConfigExists : jest . fn ( ) ,
45
+ executeAgentByConfigName : jest . fn ( ) ,
46
+ } ) ,
47
+ getUsageCollection : jest . fn ( ) ,
46
48
} ) ) ;
47
49
48
50
const renderWithRouter = ( ) => ( {
@@ -126,11 +128,13 @@ describe('GenerateAnomalyDetector spec', () => {
126
128
timeFieldName : '@timestamp' ,
127
129
} ,
128
130
} ) ;
129
-
131
+ ( getAssistantClient ( ) . agentConfigExists as jest . Mock ) . mockResolvedValueOnce ( {
132
+ exists : true
133
+ } ) ;
130
134
} ) ;
131
135
132
136
it ( 'renders with empty generated parameters' , async ( ) => {
133
- ( getAssistantClient ( ) . executeAgentByName as jest . Mock ) . mockResolvedValueOnce ( {
137
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockResolvedValueOnce ( {
134
138
body : {
135
139
inference_results : [
136
140
{
@@ -154,7 +158,7 @@ describe('GenerateAnomalyDetector spec', () => {
154
158
} ) ;
155
159
156
160
it ( 'renders with empty parameter' , async ( ) => {
157
- ( getAssistantClient ( ) . executeAgentByName as jest . Mock ) . mockResolvedValueOnce ( {
161
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockResolvedValueOnce ( {
158
162
body : {
159
163
inference_results : [
160
164
{
@@ -178,7 +182,7 @@ describe('GenerateAnomalyDetector spec', () => {
178
182
} ) ;
179
183
180
184
it ( 'renders with empty aggregation field or empty aggregation method' , async ( ) => {
181
- ( getAssistantClient ( ) . executeAgentByName as jest . Mock ) . mockResolvedValueOnce ( {
185
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockResolvedValueOnce ( {
182
186
body : {
183
187
inference_results : [
184
188
{
@@ -202,7 +206,7 @@ describe('GenerateAnomalyDetector spec', () => {
202
206
} ) ;
203
207
204
208
it ( 'renders with different number of aggregation methods and fields' , async ( ) => {
205
- ( getAssistantClient ( ) . executeAgentByName as jest . Mock ) . mockResolvedValueOnce ( {
209
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockResolvedValueOnce ( {
206
210
body : {
207
211
inference_results : [
208
212
{
@@ -226,7 +230,7 @@ describe('GenerateAnomalyDetector spec', () => {
226
230
} ) ;
227
231
228
232
it ( 'renders component completely' , async ( ) => {
229
- ( getAssistantClient ( ) . executeAgentByName as jest . Mock ) . mockResolvedValueOnce ( {
233
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockResolvedValueOnce ( {
230
234
body : {
231
235
inference_results : [
232
236
{
@@ -246,9 +250,143 @@ describe('GenerateAnomalyDetector spec', () => {
246
250
expect ( queryByText ( 'Detector details' ) ) . not . toBeNull ( ) ;
247
251
expect ( queryByText ( 'Advanced configuration' ) ) . not . toBeNull ( ) ;
248
252
expect ( queryByText ( 'Model Features' ) ) . not . toBeNull ( ) ;
253
+ expect ( queryByText ( 'Was this helpful?' ) ) . not . toBeNull ( ) ;
249
254
} ) ;
250
255
} ) ;
256
+ } ) ;
257
+
258
+ describe ( 'Test agent not configured' , ( ) => {
259
+ beforeEach ( ( ) => {
260
+ jest . clearAllMocks ( ) ;
261
+ const queryService = getQueryService ( ) ;
262
+ queryService . queryString . getQuery . mockReturnValue ( {
263
+ dataset : {
264
+ id : 'test-pattern' ,
265
+ title : 'test-pattern' ,
266
+ type : 'INDEX_PATTERN' ,
267
+ timeFieldName : '@timestamp' ,
268
+ } ,
269
+ } ) ;
270
+ } ) ;
271
+
272
+ it ( 'renders with empty generated parameters' , async ( ) => {
273
+ ( getAssistantClient ( ) . agentConfigExists as jest . Mock ) . mockResolvedValueOnce ( {
274
+ exists : false
275
+ } ) ;
276
+
277
+ const { queryByText } = renderWithRouter ( ) ;
278
+ expect ( queryByText ( 'Suggested anomaly detector' ) ) . not . toBeNull ( ) ;
251
279
280
+ await waitFor ( ( ) => {
281
+ expect ( getNotifications ( ) . toasts . addDanger ) . toHaveBeenCalledTimes ( 1 ) ;
282
+ expect ( getNotifications ( ) . toasts . addDanger ) . toHaveBeenCalledWith (
283
+ 'Generate parameters for creating anomaly detector failed, reason: Error: Agent for suggest anomaly detector not found, please configure an agent firstly!'
284
+ ) ;
285
+ } ) ;
286
+ } ) ;
287
+ } ) ;
288
+
289
+ describe ( 'Test feedback' , ( ) => {
290
+ let reportUiStatsMock : any ;
291
+
292
+ beforeEach ( ( ) => {
293
+ const queryService = getQueryService ( ) ;
294
+ queryService . queryString . getQuery . mockReturnValue ( {
295
+ dataset : {
296
+ id : 'test-pattern' ,
297
+ title : 'test-pattern' ,
298
+ type : 'INDEX_PATTERN' ,
299
+ timeFieldName : '@timestamp' ,
300
+ } ,
301
+ } ) ;
302
+
303
+ reportUiStatsMock = jest . fn ( ) ;
304
+ ( getUsageCollection as jest . Mock ) . mockReturnValue ( {
305
+ reportUiStats : reportUiStatsMock ,
306
+ METRIC_TYPE : {
307
+ CLICK : 'click' ,
308
+ } ,
309
+ } ) ;
310
+
311
+ ( getAssistantClient ( ) . agentConfigExists as jest . Mock ) . mockResolvedValueOnce ( {
312
+ exists : true
313
+ } ) ;
314
+ } ) ;
315
+
316
+ afterEach ( ( ) => {
317
+ jest . clearAllMocks ( ) ;
318
+ } ) ;
319
+
320
+ it ( 'should call reportMetric with thumbup when thumbs up is clicked' , async ( ) => {
321
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockResolvedValueOnce ( {
322
+ body : {
323
+ inference_results : [
324
+ {
325
+ output : [
326
+ { result : "{\"index\":\"opensearch_dashboards_sample_data_logs\",\"categoryField\":\"ip\",\"aggregationField\":\"responseLatency,response\",\"aggregationMethod\":\"avg,sum\",\"dateFields\":\"utc_time,timestamp\"}" }
327
+ ]
328
+ }
329
+ ]
330
+ }
331
+ } ) ;
332
+
333
+ const { queryByText, getByLabelText } = renderWithRouter ( ) ;
334
+ expect ( queryByText ( 'Suggested anomaly detector' ) ) . not . toBeNull ( ) ;
335
+
336
+ await waitFor ( ( ) => {
337
+ expect ( queryByText ( 'Create detector' ) ) . not . toBeNull ( ) ;
338
+ expect ( queryByText ( 'Was this helpful?' ) ) . not . toBeNull ( ) ;
339
+ } ) ;
340
+
341
+ userEvent . click ( getByLabelText ( 'feedback thumbs up' ) ) ;
342
+ expect ( reportUiStatsMock ) . toHaveBeenCalled ( ) ;
343
+ expect ( reportUiStatsMock ) . toHaveBeenCalledWith (
344
+ 'suggestAD' ,
345
+ 'click' ,
346
+ expect . stringContaining ( 'generated-' )
347
+ ) ;
348
+ expect ( reportUiStatsMock ) . toHaveBeenCalledWith (
349
+ 'suggestAD' ,
350
+ 'click' ,
351
+ expect . stringContaining ( 'thumbup-' )
352
+ ) ;
353
+ } ) ;
354
+
355
+
356
+ it ( 'should call reportMetric with thumbdown when thumbs down is clicked' , async ( ) => {
357
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockResolvedValueOnce ( {
358
+ body : {
359
+ inference_results : [
360
+ {
361
+ output : [
362
+ { result : "{\"index\":\"opensearch_dashboards_sample_data_logs\",\"categoryField\":\"ip\",\"aggregationField\":\"responseLatency,response\",\"aggregationMethod\":\"avg,sum\",\"dateFields\":\"utc_time,timestamp\"}" }
363
+ ]
364
+ }
365
+ ]
366
+ }
367
+ } ) ;
368
+
369
+ const { queryByText, getByLabelText } = renderWithRouter ( ) ;
370
+ expect ( queryByText ( 'Suggested anomaly detector' ) ) . not . toBeNull ( ) ;
371
+
372
+ await waitFor ( ( ) => {
373
+ expect ( queryByText ( 'Create detector' ) ) . not . toBeNull ( ) ;
374
+ expect ( queryByText ( 'Was this helpful?' ) ) . not . toBeNull ( ) ;
375
+ } ) ;
376
+
377
+ userEvent . click ( getByLabelText ( 'feedback thumbs down' ) ) ;
378
+ expect ( reportUiStatsMock ) . toHaveBeenCalled ( ) ;
379
+ expect ( reportUiStatsMock ) . toHaveBeenCalledWith (
380
+ 'suggestAD' ,
381
+ 'click' ,
382
+ expect . stringContaining ( 'generated-' )
383
+ ) ;
384
+ expect ( reportUiStatsMock ) . toHaveBeenCalledWith (
385
+ 'suggestAD' ,
386
+ 'click' ,
387
+ expect . stringContaining ( 'thumbdown-' )
388
+ ) ;
389
+ } ) ;
252
390
} ) ;
253
391
254
392
describe ( 'Test API calls' , ( ) => {
@@ -263,6 +401,9 @@ describe('GenerateAnomalyDetector spec', () => {
263
401
timeFieldName : '@timestamp' ,
264
402
} ,
265
403
} ) ;
404
+ ( getAssistantClient ( ) . agentConfigExists as jest . Mock ) . mockResolvedValueOnce ( {
405
+ exists : true
406
+ } ) ;
266
407
} ) ;
267
408
268
409
it ( 'All API calls execute successfully' , async ( ) => {
@@ -282,7 +423,7 @@ describe('GenerateAnomalyDetector spec', () => {
282
423
} ) ;
283
424
}
284
425
} ) ;
285
- ( getAssistantClient ( ) . executeAgentByName as jest . Mock ) . mockResolvedValueOnce ( {
426
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockResolvedValueOnce ( {
286
427
body : {
287
428
inference_results : [
288
429
{
@@ -314,7 +455,7 @@ describe('GenerateAnomalyDetector spec', () => {
314
455
} ) ;
315
456
316
457
it ( 'Generate parameters failed' , async ( ) => {
317
- ( getAssistantClient ( ) . executeAgentByName as jest . Mock ) . mockRejectedValueOnce ( 'Generate parameters failed' ) ;
458
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockRejectedValueOnce ( 'Generate parameters failed' ) ;
318
459
319
460
const { queryByText } = renderWithRouter ( ) ;
320
461
expect ( queryByText ( 'Suggested anomaly detector' ) ) . not . toBeNull ( ) ;
@@ -341,7 +482,7 @@ describe('GenerateAnomalyDetector spec', () => {
341
482
} ) ;
342
483
}
343
484
} ) ;
344
- ( getAssistantClient ( ) . executeAgentByName as jest . Mock ) . mockResolvedValueOnce ( {
485
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockResolvedValueOnce ( {
345
486
body : {
346
487
inference_results : [
347
488
{
@@ -412,7 +553,7 @@ describe('GenerateAnomalyDetector spec', () => {
412
553
} ,
413
554
} ) ;
414
555
415
- ( getAssistantClient ( ) . executeAgentByName as jest . Mock ) . mockResolvedValueOnce ( {
556
+ ( getAssistantClient ( ) . executeAgentByConfigName as jest . Mock ) . mockResolvedValueOnce ( {
416
557
body : {
417
558
inference_results : [
418
559
{
0 commit comments