Restore dedup test and add split-count coverage

Restore the 'does not re-fetch when backend filter params are
unchanged' test from #34324 that was accidentally dropped during
the rebase. Add a new test verifying that cursor navigation does
not re-run the count query (the core split-count behavior).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2026-05-21 18:04:40 +02:00
parent d8757b158c
commit 9772b28bd8
@@ -299,6 +299,46 @@ describe('<EntityListProvider />', () => {
});
});
it('does not re-fetch when backend filter params are unchanged', async () => {
const deferred = createDeferred<GetEntitiesResponse>();
mockCatalogApi.getEntities!.mockReturnValueOnce(deferred);
const { result } = renderHook(() => useEntityList(), {
wrapper: createWrapper({ pagination }),
});
act(() => {
result.current.updateFilters({
kind: new EntityKindFilter('component', 'component'),
});
});
await waitFor(() => {
expect(mockCatalogApi.getEntities).toHaveBeenCalledTimes(1);
});
act(() => {
result.current.updateFilters({
kind: new EntityKindFilter('component', 'Component'),
});
});
act(() => {
result.current.updateFilters({
user: EntityUserFilter.all(),
});
});
await act(async () => {
deferred.resolve({ items: entities });
});
await waitFor(() => {
expect(result.current.backendEntities.length).toBe(2);
});
expect(mockCatalogApi.getEntities).toHaveBeenCalledTimes(1);
});
it('returns an error on catalogApi failure', async () => {
const { result } = renderHook(() => useEntityList(), {
wrapper: createWrapper({ pagination }),
@@ -648,6 +688,47 @@ describe('<EntityListProvider pagination />', () => {
});
});
it('fetches count separately and does not re-count on cursor navigation', async () => {
const { result } = renderHook(() => useEntityList(), {
wrapper: createWrapper({ pagination }),
});
await waitFor(() => {
expect(result.current.backendEntities.length).toBe(2);
});
// The count query uses limit: 0 (without totalItems: 'exclude')
await waitFor(() => {
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith(
expect.objectContaining({ limit: 0 }),
);
});
const countCallsBefore = (
mockCatalogApi.queryEntities as jest.Mock
).mock.calls.filter((c: any) => c[0]?.limit === 0).length;
// Navigate to next page via cursor — should NOT re-run the count
act(() => {
result.current.pageInfo?.next?.();
});
await waitFor(() => {
expect(mockCatalogApi.queryEntities).toHaveBeenCalledWith(
expect.objectContaining({
cursor: expect.any(String),
totalItems: 'exclude',
}),
);
});
const countCallsAfter = (
mockCatalogApi.queryEntities as jest.Mock
).mock.calls.filter((c: any) => c[0]?.limit === 0).length;
expect(countCallsAfter).toBe(countCallsBefore);
});
it('returns an error on catalogApi failure', async () => {
const { result } = renderHook(() => useEntityList(), {
wrapper: createWrapper({ pagination }),