@@ -13,6 +13,16 @@ import { createNoopLogger } from '@mongodb-js/compass-logging/provider';
1313import { ReadOnlyPreferenceAccess } from 'compass-preferences-model/provider' ;
1414import { ExperimentTestName } from '@mongodb-js/compass-telemetry/provider' ;
1515import { type CollectionMetadata } from 'mongodb-collection-model' ;
16+ import {
17+ SCHEMA_ANALYSIS_STATE_COMPLETE ,
18+ SCHEMA_ANALYSIS_STATE_INITIAL ,
19+ } from '../schema-analysis-types' ;
20+ import {
21+ MOCK_DATA_GENERATOR_STATE_GENERATING ,
22+ MOCK_DATA_GENERATOR_STATE_IDLE ,
23+ } from '../mock-data-generator-types' ;
24+ import { CollectionActions } from '../modules/collection-tab' ;
25+ import { type MockDataSchemaResponse } from '@mongodb-js/compass-generative-ai' ;
1626
1727const defaultMetadata = {
1828 namespace : 'test.foo' ,
@@ -62,8 +72,10 @@ describe('Collection Tab Content store', function () {
6272 const analyzeCollectionSchemaStub = sandbox
6373 . stub ( collectionTabModule , 'analyzeCollectionSchema' )
6474 . returns ( async ( ) => { } ) ;
75+
6576 const dataService = { } as any ;
6677 const atlasAiService = { } as any ;
78+
6779 let store : ReturnType < typeof activatePlugin > [ 'store' ] ;
6880 let deactivate : ReturnType < typeof activatePlugin > [ 'deactivate' ] ;
6981
@@ -274,4 +286,194 @@ describe('Collection Tab Content store', function () {
274286 expect ( analyzeCollectionSchemaStub ) . to . not . have . been . called ;
275287 } ) ;
276288 } ) ;
289+
290+ describe ( 'generateFakerMappings thunk' , function ( ) {
291+ it ( 'can complete successfully' , async function ( ) {
292+ const dispatch = sandbox . spy ( ) ;
293+ const getState = sandbox . stub ( ) . returns ( {
294+ schemaAnalysis : {
295+ status : SCHEMA_ANALYSIS_STATE_COMPLETE ,
296+ processedSchema : {
297+ collectionName : 'foo' ,
298+ databaseName : 'test' ,
299+ schema : {
300+ name : {
301+ type : 'String' ,
302+ sampleValues : [ 'John' , 'Jane' , 'Bob' ] ,
303+ probability : 1.0 ,
304+ } ,
305+ age : {
306+ type : 'Number' ,
307+ sampleValues : [ 25 , 30 , 35 ] ,
308+ probability : 0.9 ,
309+ } ,
310+ isActive : {
311+ type : 'Boolean' ,
312+ sampleValues : [ true , false ] ,
313+ probability : 0.8 ,
314+ } ,
315+ } ,
316+ } ,
317+ } ,
318+ fakerSchemaGeneration : { status : MOCK_DATA_GENERATOR_STATE_IDLE } ,
319+ } ) ;
320+ const logger = {
321+ log : { error : sandbox . spy ( ) } ,
322+ debug : sandbox . spy ( ) ,
323+ } ;
324+
325+ const mockDataSchemaResponse : MockDataSchemaResponse = {
326+ content : {
327+ fields : [
328+ {
329+ fieldPath : 'name' ,
330+ probability : 1.0 ,
331+ mongoType : 'string' ,
332+ fakerMethod : 'person.firstName' ,
333+ fakerArgs : [ ] ,
334+ isArray : false ,
335+ } ,
336+ {
337+ fieldPath : 'age' ,
338+ probability : 1.0 ,
339+ mongoType : 'number' ,
340+ fakerMethod : 'number.int' ,
341+ fakerArgs : [ ] ,
342+ isArray : false ,
343+ } ,
344+ {
345+ fieldPath : 'isActive' ,
346+ probability : 1.0 ,
347+ mongoType : 'boolean' ,
348+ fakerMethod : 'datatype.boolean' ,
349+ fakerArgs : [ ] ,
350+ isArray : false ,
351+ } ,
352+ ] ,
353+ } ,
354+ } ;
355+ const atlasAiService = {
356+ getMockDataSchema : sandbox
357+ . stub ( )
358+ . returns ( Promise . resolve ( mockDataSchemaResponse ) ) ,
359+ } ;
360+
361+ // Act
362+ const thunk = collectionTabModule . generateFakerMappings (
363+ mockAtlasConnectionInfo . current
364+ ) ;
365+ await thunk ( dispatch , getState , { logger, atlasAiService } as any ) ;
366+
367+ // Assert
368+ expect ( dispatch ) . to . have . been . calledTwice ;
369+
370+ const calls = dispatch . getCalls ( ) ;
371+ const startedCall = calls [ 0 ] ;
372+ const completedCall = calls [ 1 ] ;
373+
374+ expect ( startedCall ) . to . be . calledWith ( {
375+ type : CollectionActions . FakerMappingGenerationStarted ,
376+ requestId : Sinon . match . string ,
377+ } ) ;
378+
379+ expect ( completedCall ) . to . be . calledWith ( {
380+ type : CollectionActions . FakerMappingGenerationCompleted ,
381+ fakerSchema : mockDataSchemaResponse ,
382+ requestId : Sinon . match . string ,
383+ } ) ;
384+ } ) ;
385+
386+ it ( 'can dispatch a failure' , async function ( ) {
387+ const dispatch = sandbox . spy ( ) ;
388+ const getState = sandbox . stub ( ) . returns ( {
389+ schemaAnalysis : {
390+ status : SCHEMA_ANALYSIS_STATE_COMPLETE ,
391+ processedSchema : undefined ,
392+ } ,
393+ fakerSchemaGeneration : { status : MOCK_DATA_GENERATOR_STATE_IDLE } ,
394+ } ) ;
395+ const logger = {
396+ log : { error : sandbox . spy ( ) } ,
397+ debug : sandbox . spy ( ) ,
398+ } ;
399+
400+ const atlasAiService = {
401+ getMockDataSchema : sandbox . stub ( ) . returns ( Promise . resolve ( { } ) ) ,
402+ } ;
403+
404+ // Act
405+ const thunk = collectionTabModule . generateFakerMappings (
406+ mockAtlasConnectionInfo . current
407+ ) ;
408+ await thunk ( dispatch , getState , { logger, atlasAiService } as any ) ;
409+
410+ // Assert
411+ expect ( dispatch ) . to . have . been . calledTwice ;
412+
413+ const calls = dispatch . getCalls ( ) ;
414+ const startedCall = calls [ 0 ] ;
415+ const completedCall = calls [ 1 ] ;
416+
417+ expect ( startedCall ) . to . be . calledWith ( {
418+ type : CollectionActions . FakerMappingGenerationStarted ,
419+ requestId : Sinon . match . string ,
420+ } ) ;
421+
422+ expect ( completedCall ) . to . be . calledWith ( {
423+ type : CollectionActions . FakerMappingGenerationFailed ,
424+ error : Sinon . match . string ,
425+ requestId : Sinon . match . string ,
426+ } ) ;
427+ } ) ;
428+
429+ it ( 'should not initiate if schemaAnalysis is incomplete' , async function ( ) {
430+ // Arrange
431+ const dispatch = sandbox . spy ( ) ;
432+ const getState = sandbox . stub ( ) . returns ( {
433+ schemaAnalysis : { status : SCHEMA_ANALYSIS_STATE_INITIAL } ,
434+ fakerSchemaGeneration : { status : MOCK_DATA_GENERATOR_STATE_IDLE } ,
435+ } ) ;
436+ const logger = {
437+ log : { error : sandbox . spy ( ) } ,
438+ debug : sandbox . spy ( ) ,
439+ } ;
440+ const atlasAiService = { } ;
441+
442+ // Act
443+ const thunk = collectionTabModule . generateFakerMappings (
444+ mockAtlasConnectionInfo . current
445+ ) ;
446+ await thunk ( dispatch , getState , { logger, atlasAiService } as any ) ;
447+
448+ // Assert
449+ expect ( dispatch ) . to . not . have . been . called ;
450+ expect ( logger . log . error ) . to . have . been . calledOnce ;
451+ } ) ;
452+
453+ it ( 'should not initiate if fakerSchemaGeneration is in progress' , async function ( ) {
454+ // Arrange
455+ const dispatch = sandbox . spy ( ) ;
456+ const getState = sandbox . stub ( ) . returns ( {
457+ schemaAnalysis : { status : SCHEMA_ANALYSIS_STATE_COMPLETE } ,
458+ fakerSchemaGeneration : { status : MOCK_DATA_GENERATOR_STATE_GENERATING } ,
459+ } ) ;
460+ const logger = {
461+ log : { error : sandbox . spy ( ) } ,
462+ debug : sandbox . spy ( ) ,
463+ } ;
464+ const atlasAiService = {
465+ getMockDataSchema : sandbox . stub ( ) . returns ( Promise . resolve ( { } ) ) ,
466+ } ;
467+
468+ // Act
469+ const thunk = collectionTabModule . generateFakerMappings (
470+ mockAtlasConnectionInfo . current
471+ ) ;
472+ await thunk ( dispatch , getState , { logger, atlasAiService } as any ) ;
473+
474+ // Assert
475+ expect ( dispatch ) . to . not . have . been . called ;
476+ expect ( logger . debug ) . to . have . been . calledOnce ;
477+ } ) ;
478+ } ) ;
277479} ) ;
0 commit comments