Skip to content

Commit

Permalink
[8.x] [React18] Migrate test suites to account for testing library up…
Browse files Browse the repository at this point in the history
…grades obs-ux-logs-team (#201148) (#201546)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[React18] Migrate test suites to account for testing library upgrades
obs-ux-logs-team
(#201148)](#201148)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Eyo O.
Eyo","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-11-25T10:49:51Z","message":"[React18]
Migrate test suites to account for testing library upgrades
obs-ux-logs-team (#201148)\n\nThis PR migrates test suites that use
`renderHook` from the library\r\n`@testing-library/react-hooks` to adopt
the equivalent and replacement\r\nof `renderHook` from the export that
is now available from\r\n`@testing-library/react`. This work is required
for the planned\r\nmigration to react18.\r\n\r\n## Context\r\n\r\nIn
this PR, usages of `waitForNextUpdate` that previously could
have\r\nbeen destructured from `renderHook` are now been replaced with
`waitFor`\r\nexported from `@testing-library/react`, furthermore
`waitFor`\r\nthat would also have been destructured from the same
renderHook result\r\nis now been replaced with `waitFor` from the export
of\r\n`@testing-library/react`.\r\n\r\n***Why is `waitFor` a sufficient
enough replacement for\r\n`waitForNextUpdate`, and better for testing
values subject to async\r\ncomputations?***\r\n\r\nWaitFor will retry
the provided callback if an error is returned, till\r\nthe configured
timeout elapses. By default the retry interval is `50ms`\r\nwith a
timeout value of `1000ms` that\r\neffectively translates to at least 20
retries for assertions placed\r\nwithin waitFor.
See\r\nhttps://testing-library.com/docs/dom-testing-library/api-async/#waitfor\r\nfor
more information.\r\nThis however means that for person's writing tests,
said person has to\r\nbe explicit about expectations that describe the
internal state of the\r\nhook being tested.\r\nThis implies checking for
instance when a react query hook is being\r\nrendered, there's an
assertion that said hook isn't loading anymore.\r\n\r\nIn this PR you'd
notice that this pattern has been adopted, with most\r\nexisting
assertions following an invocation of `waitForNextUpdate`
being\r\nplaced within a `waitFor`\r\ninvocation. In some cases the
replacement is simply a `waitFor(() => new\r\nPromise((resolve) =>
resolve(null)))` (many thanks to @kapral18, for\r\npoint out exactly why
this works),\r\nwhere this suffices the assertions that follow aren't
placed within a\r\nwaitFor so this PR doesn't get larger than it needs
to be.\r\n\r\nIt's also worth pointing out this PR might also contain
changes to test\r\nand application code to improve said existing
test.\r\n\r\n### What to do next?\r\n1. Review the changes in this
PR.\r\n2. If you think the changes are correct, approve the
PR.\r\n\r\n## Any questions?\r\nIf you have any questions or need help
with this PR, please leave\r\ncomments in this
PR.\r\n\r\nCo-authored-by: Elastic Machine
<[email protected]>","sha":"1f0f8d2c529e7b4ed9803b51bcb58e3809c418dc","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:prev-minor","ci:project-deploy-observability","Team:obs-ux-logs","React@18"],"title":"[React18]
Migrate test suites to account for testing library upgrades
obs-ux-logs-team","number":201148,"url":"https://github.com/elastic/kibana/pull/201148","mergeCommit":{"message":"[React18]
Migrate test suites to account for testing library upgrades
obs-ux-logs-team (#201148)\n\nThis PR migrates test suites that use
`renderHook` from the library\r\n`@testing-library/react-hooks` to adopt
the equivalent and replacement\r\nof `renderHook` from the export that
is now available from\r\n`@testing-library/react`. This work is required
for the planned\r\nmigration to react18.\r\n\r\n## Context\r\n\r\nIn
this PR, usages of `waitForNextUpdate` that previously could
have\r\nbeen destructured from `renderHook` are now been replaced with
`waitFor`\r\nexported from `@testing-library/react`, furthermore
`waitFor`\r\nthat would also have been destructured from the same
renderHook result\r\nis now been replaced with `waitFor` from the export
of\r\n`@testing-library/react`.\r\n\r\n***Why is `waitFor` a sufficient
enough replacement for\r\n`waitForNextUpdate`, and better for testing
values subject to async\r\ncomputations?***\r\n\r\nWaitFor will retry
the provided callback if an error is returned, till\r\nthe configured
timeout elapses. By default the retry interval is `50ms`\r\nwith a
timeout value of `1000ms` that\r\neffectively translates to at least 20
retries for assertions placed\r\nwithin waitFor.
See\r\nhttps://testing-library.com/docs/dom-testing-library/api-async/#waitfor\r\nfor
more information.\r\nThis however means that for person's writing tests,
said person has to\r\nbe explicit about expectations that describe the
internal state of the\r\nhook being tested.\r\nThis implies checking for
instance when a react query hook is being\r\nrendered, there's an
assertion that said hook isn't loading anymore.\r\n\r\nIn this PR you'd
notice that this pattern has been adopted, with most\r\nexisting
assertions following an invocation of `waitForNextUpdate`
being\r\nplaced within a `waitFor`\r\ninvocation. In some cases the
replacement is simply a `waitFor(() => new\r\nPromise((resolve) =>
resolve(null)))` (many thanks to @kapral18, for\r\npoint out exactly why
this works),\r\nwhere this suffices the assertions that follow aren't
placed within a\r\nwaitFor so this PR doesn't get larger than it needs
to be.\r\n\r\nIt's also worth pointing out this PR might also contain
changes to test\r\nand application code to improve said existing
test.\r\n\r\n### What to do next?\r\n1. Review the changes in this
PR.\r\n2. If you think the changes are correct, approve the
PR.\r\n\r\n## Any questions?\r\nIf you have any questions or need help
with this PR, please leave\r\ncomments in this
PR.\r\n\r\nCo-authored-by: Elastic Machine
<[email protected]>","sha":"1f0f8d2c529e7b4ed9803b51bcb58e3809c418dc"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/201148","number":201148,"mergeCommit":{"message":"[React18]
Migrate test suites to account for testing library upgrades
obs-ux-logs-team (#201148)\n\nThis PR migrates test suites that use
`renderHook` from the library\r\n`@testing-library/react-hooks` to adopt
the equivalent and replacement\r\nof `renderHook` from the export that
is now available from\r\n`@testing-library/react`. This work is required
for the planned\r\nmigration to react18.\r\n\r\n## Context\r\n\r\nIn
this PR, usages of `waitForNextUpdate` that previously could
have\r\nbeen destructured from `renderHook` are now been replaced with
`waitFor`\r\nexported from `@testing-library/react`, furthermore
`waitFor`\r\nthat would also have been destructured from the same
renderHook result\r\nis now been replaced with `waitFor` from the export
of\r\n`@testing-library/react`.\r\n\r\n***Why is `waitFor` a sufficient
enough replacement for\r\n`waitForNextUpdate`, and better for testing
values subject to async\r\ncomputations?***\r\n\r\nWaitFor will retry
the provided callback if an error is returned, till\r\nthe configured
timeout elapses. By default the retry interval is `50ms`\r\nwith a
timeout value of `1000ms` that\r\neffectively translates to at least 20
retries for assertions placed\r\nwithin waitFor.
See\r\nhttps://testing-library.com/docs/dom-testing-library/api-async/#waitfor\r\nfor
more information.\r\nThis however means that for person's writing tests,
said person has to\r\nbe explicit about expectations that describe the
internal state of the\r\nhook being tested.\r\nThis implies checking for
instance when a react query hook is being\r\nrendered, there's an
assertion that said hook isn't loading anymore.\r\n\r\nIn this PR you'd
notice that this pattern has been adopted, with most\r\nexisting
assertions following an invocation of `waitForNextUpdate`
being\r\nplaced within a `waitFor`\r\ninvocation. In some cases the
replacement is simply a `waitFor(() => new\r\nPromise((resolve) =>
resolve(null)))` (many thanks to @kapral18, for\r\npoint out exactly why
this works),\r\nwhere this suffices the assertions that follow aren't
placed within a\r\nwaitFor so this PR doesn't get larger than it needs
to be.\r\n\r\nIt's also worth pointing out this PR might also contain
changes to test\r\nand application code to improve said existing
test.\r\n\r\n### What to do next?\r\n1. Review the changes in this
PR.\r\n2. If you think the changes are correct, approve the
PR.\r\n\r\n## Any questions?\r\nIf you have any questions or need help
with this PR, please leave\r\ncomments in this
PR.\r\n\r\nCo-authored-by: Elastic Machine
<[email protected]>","sha":"1f0f8d2c529e7b4ed9803b51bcb58e3809c418dc"}}]}]
BACKPORT-->

Co-authored-by: Eyo O. Eyo <[email protected]>
  • Loading branch information
kibanamachine and eokoneyo authored Nov 25, 2024
1 parent 2285476 commit 920e993
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { act, cleanup, renderHook } from '@testing-library/react-hooks';
import { renderHook, act, cleanup } from '@testing-library/react';

import { useBoolean } from './use_boolean';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { renderHook } from '@testing-library/react-hooks';
import { waitFor, renderHook } from '@testing-library/react';

import { createUseFieldsMetadataHook, UseFieldsMetadataParams } from './use_fields_metadata';
import { FindFieldsMetadataResponsePayload } from '../../../common/latest';
Expand Down Expand Up @@ -46,12 +46,12 @@ describe('useFieldsMetadata', () => {

it('should return the fieldsMetadata value from the API', async () => {
fieldsMetadataClient.find.mockResolvedValue(mockedFieldsMetadataResponse);
const { result, waitForNextUpdate } = renderHook(() => useFieldsMetadata());
const { result } = renderHook(() => useFieldsMetadata());

expect(result.current.loading).toBe(true);
expect(result.current.fieldsMetadata).toEqual(undefined);

await waitForNextUpdate();
await waitFor(() => new Promise((resolve) => resolve(null)));

const { fieldsMetadata, loading, error } = result.current;
expect(fieldsMetadata).toEqual(fields);
Expand All @@ -68,21 +68,17 @@ describe('useFieldsMetadata', () => {
dataset: 'dataset_name',
};

const { waitForNextUpdate } = renderHook(() => useFieldsMetadata(params));
renderHook(() => useFieldsMetadata(params));

await waitForNextUpdate();

expect(fieldsMetadataClient.find).toHaveBeenCalledWith(params);
await waitFor(() => expect(fieldsMetadataClient.find).toHaveBeenCalledWith(params));
});

it('should return an error if the API call fails', async () => {
const error = new Error('Fetch fields metadata Failed');
fieldsMetadataClient.find.mockRejectedValueOnce(error);

const { result, waitForNextUpdate } = renderHook(() => useFieldsMetadata());

await waitForNextUpdate();
const { result } = renderHook(() => useFieldsMetadata());

expect(result.current.error?.message).toMatch(error.message);
await waitFor(() => expect(result.current.error?.message).toMatch(error.message));
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { renderHook } from '@testing-library/react-hooks';
import { waitFor, renderHook } from '@testing-library/react';
// We are using this inside a `jest.mock` call. Jest requires dynamic dependencies to be prefixed with `mock`
import { coreMock as mockCoreMock } from '@kbn/core/public/mocks';

Expand Down Expand Up @@ -56,14 +56,14 @@ describe('useLogSummary hook', () => {
.mockResolvedValueOnce(firstMockResponse)
.mockResolvedValueOnce(secondMockResponse);

const { result, waitForNextUpdate, rerender } = renderHook(
const { result, rerender } = renderHook(
({ logViewReference }) => useLogSummary(logViewReference, startTimestamp, endTimestamp, null),
{
initialProps: { logViewReference: LOG_VIEW_REFERENCE },
}
);

await waitForNextUpdate();
await waitFor(() => new Promise((resolve) => resolve(null)));

expect(fetchLogSummaryMock).toHaveBeenCalledTimes(1);
expect(fetchLogSummaryMock).toHaveBeenLastCalledWith(
Expand All @@ -75,7 +75,7 @@ describe('useLogSummary hook', () => {
expect(result.current.buckets).toEqual(firstMockResponse.data.buckets);

rerender({ logViewReference: CHANGED_LOG_VIEW_REFERENCE });
await waitForNextUpdate();
await waitFor(() => new Promise((resolve) => resolve(null)));

expect(fetchLogSummaryMock).toHaveBeenCalledTimes(2);
expect(fetchLogSummaryMock).toHaveBeenLastCalledWith(
Expand All @@ -101,15 +101,15 @@ describe('useLogSummary hook', () => {
.mockResolvedValueOnce(firstMockResponse)
.mockResolvedValueOnce(secondMockResponse);

const { result, waitForNextUpdate, rerender } = renderHook(
const { result, rerender } = renderHook(
({ filterQuery }) =>
useLogSummary(LOG_VIEW_REFERENCE, startTimestamp, endTimestamp, filterQuery),
{
initialProps: { filterQuery: 'INITIAL_FILTER_QUERY' },
}
);

await waitForNextUpdate();
await waitFor(() => new Promise((resolve) => resolve(null)));

expect(fetchLogSummaryMock).toHaveBeenCalledTimes(1);
expect(fetchLogSummaryMock).toHaveBeenLastCalledWith(
Expand All @@ -121,7 +121,7 @@ describe('useLogSummary hook', () => {
expect(result.current.buckets).toEqual(firstMockResponse.data.buckets);

rerender({ filterQuery: 'CHANGED_FILTER_QUERY' });
await waitForNextUpdate();
await waitFor(() => new Promise((resolve) => resolve(null)));

expect(fetchLogSummaryMock).toHaveBeenCalledTimes(2);
expect(fetchLogSummaryMock).toHaveBeenLastCalledWith(
Expand All @@ -139,15 +139,15 @@ describe('useLogSummary hook', () => {
.mockResolvedValueOnce(createMockResponse([]));

const firstRange = createMockDateRange();
const { waitForNextUpdate, rerender } = renderHook(
const { rerender } = renderHook(
({ startTimestamp, endTimestamp }) =>
useLogSummary(LOG_VIEW_REFERENCE, startTimestamp, endTimestamp, null),
{
initialProps: firstRange,
}
);

await waitForNextUpdate();
await waitFor(() => new Promise((resolve) => resolve(null)));
expect(fetchLogSummaryMock).toHaveBeenCalledTimes(1);
expect(fetchLogSummaryMock).toHaveBeenLastCalledWith(
expect.objectContaining({
Expand All @@ -160,7 +160,7 @@ describe('useLogSummary hook', () => {
const secondRange = createMockDateRange('now-20s', 'now');

rerender(secondRange);
await waitForNextUpdate();
await waitFor(() => new Promise((resolve) => resolve(null)));

expect(fetchLogSummaryMock).toHaveBeenCalledTimes(2);
expect(fetchLogSummaryMock).toHaveBeenLastCalledWith(
Expand All @@ -176,7 +176,7 @@ describe('useLogSummary hook', () => {
fetchLogSummaryMock.mockResolvedValueOnce(createMockResponse([]));

const firstRange = createMockDateRange();
const { waitForNextUpdate, rerender } = renderHook(
const { rerender } = renderHook(
({ startTimestamp, endTimestamp }) =>
useLogSummary(LOG_VIEW_REFERENCE, startTimestamp, endTimestamp, null),
{
Expand All @@ -188,7 +188,7 @@ describe('useLogSummary hook', () => {

// intentionally don't wait for an update to test the throttling
rerender(secondRange);
await waitForNextUpdate();
await waitFor(() => new Promise((resolve) => resolve(null)));

expect(fetchLogSummaryMock).toHaveBeenCalledTimes(1);
expect(fetchLogSummaryMock).toHaveBeenLastCalledWith(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { act, renderHook } from '@testing-library/react-hooks';
import { renderHook, act } from '@testing-library/react';
import React from 'react';
import { firstValueFrom, Observable, of, Subject } from 'rxjs';
import type { ISearchGeneric, IKibanaSearchResponse } from '@kbn/search-types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { act, renderHook } from '@testing-library/react-hooks';
import { renderHook, act } from '@testing-library/react';
import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
import { IKibanaSearchRequest } from '@kbn/search-types';
import { ParsedDataSearchRequestDescriptor, ParsedKibanaSearchResponse } from './types';
Expand Down

0 comments on commit 920e993

Please sign in to comment.