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
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { ATLAS_SEARCH_TEMPLATES } from '@mongodb-js/mongodb-constants';
import {
ATLAS_SEARCH_TEMPLATES,
ATLAS_VECTOR_SEARCH_TEMPLATE,
} from '@mongodb-js/mongodb-constants';
import { expect } from 'chai';
import { BaseSearchIndexModal } from './base-search-index-modal';
import sinon from 'sinon';
Expand All @@ -7,7 +10,10 @@ import { render, screen, cleanup, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import React from 'react';
import { getCodemirrorEditorValue } from '@mongodb-js/compass-editor';
import {
getCodemirrorEditorValue,
setCodemirrorEditorValue,
} from '@mongodb-js/compass-editor';

function normalizedTemplateNamed(name: string) {
const snippet =
Expand All @@ -19,6 +25,20 @@ function normalizedTemplateNamed(name: string) {
return snippet.replace(/\${\d+:([^}]+)}/gm, '$1');
}

const VALID_ATLAS_SEARCH_INDEX_DEFINITION = {
fields: [
{
type: 'vector',
path: 'pineapple',
numDimensions: 1000,
similarity: 'cosine',
},
],
};
const VALID_ATLAS_SEARCH_INDEX_DEFINITION_STRING = JSON.stringify(
VALID_ATLAS_SEARCH_INDEX_DEFINITION
);

function renderBaseSearchIndexModal(
props?: Partial<React.ComponentProps<typeof BaseSearchIndexModal>>
) {
Expand Down Expand Up @@ -113,7 +133,7 @@ describe('Base Search Index Modal', function () {
});
});

it('submits the modal with the correct type on create search index', function () {
it('submits the modal with the correct type on create search index', async function () {
userEvent.click(
screen.getByTestId('search-index-type-vectorSearch-button'),
undefined,
Expand All @@ -122,15 +142,73 @@ describe('Base Search Index Modal', function () {
skipPointerEventsCheck: true,
}
);
await waitFor(() => {
const indexDef = getCodemirrorEditorValue(
'definition-of-search-index'
);
expect(indexDef).to.equal(ATLAS_VECTOR_SEARCH_TEMPLATE.snippet);
});

// Set the value to something where the create index button is enabled.
await setCodemirrorEditorValue(
'definition-of-search-index',
VALID_ATLAS_SEARCH_INDEX_DEFINITION_STRING
);
userEvent.click(
screen.getByRole('button', { name: 'Create Search Index' })
);
expect(onSubmitSpy).to.have.been.calledOnceWithExactly({
name: 'default',
definition: {},
definition: VALID_ATLAS_SEARCH_INDEX_DEFINITION,
type: 'vectorSearch',
});
});

it('resets the template on type switch', async function () {
userEvent.click(
screen.getByTestId('search-index-type-vectorSearch-button'),
undefined,
{
// leafygreen adds pointer-events: none on actually clickable elements
skipPointerEventsCheck: true,
}
);

await waitFor(() => {
const indexDef = getCodemirrorEditorValue(
'definition-of-search-index'
);
expect(indexDef).to.equal(ATLAS_VECTOR_SEARCH_TEMPLATE.snippet);
});

userEvent.click(
screen.getByTestId('search-index-type-search-button'),
undefined,
{
// leafygreen adds pointer-events: none on actually clickable elements
skipPointerEventsCheck: true,
}
);

await waitFor(() => {
const indexDef = getCodemirrorEditorValue(
'definition-of-search-index'
);
expect(indexDef).to.equal(
normalizedTemplateNamed('Dynamic field mappings')
);
});
// Ensure the state is updated when the ace snippet changes.
await new Promise((resolve) => setTimeout(resolve, 10));
userEvent.click(
screen.getByRole('button', { name: 'Create Search Index' })
);
expect(onSubmitSpy).to.have.been.calledOnceWithExactly({
name: 'default',
definition: { mappings: { dynamic: true } },
type: 'search',
});
});
});

describe('templates', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import type { Document } from 'mongodb';
import { useTrackOnChange } from '@mongodb-js/compass-logging/provider';
import { SearchIndexTemplateDropdown } from '../search-index-template-dropdown';
import {
ATLAS_SEARCH_TEMPLATES,
ATLAS_VECTOR_SEARCH_TEMPLATE,
type SearchTemplate,
} from '@mongodb-js/mongodb-constants';
Expand Down Expand Up @@ -201,6 +202,7 @@ export const BaseSearchIndexModal: React.FunctionComponent<

useEffect(() => {
if (isModalOpen) {
setSearchIndexType('search');
setIndexName(initialIndexName);
setIndexDefinition(initialIndexDefinition);
setParsingError(undefined);
Expand Down Expand Up @@ -261,12 +263,14 @@ export const BaseSearchIndexModal: React.FunctionComponent<

// Set the template.
if (value === 'vectorSearch') {
setIndexDefinition(ATLAS_VECTOR_SEARCH_TEMPLATE.snippet);
onChangeTemplate(ATLAS_VECTOR_SEARCH_TEMPLATE);
} else {
onSearchIndexDefinitionChanged(DEFAULT_INDEX_DEFINITION);
setIndexDefinition(ATLAS_SEARCH_TEMPLATES[0].snippet);
onChangeTemplate(ATLAS_SEARCH_TEMPLATES[0]);
}
},
[setSearchIndexType, onChangeTemplate, onSearchIndexDefinitionChanged]
[setSearchIndexType, onChangeTemplate, setIndexDefinition]
);

const fields = useAutocompleteFields(namespace);
Expand Down Expand Up @@ -421,7 +425,7 @@ export const BaseSearchIndexModal: React.FunctionComponent<
data-testid="search-index-submit-button"
variant="primary"
onClick={onSubmitIndex}
disabled={isBusy}
disabled={isBusy || !!parsingError}
>
{mode === 'create' ? 'Create Search Index' : 'Save'}
</Button>
Expand Down