diff --git a/app/src/components/Search.js b/app/src/components/Search.js index 96abca9a..fde58c6f 100644 --- a/app/src/components/Search.js +++ b/app/src/components/Search.js @@ -131,12 +131,14 @@ export const useSearch = (defaultLimit = 48, totalPages = 0, emptySearch = false } export function useSuggestions(searchStr, tagNames, filter, anyTag) { + // The general groups are null until the suggestion request returns: an empty list means the + // server found none, and the dropdown may say "No results" only for that. const defaultSuggestions = { fileGroups: [], - channels: [], - domains: [], - authors: [], - subjects: [], + channels: null, + domains: null, + authors: null, + subjects: null, zimsEstimates: [], } const [suggestions, setSuggestions] = React.useState(defaultSuggestions); @@ -401,8 +403,8 @@ export function useSearchSuggestions(defaultSearchStr, defaultTagNames, anyTag) zims: zimSum, otherSum: otherSum, mapPlaces: newSuggestions.mapPlaces || 0, - channels: newSuggestions.channels.length, - domains: newSuggestions.domains.length, + channels: newSuggestions.channels?.length, + domains: newSuggestions.domains?.length, authors: newSuggestions.authors?.length, subjects: newSuggestions.subjects?.length, tags: matchingTags?.length, diff --git a/app/src/components/SearchSuggestions.test.js b/app/src/components/SearchSuggestions.test.js new file mode 100644 index 00000000..798f459d --- /dev/null +++ b/app/src/components/SearchSuggestions.test.js @@ -0,0 +1,105 @@ +import React from 'react'; +import {act, render, screen} from '../test-utils'; +import {useSearchSuggestions} from './Search'; +import {TagsContext} from '../Tags'; +import {tagsContextFixture} from '../test-fixtures'; +import { + searchEstimateFiles, searchEstimateMap, searchEstimateOthers, searchEstimateZims, searchSuggestions, +} from '../api'; + +// The global search dropdown's groups are built from useSuggestions. A "Channels: No results" row +// may only appear once the suggestion request has come back empty, never before the user has +// typed, and never while the request is pending. + +jest.mock('../api', () => ({ + ...jest.requireActual('../api'), + searchSuggestions: jest.fn(), + searchEstimateFiles: jest.fn(), + searchEstimateMap: jest.fn(), + searchEstimateOthers: jest.fn(), + searchEstimateZims: jest.fn(), +})); + +const DEBOUNCE = 500; +const pending = () => new Promise(() => { +}); + +let hook; + +function Probe() { + hook = useSearchSuggestions('', [], false); + return
{JSON.stringify(hook.suggestionsResults)};
+}
+
+const results = () => JSON.parse(screen.getByTestId('results').textContent);
+
+const renderProbe = () => render(