fix(ui) Prevent ever searching past the 10k asset boundary (#14437)

This commit is contained in:
Chris Collins 2025-08-21 12:18:47 -04:00 committed by GitHub
parent 904d4e85eb
commit a79b542d65
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 122 additions and 5 deletions

View File

@ -27,6 +27,7 @@ import useGetSearchQueryInputs from '@app/searchV2/useGetSearchQueryInputs';
import { useIsBrowseV2, useIsSearchV2, useSearchVersion } from '@app/searchV2/useSearchAndBrowseVersion';
import { ENTITY_SUB_TYPE_FILTER_FIELDS, UnionType } from '@app/searchV2/utils/constants';
import { navigateToSearchUrl } from '@app/searchV2/utils/navigateToSearchUrl';
import { getSearchCount } from '@app/searchV2/utils/searchUtils';
import { DownloadSearchResults, DownloadSearchResultsInput } from '@app/searchV2/utils/types';
import { useDownloadScrollAcrossEntitiesSearchResults } from '@app/searchV2/utils/useDownloadScrollAcrossEntitiesSearchResults';
import { scrollToTop } from '@app/shared/searchUtils';
@ -58,6 +59,7 @@ export const SearchPage = () => {
const [numResultsPerPage, setNumResultsPerPage] = useState(SearchCfg.RESULTS_PER_PAGE);
const [isSelectMode, setIsSelectMode] = useState(false);
const [selectedEntities, setSelectedEntities] = useState<EntityAndType[]>([]);
const start = (page - 1) * numResultsPerPage;
const {
data,
@ -69,8 +71,8 @@ export const SearchPage = () => {
input: {
types: [],
query,
start: (page - 1) * numResultsPerPage,
count: numResultsPerPage,
start,
count: getSearchCount(start, numResultsPerPage),
filters: [],
orFilters,
viewUrn,

View File

@ -172,9 +172,8 @@ export const SearchResults = ({
const showSearchFiltersV2 = useIsSearchV2();
const showBrowseV2 = useIsBrowseV2();
const pageStart = searchResponse?.start || 0;
const pageSize = searchResponse?.count || 0;
const totalResults = searchResponse?.total || 0;
const lastResultIndex = pageStart + pageSize > totalResults ? totalResults : pageStart + pageSize;
const lastResultIndex = pageStart + numResultsPerPage > totalResults ? totalResults : pageStart + numResultsPerPage;
const showSeparateSiblings = useIsShowSeparateSiblingsEnabled();
const isShowNavBarRedesign = useShowNavBarRedesign();
const combinedSiblingSearchResults = combineSiblingsInSearchResults(
@ -253,7 +252,7 @@ export const SearchResults = ({
<LeftControlsContainer>
Showing{' '}
<b>
{lastResultIndex > 0 ? (page - 1) * pageSize + 1 : 0} -{' '}
{lastResultIndex > 0 ? (page - 1) * numResultsPerPage + 1 : 0} -{' '}
{lastResultIndex}
</b>{' '}
of{' '}

View File

@ -0,0 +1,106 @@
import { MAX_COUNT_VAL } from '@app/searchV2/utils/constants';
import { getSearchCount } from '@app/searchV2/utils/searchUtils';
describe('getSearchCount', () => {
it('should return numResultsPerPage when start + numResultsPerPage is less than MAX_COUNT_VAL', () => {
const start = 0;
const numResultsPerPage = 20;
const result = getSearchCount(start, numResultsPerPage);
expect(result).toBe(numResultsPerPage);
});
it('should return numResultsPerPage when start + numResultsPerPage equals MAX_COUNT_VAL', () => {
const start = 9980;
const numResultsPerPage = 20;
const result = getSearchCount(start, numResultsPerPage);
expect(result).toBe(numResultsPerPage);
});
it('should return adjusted count when start + numResultsPerPage exceeds MAX_COUNT_VAL', () => {
const start = 9990;
const numResultsPerPage = 20;
const expectedCount = MAX_COUNT_VAL - start; // 10000 - 9990 = 10
const result = getSearchCount(start, numResultsPerPage);
expect(result).toBe(expectedCount);
});
it('should return 0 when start equals MAX_COUNT_VAL', () => {
const start = MAX_COUNT_VAL;
const numResultsPerPage = 20;
const result = getSearchCount(start, numResultsPerPage);
expect(result).toBe(0);
});
it('should handle edge case when start is close to MAX_COUNT_VAL', () => {
const start = 9999;
const numResultsPerPage = 50;
const expectedCount = MAX_COUNT_VAL - start; // 10000 - 9999 = 1
const result = getSearchCount(start, numResultsPerPage);
expect(result).toBe(expectedCount);
});
it('should handle typical pagination scenarios', () => {
// First page
expect(getSearchCount(0, 10)).toBe(10);
// Second page
expect(getSearchCount(10, 10)).toBe(10);
// Page 100
expect(getSearchCount(990, 10)).toBe(10);
// Page 1000 (near the limit)
expect(getSearchCount(9990, 10)).toBe(10);
});
it('should handle large numResultsPerPage values', () => {
const start = 0;
const numResultsPerPage = 1000;
const result = getSearchCount(start, numResultsPerPage);
expect(result).toBe(numResultsPerPage);
});
it('should handle numResultsPerPage of 1', () => {
const start = 9999;
const numResultsPerPage = 1;
const result = getSearchCount(start, numResultsPerPage);
expect(result).toBe(1);
});
it('should handle when start is negative (edge case)', () => {
const start = -5;
const numResultsPerPage = 20;
const result = getSearchCount(start, numResultsPerPage);
// Should still return numResultsPerPage since -5 + 20 = 15 < MAX_COUNT_VAL
expect(result).toBe(numResultsPerPage);
});
it('should use MAX_COUNT_VAL constant correctly', () => {
// Verify our understanding of MAX_COUNT_VAL
expect(MAX_COUNT_VAL).toBe(10000);
// Test right at the boundary
const start = MAX_COUNT_VAL - 1;
const numResultsPerPage = 5;
const result = getSearchCount(start, numResultsPerPage);
expect(result).toBe(1); // MAX_COUNT_VAL - (MAX_COUNT_VAL - 1) = 1
});
});

View File

@ -0,0 +1,10 @@
import { MAX_COUNT_VAL } from '@app/searchV2/utils/constants';
// we can't ask for more than the max (10,000) so calculate count to ask for up to but no more than the max
export function getSearchCount(start: number, numResultsPerPage: number) {
let count = numResultsPerPage;
if (start + numResultsPerPage > MAX_COUNT_VAL) {
count = MAX_COUNT_VAL - start;
}
return count;
}