Skip to content

enzyme -> RTL: convert the hooks test suites - #475

Merged
cigamit merged 2 commits into
ctrliq:mainfrom
blaipr:feature/rtl-hooks
Jun 18, 2026
Merged

enzyme -> RTL: convert the hooks test suites#475
cigamit merged 2 commits into
ctrliq:mainfrom
blaipr:feature/rtl-hooks

Conversation

@blaipr

@blaipr blaipr commented Jun 16, 2026

Copy link
Copy Markdown
Contributor
SUMMARY

Converts the src/hooks test suites from enzyme to React Testing Library, continuing the enzyme → RTL migration.

Files migrated off enzyme onto RTL: useSelected, useExpanded, useModal, useToast, useRequest (+useDeleteItems), useWsTemplates, useDebounce.

Each hook is exercised via a small harness component that exposes its result through a const ref object / a data-testid JSON node (RTL 12 has no renderHook); state-mutating methods run inside act(), and the websocket hook uses jest-websocket-mock (mirroring the converted useWs* screen hooks). Behaviour and assertions are preserved.

ISSUE TYPE
  • Bug, Docs Fix or other nominal change
COMPONENT NAME
  • UI
ADDITIONAL INFORMATION

npm test for src/hooks: 7 suites, 35 tests, all passing. ESLint clean (--no-ignore).

Note: the result is captured via property mutation on a const object (result.current = useHook(...)) rather than reassigning a let — the latter trips react-hooks/globals (eslint-plugin-react-hooks v7). Also fixed a copy-paste describe('useSelected') label / mismatched test names in useExpanded.test.js. No production code changed — test-only.

Migrate src/hooks tests (useSelected, useExpanded, useModal, useToast,
useRequest, useWsTemplates, useDebounce) off enzyme onto React Testing
Library. Each hook is exercised via a small harness that exposes its
result through a const ref/DOM node (RTL 12 has no renderHook); mutators
run inside act(). Behaviour and assertions are preserved.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues the UI test migration from Enzyme to React Testing Library by converting multiple src/hooks test suites to RTL-style harness components while preserving existing behavior and assertions.

Changes:

  • Migrated several hook test suites (useSelected, useExpanded, useModal, useToast, useRequest/useDeleteItems, useWsTemplates, useDebounce) from Enzyme to RTL.
  • Replaced Enzyme wrapper-based assertions with DOM queries (screen) and ref-based result capture patterns compatible with the repo’s RTL setup.
  • Updated websocket hook tests to assert updates via rendered JSON output and waitFor() rather than Enzyme wrapper.update().

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
awx/ui/src/hooks/useWsTemplates.test.js Migrates websocket hook tests to RTL with a JSON-output harness and waitFor() assertions.
awx/ui/src/hooks/useToast.test.js Converts useToast/Toast tests to RTL using result capture and DOM-based assertions.
awx/ui/src/hooks/useSelected.test.js Rewrites selection hook tests to RTL with a ref-backed harness and act() state updates.
awx/ui/src/hooks/useRequest.test.js Converts request hooks tests to RTL harnesses; needs follow-up fixes to correctly await async updates in act().
awx/ui/src/hooks/useModal.test.js Migrates modal state hook tests to RTL with ref-backed harness and act().
awx/ui/src/hooks/useExpanded.test.js Migrates expanded-state hook tests to RTL with ref-backed harness and updated test naming.
awx/ui/src/hooks/useDebounce.test.js Converts debounce hook test to RTL and wraps timer advancement in act().

Comment on lines 42 to 46
await act(async () => {
wrapper.find('TestInner').invoke('request')();
latest().request();
});
wrapper.update();
expect(wrapper.find('TestInner').prop('result')).toEqual({ data: 'foo' });
expect(latest().result).toEqual({ data: 'foo' });
});
Comment on lines 57 to 66
await act(async () => {
wrapper.find('TestInner').invoke('request')();
latest().request();
});
wrapper.update();
expect(wrapper.find('TestInner').prop('isLoading')).toEqual(true);
expect(latest().isLoading).toEqual(true);
await act(async () => {
resolve({ data: 'foo' });
});
wrapper.update();
expect(wrapper.find('TestInner').prop('isLoading')).toEqual(false);
expect(wrapper.find('TestInner').prop('result')).toEqual({ data: 'foo' });
expect(latest().isLoading).toEqual(false);
expect(latest().result).toEqual({ data: 'foo' });
});
Comment on lines 74 to 78
await act(async () => {
wrapper.find('TestInner').invoke('request')();
latest().request();
});
wrapper.update();
expect(makeRequest).toHaveBeenCalledTimes(1);
});
Comment on lines 109 to +113
await act(async () => {
wrapper.find('TestInner').invoke('request')();
latest().request();
});
wrapper.update();
expect(wrapper.find('TestInner').prop('result')).toEqual({ data: 'foo' });
expect(wrapper.find('TestInner').prop('error')).toEqual(null);
expect(latest().result).toEqual({ data: 'foo' });
expect(latest().error).toEqual(null);
Await the request() promise inside act() so the resulting state updates flush within act (no not-wrapped-in-act warnings); for the isLoading test capture the pending request and await it in the act() that resolves makeRequest.
@blaipr

blaipr commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Pushed a commit: await the request() promise inside act() so the resulting state updates flush within act, and for the isLoading case capture the pending request and await it in the act() that resolves the request.

@cigamit
cigamit merged commit 8989128 into ctrliq:main Jun 18, 2026
@cigamit cigamit self-assigned this Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants