@@ -16,37 +16,42 @@ import type { CollectionState } from '../../modules/collection-tab';
16
16
import { default as collectionTabReducer } from '../../modules/collection-tab' ;
17
17
import type { ConnectionInfo } from '@mongodb-js/connection-info' ;
18
18
import type { MockDataSchemaResponse } from '@mongodb-js/compass-generative-ai' ;
19
+ import type { SchemaAnalysisState } from '../../schema-analysis-types' ;
20
+
21
+ const defaultSchemaAnalysisState : SchemaAnalysisState = {
22
+ status : 'complete' ,
23
+ processedSchema : {
24
+ name : {
25
+ type : 'String' ,
26
+ probability : 1.0 ,
27
+ sample_values : [ 'John' , 'Jane' ] ,
28
+ } ,
29
+ } ,
30
+ sampleDocument : { name : 'John' } ,
31
+ schemaMetadata : { maxNestingDepth : 1 , validationRules : null } ,
32
+ } ;
19
33
20
34
describe ( 'MockDataGeneratorModal' , ( ) => {
21
35
async function renderModal ( {
22
36
isOpen = true ,
23
37
currentStep = MockDataGeneratorStep . SCHEMA_CONFIRMATION ,
24
38
enableGenAISampleDocumentPassing = false ,
25
39
mockServices = createMockServices ( ) ,
40
+ schemaAnalysis = defaultSchemaAnalysisState ,
26
41
connectionInfo,
27
42
} : {
28
43
isOpen ?: boolean ;
29
44
enableGenAISampleDocumentPassing ?: boolean ;
30
45
currentStep ?: MockDataGeneratorStep ;
31
46
mockServices ?: any ;
32
47
connectionInfo ?: ConnectionInfo ;
48
+ schemaAnalysis ?: SchemaAnalysisState ;
33
49
} = { } ) {
34
50
const initialState : CollectionState = {
35
51
workspaceTabId : 'test-workspace-tab-id' ,
36
52
namespace : 'test.collection' ,
37
53
metadata : null ,
38
- schemaAnalysis : {
39
- status : 'complete' ,
40
- processedSchema : {
41
- name : {
42
- type : 'String' ,
43
- probability : 1.0 ,
44
- sample_values : [ 'John' , 'Jane' ] ,
45
- } ,
46
- } ,
47
- sampleDocument : { name : 'John' } ,
48
- schemaMetadata : { maxNestingDepth : 1 , validationRules : null } ,
49
- } ,
54
+ schemaAnalysis,
50
55
fakerSchemaGeneration : {
51
56
status : 'idle' ,
52
57
} ,
@@ -284,6 +289,33 @@ describe('MockDataGeneratorModal', () => {
284
289
} ) ;
285
290
286
291
describe ( 'on the schema editor step' , ( ) => {
292
+ const mockSchemaAnalysis : SchemaAnalysisState = {
293
+ ...defaultSchemaAnalysisState ,
294
+ processedSchema : {
295
+ name : {
296
+ type : 'String' ,
297
+ probability : 1.0 ,
298
+ } ,
299
+ age : {
300
+ type : 'Int32' ,
301
+ probability : 1.0 ,
302
+ } ,
303
+ email : {
304
+ type : 'String' ,
305
+ probability : 1.0 ,
306
+ } ,
307
+ username : {
308
+ type : 'String' ,
309
+ probability : 1.0 ,
310
+ } ,
311
+ } ,
312
+ sampleDocument : {
313
+ name : 'Jane' ,
314
+ age : 99 ,
315
+
316
+ username : 'JaneDoe123' ,
317
+ } ,
318
+ } ;
287
319
const mockServicesWithMockDataResponse = createMockServices ( ) ;
288
320
mockServicesWithMockDataResponse . atlasAiService . getMockDataSchema = ( ) =>
289
321
Promise . resolve ( {
@@ -336,19 +368,22 @@ describe('MockDataGeneratorModal', () => {
336
368
fields : [ ] ,
337
369
} ,
338
370
} ) ,
339
- 1000
371
+ 1
340
372
)
341
373
) ;
342
374
343
- await renderModal ( ) ;
375
+ await renderModal ( { mockServices } ) ;
344
376
345
377
// advance to the schema editor step
346
378
userEvent . click ( screen . getByText ( 'Confirm' ) ) ;
347
379
expect ( screen . getByTestId ( 'faker-schema-editor-loader' ) ) . to . exist ;
348
380
} ) ;
349
381
350
382
it ( 'shows the faker schema editor when the faker schema generation is completed' , async ( ) => {
351
- await renderModal ( { mockServices : mockServicesWithMockDataResponse } ) ;
383
+ await renderModal ( {
384
+ mockServices : mockServicesWithMockDataResponse ,
385
+ schemaAnalysis : mockSchemaAnalysis ,
386
+ } ) ;
352
387
353
388
// advance to the schema editor step
354
389
userEvent . click ( screen . getByText ( 'Confirm' ) ) ;
@@ -359,7 +394,10 @@ describe('MockDataGeneratorModal', () => {
359
394
} ) ;
360
395
361
396
it ( 'shows correct values for the faker schema editor' , async ( ) => {
362
- await renderModal ( { mockServices : mockServicesWithMockDataResponse } ) ;
397
+ await renderModal ( {
398
+ mockServices : mockServicesWithMockDataResponse ,
399
+ schemaAnalysis : mockSchemaAnalysis ,
400
+ } ) ;
363
401
364
402
// advance to the schema editor step
365
403
userEvent . click ( screen . getByText ( 'Confirm' ) ) ;
@@ -402,6 +440,124 @@ describe('MockDataGeneratorModal', () => {
402
440
) ;
403
441
} ) ;
404
442
443
+ it ( 'does not show any fields that are not in the input schema' , async ( ) => {
444
+ const mockServices = createMockServices ( ) ;
445
+ mockServices . atlasAiService . getMockDataSchema = ( ) =>
446
+ Promise . resolve ( {
447
+ content : {
448
+ fields : [
449
+ {
450
+ fieldPath : 'name' ,
451
+ mongoType : 'string' ,
452
+ fakerMethod : 'person.firstName' ,
453
+ fakerArgs : [ ] ,
454
+ isArray : false ,
455
+ probability : 1.0 ,
456
+ } ,
457
+ {
458
+ fieldPath : 'email' ,
459
+ mongoType : 'string' ,
460
+ fakerMethod : 'internet.email' ,
461
+ fakerArgs : [ ] ,
462
+ isArray : false ,
463
+ probability : 1.0 ,
464
+ } ,
465
+ ] ,
466
+ } ,
467
+ } ) ;
468
+ await renderModal ( {
469
+ mockServices,
470
+ } ) ;
471
+
472
+ // advance to the schema editor step
473
+ userEvent . click ( screen . getByText ( 'Confirm' ) ) ;
474
+
475
+ await waitFor ( ( ) => {
476
+ expect ( screen . getByTestId ( 'faker-schema-editor' ) ) . to . exist ;
477
+ } ) ;
478
+
479
+ expect ( screen . getByText ( 'name' ) ) . to . exist ;
480
+ expect ( screen . queryByText ( 'email' ) ) . to . not . exist ;
481
+ } ) ;
482
+
483
+ it ( 'shows unmapped fields as "Unrecognized"' , async ( ) => {
484
+ const mockServices = createMockServices ( ) ;
485
+ mockServices . atlasAiService . getMockDataSchema = ( ) =>
486
+ Promise . resolve ( {
487
+ content : {
488
+ fields : [
489
+ {
490
+ fieldPath : 'name' ,
491
+ mongoType : 'String' ,
492
+ fakerMethod : 'person.firstName' ,
493
+ fakerArgs : [ ] ,
494
+ isArray : false ,
495
+ probability : 1.0 ,
496
+ } ,
497
+ {
498
+ fieldPath : 'age' ,
499
+ mongoType : 'Int32' ,
500
+ fakerMethod : 'number.int' ,
501
+ fakerArgs : [ ] ,
502
+ isArray : false ,
503
+ probability : 1.0 ,
504
+ } ,
505
+ ] ,
506
+ } ,
507
+ } ) ;
508
+
509
+ await renderModal ( {
510
+ mockServices,
511
+ schemaAnalysis : {
512
+ ...defaultSchemaAnalysisState ,
513
+ processedSchema : {
514
+ name : {
515
+ type : 'String' ,
516
+ probability : 1.0 ,
517
+ } ,
518
+ age : {
519
+ type : 'Int32' ,
520
+ probability : 1.0 ,
521
+ } ,
522
+ type : {
523
+ type : 'String' ,
524
+ probability : 1.0 ,
525
+ sample_values : [ 'cat' , 'dog' ] ,
526
+ } ,
527
+ } ,
528
+ sampleDocument : { name : 'Peaches' , age : 10 , type : 'cat' } ,
529
+ } ,
530
+ } ) ;
531
+
532
+ // advance to the schema editor step
533
+ userEvent . click ( screen . getByText ( 'Confirm' ) ) ;
534
+
535
+ await waitFor ( ( ) => {
536
+ expect ( screen . getByTestId ( 'faker-schema-editor' ) ) . to . exist ;
537
+ } ) ;
538
+
539
+ // select the "name" field
540
+ userEvent . click ( screen . getByText ( 'name' ) ) ;
541
+ expect ( screen . getByLabelText ( 'JSON Type' ) ) . to . have . value ( 'String' ) ;
542
+ expect ( screen . getByLabelText ( 'Faker Function' ) ) . to . have . value (
543
+ 'person.firstName'
544
+ ) ;
545
+
546
+ // select the "age" field
547
+ userEvent . click ( screen . getByText ( 'age' ) ) ;
548
+ expect ( screen . getByLabelText ( 'JSON Type' ) ) . to . have . value ( 'Int32' ) ;
549
+ expect ( screen . getByLabelText ( 'Faker Function' ) ) . to . have . value (
550
+ 'number.int'
551
+ ) ;
552
+
553
+ // select the "type" field
554
+ userEvent . click ( screen . getByText ( 'type' ) ) ;
555
+ expect ( screen . getByLabelText ( 'JSON Type' ) ) . to . have . value ( 'String' ) ;
556
+ expect ( screen . getByLabelText ( 'Faker Function' ) ) . to . have . value (
557
+ 'Unrecognized'
558
+ ) ;
559
+ } ) ;
560
+
405
561
it ( 'disables the Next button when the faker schema mapping is not confirmed' , async ( ) => {
406
562
await renderModal ( {
407
563
mockServices : mockServicesWithMockDataResponse ,
0 commit comments