Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(compass-validation): unified validation preview CTA COMPASS-8862 #6769

Merged
merged 6 commits into from
Mar 6, 2025
Merged
Show file tree
Hide file tree
Changes from 5 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: 1 addition & 1 deletion packages/compass-e2e-tests/helpers/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,7 @@ export const UpdateValidationButton =
'[data-testid="update-validation-button"]';
export const ValidationMatchingDocumentsPreview =
'[data-testid="validation-content"] [data-testid="matching-documents"] [data-testid="document-preview"]';
export const ValidationLoadMatchingDocumentsBtn = `${ValidationMatchingDocumentsPreview} [data-testid="load-sample-document"]`;
export const ValidationLoadSampleDocumentsBtn = `[data-testid="load-sample-documents"]`;
export const ValidationNotMatchingDocumentsPreview =
'[data-testid="validation-content"] [data-testid="notmatching-documents"] [data-testid="document-preview"]';
export const ValidationLoadNotMatchingDocumentsBtn = `${ValidationNotMatchingDocumentsPreview} [data-testid="load-sample-document"]`;
Expand Down
19 changes: 7 additions & 12 deletions packages/compass-e2e-tests/tests/collection-validation-tab.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import * as Selectors from '../helpers/selectors';
import { createNumbersCollection } from '../helpers/insert-data';

