Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/compass-schema-validation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"@mongodb-js/compass-field-store": "^9.25.2",
"@mongodb-js/compass-logging": "^1.6.2",
"@mongodb-js/compass-telemetry": "^1.4.2",
"@mongodb-js/compass-workspaces": "^0.31.2",
"bson": "^6.10.1",
"compass-preferences-model": "^2.33.2",
"hadron-app-registry": "^9.4.2",
Expand Down
2 changes: 2 additions & 0 deletions packages/compass-schema-validation/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { preferencesLocator } from 'compass-preferences-model/provider';
import { createLoggerLocator } from '@mongodb-js/compass-logging/provider';
import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider';
import { SchemaValidationTabTitle } from './plugin-title';
import { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider';

const CompassSchemaValidationHadronPlugin = registerHadronPlugin(
{
Expand All @@ -30,6 +31,7 @@ const CompassSchemaValidationHadronPlugin = registerHadronPlugin(
preferences: preferencesLocator,
logger: createLoggerLocator('COMPASS-SCHEMA-VALIDATION-UI'),
track: telemetryLocator,
workspaces: workspacesServiceLocator,
}
);
export const CompassSchemaValidationPlugin = {
Expand Down
2 changes: 2 additions & 0 deletions packages/compass-schema-validation/src/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import type {
import type AppRegistry from 'hadron-app-registry';
import type { Logger } from '@mongodb-js/compass-logging/provider';
import type { TrackFunction } from '@mongodb-js/compass-telemetry';
import { type WorkspacesService } from '@mongodb-js/compass-workspaces/provider';

/**
* Reset action constant.
Expand Down Expand Up @@ -67,6 +68,7 @@ export type SchemaValidationExtraArgs = {
connectionInfoRef: ConnectionInfoRef;
preferences: PreferencesAccess;
globalAppRegistry: AppRegistry;
workspaces: WorkspacesService;
logger: Logger;
track: TrackFunction;
};
Expand Down
61 changes: 44 additions & 17 deletions packages/compass-schema-validation/src/stores/store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { createSandboxFromDefaultPreferences } from 'compass-preferences-model';
import { createNoopLogger } from '@mongodb-js/compass-logging/provider';
import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider';
import type { ConnectionInfoRef } from '@mongodb-js/compass-connections/provider';
import { type WorkspacesService } from '@mongodb-js/compass-workspaces/provider';
import Sinon from 'sinon';

const topologyDescription = {
type: 'Unknown',
Expand All @@ -42,34 +44,49 @@ const fakeDataService = {
}),
} as any;

describe('Schema Validation Store', function () {
let store: Store<RootState, RootAction>;
let deactivate: null | (() => void) = null;
const fakeWorkspaces = {
onTabReplace: () => {},
onTabClose: () => {},
} as unknown as WorkspacesService;

const getMockedStore = async () => {
const globalAppRegistry = new AppRegistry();
const connectionInfoRef = {
current: {},
} as ConnectionInfoRef;
const activateResult = onActivated(
{ namespace: 'test.test' } as any,
{
globalAppRegistry: globalAppRegistry,
dataService: fakeDataService,
instance: fakeInstance,
workspaces: fakeWorkspaces,
preferences: await createSandboxFromDefaultPreferences(),
logger: createNoopLogger(),
track: createNoopTrack(),
connectionInfoRef,
},
createActivateHelpers()
);
return activateResult;
};

describe('Schema Validation Store', function () {
let store: Store<RootState, RootAction>;
let deactivate: null | (() => void) = null;
let sandbox: Sinon.SinonSandbox;

beforeEach(async function () {
const activateResult = onActivated(
{ namespace: 'test.test' } as any,
{
globalAppRegistry: globalAppRegistry,
dataService: fakeDataService,
instance: fakeInstance,
preferences: await createSandboxFromDefaultPreferences(),
logger: createNoopLogger(),
track: createNoopTrack(),
connectionInfoRef,
},
createActivateHelpers()
);
sandbox = Sinon.createSandbox();
fakeWorkspaces.onTabClose = sandbox.stub();
fakeWorkspaces.onTabReplace = sandbox.stub();
const activateResult = await getMockedStore();
store = activateResult.store;
// eslint-disable-next-line @typescript-eslint/unbound-method
deactivate = activateResult.deactivate;
});

afterEach(function () {
sandbox.reset();
deactivate?.();
deactivate = null;
});
Expand Down Expand Up @@ -128,6 +145,16 @@ describe('Schema Validation Store', function () {
});
store.dispatch(validatorChanged(validator));
});

it('prevents closing the tab', function () {
store.dispatch(validatorChanged(validator));
expect(store.getState().validation.isChanged).to.be.true;
deactivate?.();
const fnProvidedToOnTabClose = (
fakeWorkspaces.onTabClose as Sinon.SinonStub
).args[0][0];
expect(fnProvidedToOnTabClose()).to.be.false;
});
});

context('when the action is fetch valid sample documents', function () {
Expand Down
17 changes: 15 additions & 2 deletions packages/compass-schema-validation/src/stores/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ import type { MongoDBInstance } from '@mongodb-js/compass-app-stores/provider';
import type { PreferencesAccess } from 'compass-preferences-model';
import type { Logger } from '@mongodb-js/compass-logging/provider';
import type { TrackFunction } from '@mongodb-js/compass-telemetry';
import { type WorkspacesService } from '@mongodb-js/compass-workspaces/provider';

/**
* The lowest supported version.
*/
const MIN_VERSION = '3.2.0';

type SchemaValidationServices = {
export type SchemaValidationServices = {
globalAppRegistry: AppRegistry;
dataService: Pick<
DataService,
Expand All @@ -32,6 +33,7 @@ type SchemaValidationServices = {
preferences: PreferencesAccess;
instance: MongoDBInstance;
logger: Logger;
workspaces: WorkspacesService;
track: TrackFunction;
};

Expand All @@ -41,6 +43,7 @@ export function configureStore(
services: Pick<
SchemaValidationServices,
| 'globalAppRegistry'
| 'workspaces'
| 'dataService'
| 'preferences'
| 'logger'
Expand Down Expand Up @@ -70,9 +73,10 @@ export function onActivated(
preferences,
instance,
logger,
workspaces,
track,
}: SchemaValidationServices,
{ on, cleanup }: ActivateHelpers
{ on, cleanup, addCleanup }: ActivateHelpers
) {
const store = configureStore(
{
Expand All @@ -90,6 +94,7 @@ export function onActivated(
connectionInfoRef,
preferences,
globalAppRegistry,
workspaces,
logger,
track,
}
Expand All @@ -107,6 +112,14 @@ export function onActivated(
// Activate validation when this plugin is first rendered
store.dispatch(activateValidation());

const onCloseOrReplace = () => {
return !store.getState().validation.isChanged;
};

addCleanup(workspaces.onTabReplace?.(onCloseOrReplace));

addCleanup(workspaces.onTabClose?.(onCloseOrReplace));

return {
store,
deactivate: cleanup,
Expand Down
Loading