Skip to content

Commit

Permalink
test: add empty result test
Browse files Browse the repository at this point in the history
  • Loading branch information
rpenido committed Apr 16, 2024
1 parent 68da2b9 commit 879a395
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/search-modal/SearchUI.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import fetchMock from 'fetch-mock-jest';
import initializeStore from '../store';
// @ts-ignore
import mockResult from './__mocks__/search-result.json';
// @ts-ignore
import mockEmptyResult from './__mocks__/empty-search-result.json';
import SearchUI from './SearchUI';

// mockResult contains only a single result - this one:
Expand Down Expand Up @@ -44,6 +46,19 @@ const Wrap = ({ children }) => (
</AppProvider>
);

const returnEmptyResult = (_url, req) => {
const requestData = JSON.parse(req.body?.toString() ?? '');
const query = requestData?.queries[0]?.q ?? '';
// We have to replace the query (search keywords) in the mock results with the actual query,
// because otherwise Instantsearch will update the UI and change the query,
// leading to unexpected results in the test cases.
mockEmptyResult.results[0].query = query;
// And create the required '_formatted' field; not sure why it's there - seems very redundant. But it's required.
// eslint-disable-next-line no-underscore-dangle, no-param-reassign
mockEmptyResult.results[0]?.hits.forEach((hit) => { hit._formatted = { ...hit }; });
return mockEmptyResult;
};

describe('<SearchUI />', () => {
beforeEach(async () => {
initializeMockApp({
Expand Down Expand Up @@ -83,6 +98,23 @@ describe('<SearchUI />', () => {
expect(getByText('Start searching to find content')).toBeInTheDocument();
});

it('should render an empty state if no result found', async () => {
fetchMock.post(searchEndpoint, returnEmptyResult, { overwriteRoutes: true });
const { getByText, getByRole } = render(<Wrap><SearchUI {...defaults} /></Wrap>);
// Return an empty result set:
// Before the results have even loaded, we see this message:
expect(getByText('Start searching to find content')).toBeInTheDocument();
// When this UI loads, Instantsearch makes two queries. I think one to load the facets and one "blank" search.
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(2, searchEndpoint, 'post'); });
// And that message is still displayed even after the initial results/filters have loaded:
expect(getByText('Start searching to find content')).toBeInTheDocument();
// Enter a keyword - search for 'noresults':
fireEvent.change(getByRole('searchbox'), { target: { value: 'noresults' } });
// Wait for the new search request to load all the results:
await waitFor(() => { expect(fetchMock).toHaveFetchedTimes(3, searchEndpoint, 'post'); });
expect(getByText('We didn\'t find anything matching your search')).toBeInTheDocument();
});

it('defaults to searching "All Courses" if used outside of any particular course', async () => {
const { getByText, queryByText, getByRole } = render(<Wrap><SearchUI {...defaults} courseId="" /></Wrap>);
// We default to searching all courses:
Expand Down
19 changes: 19 additions & 0 deletions src/search-modal/__mocks__/empty-search-result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"comment": "This is a mock of the empty response from Meilisearch, based on an actual search in Studio.",
"results": [
{
"indexUid": "tutor_studio_content",
"hits": [],
"query": "noresult",
"processingTimeMs": 0,
"limit": 21,
"offset": 0,
"estimatedTotalHits": 0,
"facetDistribution": {
"block_type": {},
"tags.taxonomy": {}
},
"facetStats": {}
}
]
}

0 comments on commit 879a395

Please sign in to comment.