const NO_PREVIEW_DOCUMENTS = 'No Preview Documents';
const LOAD_SAMPLE_DOCUMENT = 'Load document';
const PASSING_VALIDATOR = '{ $jsonSchema: {} }';
const FAILING_VALIDATOR =
'{ $jsonSchema: { bsonType: "object", required: [ "phone" ] } }';
Expand Down Expand Up @@ -54,9 +53,11 @@ describe('Collection validation tab', function () {
}

context('when the schema validation is set or modified', function () {
it('provides users with a button to load sample documents', async function () {
it('provides users with a single button to load sample documents', async function () {
await addValidation(PASSING_VALIDATOR);

await browser.clickVisible(Selectors.ValidationLoadSampleDocumentsBtn);

await browser.waitUntil(async () => {
const matchTextElement = browser.$(
Selectors.ValidationMatchingDocumentsPreview
Expand All @@ -67,18 +68,15 @@ describe('Collection validation tab', function () {
);
const notMatchingText = await notMatchingTextElement.getText();
return (
matchText === LOAD_SAMPLE_DOCUMENT &&
notMatchingText === LOAD_SAMPLE_DOCUMENT
matchText.includes('ObjectId(') &&
notMatchingText === NO_PREVIEW_DOCUMENTS
);
});
});

it('supports rules in JSON schema', async function () {
await addValidation(FAILING_VALIDATOR);
await browser.clickVisible(Selectors.ValidationLoadMatchingDocumentsBtn);
await browser.clickVisible(
Selectors.ValidationLoadNotMatchingDocumentsBtn
);
await browser.clickVisible(Selectors.ValidationLoadSampleDocumentsBtn);

// nothing passed, everything failed
await browser.waitUntil(async () => {
Expand All @@ -100,10 +98,7 @@ describe('Collection validation tab', function () {

// the automatic indentation and brackets makes multi-line values very fiddly here
await browser.setValidation(PASSING_VALIDATOR);
await browser.clickVisible(Selectors.ValidationLoadMatchingDocumentsBtn);
await browser.clickVisible(
Selectors.ValidationLoadNotMatchingDocumentsBtn
);
await browser.clickVisible(Selectors.ValidationLoadSampleDocumentsBtn);

// nothing failed, everything passed
await browser.waitUntil(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,14 @@ import { expect } from 'chai';
import { DocumentPreview } from './document-preview';

describe('DocumentPreview [Component]', function () {
context('when document loading state is initial', function () {
it('renders a button to load a sample document', function () {
const component = mount(<DocumentPreview loadingState="initial" />);
expect(component.find('[data-testid="load-sample-document"]')).to.exist;
});
});

context('when document loading state is loading', function () {
it('renders a spinner', function () {
const component = mount(<DocumentPreview loadingState="loading" />);
expect(component.find('[data-testid="load-sample-spinner"]')).to.exist;
});
});

context('when document loading state is success', function () {
it('renders a document if there is one present', function () {
const component = mount(
<DocumentPreview loadingState="success" document={{}} />
);
const component = mount(<DocumentPreview document={{}} />);
expect(component.find('HadronDocument')).to.exist;
});

it('renders a no preview text when there is no document', function () {
const component = mount(<DocumentPreview loadingState="success" />);
expect(component).to.have.text('No Preview Documents');
});
});

context('when document loading state is error', function () {
it('renders a no preview text', function () {
const component = mount(<DocumentPreview loadingState="error" />);
const component = mount(<DocumentPreview />);
expect(component).to.have.text('No Preview Documents');
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
import React from 'react';
import { connect } from 'react-redux';
import {
Body,
KeylineCard,
css,
cx,
spacing,
Button,
} from '@mongodb-js/compass-components';
import { Document } from '@mongodb-js/compass-crud';

import { LoadingOverlay } from './loading-overlay';
import type { DOCUMENT_LOADING_STATES } from '../modules/sample-documents';
import {
fetchValidDocument,
fetchInvalidDocument,
} from '../modules/sample-documents';
import type { RootState } from '../modules';

const previewStyles = css({
display: 'flex',
height: spacing[6] * 3,
Expand All @@ -30,45 +20,20 @@ const noPreviewStyles = css({
alignItems: 'center',
});

const loadSampleStyles = css({
width: '100%',
textAlign: 'center',
});

const noPreviewTextStyles = css({
padding: spacing[3],
textAlign: 'center',
fontStyle: 'italic',
width: '100%',
});

function DocumentPreview({
document,
loadingState,
onLoadSampleClick,
}: {
document?: Record<string, unknown>;
loadingState: DOCUMENT_LOADING_STATES;
onLoadSampleClick?: () => void;
}) {
function DocumentPreview({ document }: { document?: Record<string, unknown> }) {
return (
<KeylineCard
className={cx(previewStyles, document ? undefined : noPreviewStyles)}
data-testid="document-preview"
>
{loadingState === 'initial' ? (
<Body as="div" className={loadSampleStyles}>
<Button
data-testid="load-sample-document"
size="small"
onClick={onLoadSampleClick}
>
Load document
</Button>
</Body>
) : loadingState === 'loading' ? (
<LoadingOverlay />
) : document ? (
{document ? (
<Document doc={document} editable={false} />
) : (
<Body
Expand All @@ -82,24 +47,4 @@ function DocumentPreview({
);
}

const ValidDocumentPreview = connect(
(state: RootState) => ({
document: state.sampleDocuments.validDocument,
loadingState: state.sampleDocuments.validDocumentState,
}),
{
onLoadSampleClick: fetchValidDocument,
}
)(DocumentPreview);

const InvalidDocumentPreview = connect(
(state: RootState) => ({
document: state.sampleDocuments.invalidDocument,
loadingState: state.sampleDocuments.invalidDocumentState,
}),
{
onLoadSampleClick: fetchInvalidDocument,
}
)(DocumentPreview);

export { DocumentPreview, ValidDocumentPreview, InvalidDocumentPreview };
export { DocumentPreview };
Original file line number Diff line number Diff line change
@@ -1,20 +1,46 @@
import React from 'react';
import { mount } from 'enzyme';
import { render, screen } from '@mongodb-js/testing-library-compass';
import { expect } from 'chai';
import { SampleDocuments } from './sample-documents';
import { Provider } from 'react-redux';
import { configureStore } from '../stores/store';
import { INITIAL_STATE } from '../modules';

describe('SampleDocuments [Component]', function () {
it('renders a valid and invalid document preview', function () {
it('initial state : renders the CTA', function () {
const store = configureStore({}, {} as any);
const component = mount(
render(
<Provider store={store}>
<SampleDocuments />
</Provider>
);

expect(component.find('[data-testid="matching-documents"]')).to.exist;
expect(component.find('[data-testid="notmatching-documents"]')).to.exist;
expect(screen.getByRole('button', { name: 'Preview documents' })).to.be
.visible;
});

it('non initial state : renders a valid and invalid document preview', function () {
const store = configureStore(
{
...INITIAL_STATE,
sampleDocuments: {
validDocumentState: 'loading',
invalidDocumentState: 'loading',
validDocument: undefined,
invalidDocument: undefined,
},
},
{} as any
);
render(
<Provider store={store}>
<SampleDocuments />
</Provider>
);

expect(screen.queryByRole('button', { name: 'Preview documents' })).not.to
.exist;
expect(screen.getByTestId('matching-documents')).to.be.visible;
expect(screen.getByTestId('notmatching-documents')).to.be.visible;
});
});
Loading
Loading