Skip to content

Commit 47c1f3b

Browse files
committed
unit test thunk
1 parent 203ee82 commit 47c1f3b

File tree

1 file changed

+204
-0
lines changed

1 file changed

+204
-0
lines changed

packages/compass-collection/src/stores/collection-tab.spec.ts

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ import { createNoopLogger } from '@mongodb-js/compass-logging/provider';
1313
import { ReadOnlyPreferenceAccess } from 'compass-preferences-model/provider';
1414
import { ExperimentTestName } from '@mongodb-js/compass-telemetry/provider';
1515
import { 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 '../components/mock-data-generator-modal/types';
24+
import { CollectionActions } from '../modules/collection-tab';
25+
import { type MockDataSchemaResponse } from '@mongodb-js/compass-generative-ai';
1626

1727
const defaultMetadata = {
1828
namespace: 'test.foo',
@@ -62,7 +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;
77+
const atlasAiService = {} as any;
78+
6679
let store: ReturnType<typeof activatePlugin>['store'];
6780
let deactivate: ReturnType<typeof activatePlugin>['deactivate'];
6881

@@ -99,6 +112,7 @@ describe('Collection Tab Content store', function () {
99112
},
100113
{
101114
dataService,
115+
atlasAiService,
102116
localAppRegistry,
103117
collection: mockCollection as any,
104118
workspaces: workspaces as any,
@@ -272,4 +286,194 @@ describe('Collection Tab Content store', function () {
272286
expect(analyzeCollectionSchemaStub).to.not.have.been.called;
273287
});
274288
});
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+
namespace: 'some_db.some_collection',
295+
schemaAnalysis: {
296+
status: SCHEMA_ANALYSIS_STATE_COMPLETE,
297+
processedSchema: {
298+
name: {
299+
type: 'String',
300+
probability: 1.0,
301+
sampleValues: ['John', 'Jane', 'Bob'],
302+
},
303+
age: {
304+
type: 'Number',
305+
probability: 0.9,
306+
sampleValues: [25, 30],
307+
},
308+
isActive: {
309+
type: 'Boolean',
310+
probability: 0.8,
311+
sampleValues: [true, false],
312+
},
313+
},
314+
schemaMetadata: {
315+
maxNestingDepth: 1,
316+
validationRules: null,
317+
},
318+
},
319+
fakerSchemaGeneration: { status: MOCK_DATA_GENERATOR_STATE_IDLE },
320+
});
321+
const logger = {
322+
log: { error: sandbox.spy() },
323+
debug: sandbox.spy(),
324+
};
325+
326+
const mockDataSchemaResponse: MockDataSchemaResponse = {
327+
content: {
328+
fields: [
329+
{
330+
fieldPath: 'name',
331+
probability: 1.0,
332+
mongoType: 'string',
333+
fakerMethod: 'person.firstName',
334+
fakerArgs: [],
335+
isArray: false,
336+
},
337+
{
338+
fieldPath: 'age',
339+
probability: 1.0,
340+
mongoType: 'number',
341+
fakerMethod: 'number.int',
342+
fakerArgs: [],
343+
isArray: false,
344+
},
345+
{
346+
fieldPath: 'isActive',
347+
probability: 1.0,
348+
mongoType: 'boolean',
349+
fakerMethod: 'datatype.boolean',
350+
fakerArgs: [],
351+
isArray: false,
352+
},
353+
],
354+
},
355+
};
356+
const atlasAiService = {
357+
getMockDataSchema: sandbox.stub().resolves(mockDataSchemaResponse),
358+
};
359+
360+
// Act
361+
const thunk = collectionTabModule.generateFakerMappings(
362+
mockAtlasConnectionInfo.current
363+
);
364+
await thunk(dispatch, getState, { logger, atlasAiService } as any);
365+
366+
// Assert
367+
expect(dispatch).to.have.been.calledTwice;
368+
369+
const calls = dispatch.getCalls();
370+
const startedCall = calls[0];
371+
const completedCall = calls[1];
372+
373+
expect(startedCall).to.be.calledWith({
374+
type: CollectionActions.FakerMappingGenerationStarted,
375+
requestId: Sinon.match.string,
376+
});
377+
378+
expect(completedCall).to.be.calledWith({
379+
type: CollectionActions.FakerMappingGenerationCompleted,
380+
fakerSchema: mockDataSchemaResponse,
381+
requestId: Sinon.match.string,
382+
});
383+
});
384+
385+
it('can dispatch a failure', async function () {
386+
const dispatch = sandbox.spy();
387+
const getState = sandbox.stub().returns({
388+
namespace: 'some_db.some_collection',
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().resolves({}),
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+
});
275479
});

0 commit comments

Comments
 (0)