diff --git a/.changeset/cold-coins-listen.md b/.changeset/cold-coins-listen.md new file mode 100644 index 0000000000..322d8366b6 --- /dev/null +++ b/.changeset/cold-coins-listen.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Fixes errant `act` output from unit tests diff --git a/packages/clerk-js/src/core/clerk.test.ts b/packages/clerk-js/src/core/clerk.test.ts index 7bf3a01634..0bd743f51d 100644 --- a/packages/clerk-js/src/core/clerk.test.ts +++ b/packages/clerk-js/src/core/clerk.test.ts @@ -519,7 +519,7 @@ describe('Clerk singleton', () => { let logSpy; beforeEach(() => { - logSpy = jest.spyOn(console, 'log'); + logSpy = jest.spyOn(console, 'log').mockReturnValue(void 0); sut = new Clerk(productionPublishableKey); }); diff --git a/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/InviteMembersPage.test.tsx b/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/InviteMembersPage.test.tsx index 9a1b97ce9e..b47c065b8d 100644 --- a/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/InviteMembersPage.test.tsx +++ b/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/InviteMembersPage.test.tsx @@ -1,7 +1,6 @@ import type { MembershipRole, OrganizationInvitationResource } from '@clerk/types'; import { describe } from '@jest/globals'; import { waitFor } from '@testing-library/dom'; -import { act } from '@testing-library/react'; import React from 'react'; import { ClerkAPIResponseError } from '../../../../core/resources'; @@ -15,12 +14,16 @@ describe('InviteMembersPage', () => { it('renders the component', async () => { const { wrapper, fixtures } = await createFixtures(f => { f.withOrganizations(); - f.withUser({ email_addresses: ['test@clerk.com'], organization_memberships: [{ name: 'Org1', role: 'admin' }] }); + f.withUser({ + email_addresses: ['test@clerk.com'], + organization_memberships: [{ name: 'Org1', role: 'admin' }], + }); }); fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { getByText } = await act(() => render(, { wrapper })); - expect(getByText('Invite new members to this organization')).toBeDefined(); + + const { findByText } = render(, { wrapper }); + await waitFor(async () => expect(await findByText('Invite new members to this organization')).toBeInTheDocument()); }); describe('Submitting', () => { @@ -42,6 +45,7 @@ describe('InviteMembersPage', () => { await userEvent.click(getByRole('button', { name: /select an option/i })); await userEvent.click(getByText(/^member$/i)); + expect(getByRole('button', { name: 'Send invitations' })).not.toBeDisabled(); }); @@ -61,9 +65,12 @@ describe('InviteMembersPage', () => { await userEvent.click(getByRole('button', { name: 'Select an option' })); await userEvent.click(getByText('Member')); await userEvent.click(getByRole('button', { name: 'Send invitations' })); - expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ - emailAddresses: ['test+1@clerk.com'], - role: 'basic_member' as MembershipRole, + + await waitFor(() => { + expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ + emailAddresses: ['test+1@clerk.com'], + role: 'basic_member' as MembershipRole, + }); }); }); @@ -98,9 +105,12 @@ describe('InviteMembersPage', () => { await userEvent.click(getByRole('button', { name: 'Select an option' })); await userEvent.click(getByText('Teacher')); await userEvent.click(getByRole('button', { name: 'Send invitations' })); - expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ - emailAddresses: ['test+1@clerk.com'], - role: 'org:teacher' as MembershipRole, + + await waitFor(() => { + expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ + emailAddresses: ['test+1@clerk.com'], + role: 'org:teacher' as MembershipRole, + }); }); }); @@ -123,9 +133,12 @@ describe('InviteMembersPage', () => { await userEvent.click(getByRole('button', { name: 'Select an option' })); await userEvent.click(getByText('Member')); await userEvent.click(getByRole('button', { name: 'Send invitations' })); - expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ - emailAddresses: ['test+1@clerk.com', 'test+2@clerk.com', 'test+3@clerk.com', 'test+4@clerk.com'], - role: 'basic_member' as MembershipRole, + + await waitFor(() => { + expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ + emailAddresses: ['test+1@clerk.com', 'test+2@clerk.com', 'test+3@clerk.com', 'test+4@clerk.com'], + role: 'basic_member' as MembershipRole, + }); }); }); @@ -145,9 +158,11 @@ describe('InviteMembersPage', () => { await userEvent.click(getByRole('button', { name: 'Select an option' })); await userEvent.click(getByText('Admin')); await userEvent.click(getByRole('button', { name: 'Send invitations' })); - expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ - emailAddresses: ['test+1@clerk.com'], - role: 'admin' as MembershipRole, + await waitFor(() => { + expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ + emailAddresses: ['test+1@clerk.com'], + role: 'admin' as MembershipRole, + }); }); }); diff --git a/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/OrganizationMembers.test.tsx b/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/OrganizationMembers.test.tsx index 4017c0c4b3..556f744704 100644 --- a/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/OrganizationMembers.test.tsx +++ b/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/OrganizationMembers.test.tsx @@ -1,35 +1,37 @@ import type { OrganizationInvitationResource, OrganizationMembershipResource } from '@clerk/types'; import { describe } from '@jest/globals'; -import { act, waitFor } from '@testing-library/react'; +import { waitFor, waitForElementToBeRemoved } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { render } from '../../../../testUtils'; import { bindCreateFixtures } from '../../../utils/test/createFixtures'; -import { runFakeTimers } from '../../../utils/test/runFakeTimers'; import { OrganizationMembers } from '../OrganizationMembers'; import { createFakeMember, createFakeOrganizationInvitation, createFakeOrganizationMembershipRequest } from './utils'; const { createFixtures } = bindCreateFixtures('OrganizationProfile'); +async function waitForLoadingCompleted(container: HTMLElement) { + return waitForElementToBeRemoved(() => container.querySelector('span[aria-busy="true"]')); +} + describe('OrganizationMembers', () => { it('renders the Organization Members page', async () => { const { wrapper, fixtures } = await createFixtures(f => { f.withOrganizations(); f.withUser({ email_addresses: ['test@clerk.com'], organization_memberships: ['Org1'] }); }); + fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { getByText, getByRole } = render(, { wrapper }); + const { container, getByText, getByRole } = render(, { wrapper }); - await waitFor(() => { - expect(getByRole('heading', { name: /members/i })).toBeInTheDocument(); - expect(getByText('View and manage organization members')).toBeInTheDocument(); - }); + await waitForLoadingCompleted(container); - await waitFor(() => { - // Tabs - expect(getByRole('tab', { name: 'Members' })).toBeInTheDocument(); - expect(getByRole('tab', { name: 'Invitations' })).toBeInTheDocument(); - }); + expect(getByRole('heading', { name: /members/i })).toBeInTheDocument(); + expect(getByText('View and manage organization members')).toBeInTheDocument(); + + // Tabs + expect(getByRole('tab', { name: 'Members' })).toBeInTheDocument(); + expect(getByRole('tab', { name: 'Invitations' })).toBeInTheDocument(); }); it('shows requests if domains is turned on', async () => { @@ -41,11 +43,11 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { getByRole } = render(, { wrapper }); + const { getByRole, container } = render(, { wrapper }); - await waitFor(() => { - expect(getByRole('tab', { name: 'Requests' })).toBeInTheDocument(); - }); + await waitForLoadingCompleted(container); + + expect(getByRole('tab', { name: 'Requests' })).toBeInTheDocument(); }); it('shows an invite button inside invitations tab if the current user is an admin', async () => { @@ -56,13 +58,11 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { getByRole, getByText } = render(, { wrapper }); + const { getByRole, findByText } = render(, { wrapper }); - await waitFor(async () => { - await userEvent.click(getByRole('tab', { name: 'Invitations' })); - expect(getByText('Invited')).toBeDefined(); - expect(getByRole('button', { name: 'Invite' })).toBeDefined(); - }); + await userEvent.click(getByRole('tab', { name: 'Invitations' })); + expect(await findByText('Invited')).toBeInTheDocument(); + expect(getByRole('button', { name: 'Invite' })).toBeInTheDocument(); }); it('does not show invitations and requests if user is not an admin', async () => { @@ -76,13 +76,13 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { queryByRole } = render(, { wrapper }); + const { container, queryByRole } = render(, { wrapper }); - await waitFor(() => { - expect(queryByRole('tab', { name: 'Members' })).toBeInTheDocument(); - expect(queryByRole('tab', { name: 'Invitations' })).not.toBeInTheDocument(); - expect(queryByRole('tab', { name: 'Requests' })).not.toBeInTheDocument(); - }); + await waitForLoadingCompleted(container); + + expect(queryByRole('tab', { name: 'Members' })).toBeInTheDocument(); + expect(queryByRole('tab', { name: 'Invitations' })).not.toBeInTheDocument(); + expect(queryByRole('tab', { name: 'Requests' })).not.toBeInTheDocument(); }); it('does not show members tab or navbar route if user is lacking permissions', async () => { @@ -98,11 +98,9 @@ describe('OrganizationMembers', () => { const { queryByRole } = render(, { wrapper }); - await waitFor(() => { - expect(queryByRole('tab', { name: 'Members' })).not.toBeInTheDocument(); - expect(queryByRole('tab', { name: 'Invitations' })).not.toBeInTheDocument(); - expect(queryByRole('tab', { name: 'Requests' })).not.toBeInTheDocument(); - }); + expect(queryByRole('tab', { name: 'Members' })).not.toBeInTheDocument(); + expect(queryByRole('tab', { name: 'Invitations' })).not.toBeInTheDocument(); + expect(queryByRole('tab', { name: 'Requests' })).not.toBeInTheDocument(); }); it('navigates to invite screen when user clicks on Invite button', async () => { @@ -113,13 +111,14 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { getByRole } = render(, { wrapper }); + const { container, getByRole } = render(, { wrapper }); - await waitFor(async () => { - await userEvent.click(getByRole('tab', { name: 'Invitations' })); - await userEvent.click(getByRole('button', { name: 'Invite' })); - expect(fixtures.router.navigate).toHaveBeenCalledWith('invite-members'); - }); + await waitForLoadingCompleted(container); + + await userEvent.click(getByRole('tab', { name: 'Invitations' })); + await userEvent.click(getByRole('button', { name: 'Invite' })); + + expect(fixtures.router.navigate).toHaveBeenCalledWith('invite-members'); }); it('lists all the members of the Organization', async () => { @@ -176,20 +175,23 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { queryByText, queryAllByRole } = render(, { wrapper }); + const { container, queryByText, queryAllByRole } = render(, { wrapper }); - await waitFor(() => { - expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled(); - expect(fixtures.clerk.organization?.getInvitations).not.toHaveBeenCalled(); - expect(fixtures.clerk.organization?.getMembershipRequests).not.toHaveBeenCalled(); - expect(queryByText('test_user1')).toBeInTheDocument(); - expect(queryByText('First1 Last1')).toBeInTheDocument(); - const buttons = queryAllByRole('button', { name: 'Admin' }); - buttons.forEach(button => expect(button).not.toBeDisabled()); - expect(queryByText('test_user2')).toBeInTheDocument(); - expect(queryByText('First2 Last2')).toBeInTheDocument(); - expect(queryByText('Member')).toBeInTheDocument(); - }); + await waitForLoadingCompleted(container); + + expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled(); + expect(fixtures.clerk.organization?.getInvitations).not.toHaveBeenCalled(); + expect(fixtures.clerk.organization?.getMembershipRequests).not.toHaveBeenCalled(); + + expect(queryByText('test_user1')).toBeInTheDocument(); + expect(queryByText('First1 Last1')).toBeInTheDocument(); + + const buttons = queryAllByRole('button', { name: 'Admin' }); + buttons.forEach(button => expect(button).not.toBeDisabled()); + + expect(queryByText('test_user2')).toBeInTheDocument(); + expect(queryByText('First2 Last2')).toBeInTheDocument(); + expect(queryByText('Member')).toBeInTheDocument(); }); it('display pagination counts for 2 pages', async () => { @@ -210,26 +212,19 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { queryByText, getByText } = render(, { wrapper }); + const { container, getByText } = render(, { wrapper }); - await waitFor(async () => { - expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled(); - expect(fixtures.clerk.organization?.getInvitations).not.toHaveBeenCalled(); - expect(fixtures.clerk.organization?.getMembershipRequests).not.toHaveBeenCalled(); - - expect(queryByText(/displaying/i)).toBeInTheDocument(); + await waitForLoadingCompleted(container); - expect(queryByText(/1 – 10/i)).toBeInTheDocument(); - expect(queryByText(/of/i)).toBeInTheDocument(); - expect(queryByText(/^14/i)).toBeInTheDocument(); - }); + expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled(); + expect(fixtures.clerk.organization?.getInvitations).not.toHaveBeenCalled(); + expect(fixtures.clerk.organization?.getMembershipRequests).not.toHaveBeenCalled(); - await act(async () => await userEvent.click(getByText(/next/i))); + await userEvent.click(getByText(/next/i)); await waitFor(async () => { - expect(queryByText(/11 – 14/i)).toBeInTheDocument(); - expect(queryByText(/of/i)).toBeInTheDocument(); - expect(queryByText(/^14/i)).toBeInTheDocument(); + const pagination = getByText(/displaying/i).closest('p'); + expect(pagination?.textContent).toEqual('Displaying 11 – 14 of 14'); }); }); @@ -251,15 +246,13 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { queryByText, getByText } = render(, { wrapper }); + const { container, getByText } = render(, { wrapper }); - await waitFor(async () => { - expect(queryByText(/displaying/i)).toBeInTheDocument(); - expect(queryByText(/1 – 5/i)).toBeInTheDocument(); - expect(queryByText(/of/i)).toBeInTheDocument(); - expect(queryByText(/^5/i)).toBeInTheDocument(); - expect(getByText(/next/i)).toBeDisabled(); - }); + await waitForLoadingCompleted(container); + + const pagination = getByText(/displaying/i).closest('p'); + expect(pagination?.textContent).toEqual('Displaying 1 – 5 of 5'); + expect(getByText(/next/i)).toBeDisabled(); }); // TODO: Bring this test back once we can determine the last admin by permissions. @@ -328,12 +321,8 @@ describe('OrganizationMembers', () => { }), ); - await runFakeTimers(async () => { - const { getByText } = render(, { wrapper }); - await waitFor(() => { - expect(getByText('2')).toBeInTheDocument(); - }); - }); + const { findByText } = render(, { wrapper }); + expect(await findByText('2')).toBeInTheDocument(); }); it.todo('removes member from organization when clicking the respective button on a user row'); @@ -371,13 +360,17 @@ describe('OrganizationMembers', () => { total_count: 2, }), ); - const { queryByText, findByRole } = render(, { wrapper }); - await userEvent.click(await findByRole('tab', { name: 'Invitations' })); + + const { container, getByRole, getByText, findByText } = render(, { wrapper }); + + await waitForLoadingCompleted(container); + await userEvent.click(getByRole('tab', { name: 'Invitations' })); + + expect(await findByText('admin1@clerk.com')).toBeInTheDocument(); + expect(getByText('Admin')).toBeInTheDocument(); + expect(getByText('member2@clerk.com')).toBeInTheDocument(); + expect(getByText('Member')).toBeInTheDocument(); expect(fixtures.clerk.organization?.getInvitations).toHaveBeenCalled(); - expect(queryByText('admin1@clerk.com')).toBeInTheDocument(); - expect(queryByText('Admin')).toBeInTheDocument(); - expect(queryByText('member2@clerk.com')).toBeInTheDocument(); - expect(queryByText('Member')).toBeInTheDocument(); }); it('changes tab and renders pending requests', async () => { @@ -460,8 +453,11 @@ describe('OrganizationMembers', () => { }), ); - const { findByText } = await act(() => render(, { wrapper })); - await waitFor(() => expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled()); - expect(await findByText('You')).toBeInTheDocument(); + const { container, getByText } = render(, { wrapper }); + + await waitForLoadingCompleted(container); + + expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled(); + expect(getByText('You')).toBeInTheDocument(); }); }); diff --git a/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx b/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx index ea4b3036fd..24fa61618e 100644 --- a/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx +++ b/packages/clerk-js/src/ui.retheme/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx @@ -9,6 +9,8 @@ import { OrganizationProfile } from '../OrganizationProfile'; const { createFixtures } = bindCreateFixtures('OrganizationProfile'); describe('OrganizationProfile', () => { + beforeEach(() => jest.useFakeTimers()); + afterEach(() => jest.useRealTimers()); it('includes buttons for the bigger sections', async () => { const { wrapper } = await createFixtures(f => { f.withOrganizations(); diff --git a/packages/clerk-js/src/ui.retheme/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx b/packages/clerk-js/src/ui.retheme/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx index 4357679706..b93ee5d136 100644 --- a/packages/clerk-js/src/ui.retheme/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx +++ b/packages/clerk-js/src/ui.retheme/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx @@ -3,7 +3,6 @@ import { describe } from '@jest/globals'; import { act, render, waitFor } from '../../../../testUtils'; import { bindCreateFixtures } from '../../../utils/test/createFixtures'; -import { runFakeTimers } from '../../../utils/test/runFakeTimers'; import { OrganizationSwitcher } from '../OrganizationSwitcher'; import { createFakeUserOrganizationInvitation, @@ -19,8 +18,8 @@ describe('OrganizationSwitcher', () => { f.withOrganizations(); f.withUser({ email_addresses: ['test@clerk.com'] }); }); - const { queryByRole } = await act(() => render(, { wrapper })); - expect(queryByRole('button')).toBeDefined(); + const { getByRole } = await act(() => render(, { wrapper })); + expect(getByRole('button')).toBeInTheDocument(); }); describe('Personal Workspace', () => { @@ -31,7 +30,7 @@ describe('OrganizationSwitcher', () => { }); props.setProps({ hidePersonal: false }); const { getByText } = await act(() => render(, { wrapper })); - expect(getByText('Personal account')).toBeDefined(); + expect(getByText('Personal account')).toBeInTheDocument(); }); it('does not show the personal workspace when disabled', async () => { @@ -43,7 +42,7 @@ describe('OrganizationSwitcher', () => { const { queryByText, getByRole, userEvent, getByText } = render(, { wrapper }); await userEvent.click(getByRole('button')); expect(queryByText('Personal Workspace')).toBeNull(); - expect(getByText('No organization selected')).toBeDefined(); + expect(getByText('No organization selected')).toBeInTheDocument(); }); }); @@ -71,13 +70,8 @@ describe('OrganizationSwitcher', () => { }), ); - await runFakeTimers(async () => { - const { getByText } = render(, { wrapper }); - - await waitFor(() => { - expect(getByText('5')).toBeInTheDocument(); - }); - }); + const { findByText } = render(, { wrapper }); + expect(await findByText('5')).toBeInTheDocument(); }); it('shows the counter for pending suggestions and invitations and membership requests', async () => { @@ -110,14 +104,8 @@ describe('OrganizationSwitcher', () => { total_count: 3, }), ); - - await runFakeTimers(async () => { - const { getByText } = render(, { wrapper }); - - await waitFor(() => { - expect(getByText('7')).toBeInTheDocument(); - }); - }); + const { findByText } = render(, { wrapper }); + expect(await findByText('7')).toBeInTheDocument(); }); }); @@ -131,7 +119,7 @@ describe('OrganizationSwitcher', () => { props.setProps({ hidePersonal: true }); const { getByText, getByRole, userEvent } = render(, { wrapper }); await userEvent.click(getByRole('button')); - expect(getByText('Create Organization')).toBeDefined(); + expect(getByText('Create Organization')).toBeInTheDocument(); }); it('lists all organizations the user belongs to', async () => { @@ -176,8 +164,8 @@ describe('OrganizationSwitcher', () => { const { getAllByText, getByText, getByRole, userEvent } = render(, { wrapper }); await userEvent.click(getByRole('button')); expect(getAllByText('Org1')).not.toBeNull(); - expect(getByText('Personal account')).toBeDefined(); - expect(getByText('Org2')).toBeDefined(); + expect(getByText('Personal account')).toBeInTheDocument(); + expect(getByText('Org2')).toBeInTheDocument(); }); it.each([ @@ -196,8 +184,8 @@ describe('OrganizationSwitcher', () => { props.setProps({ hidePersonal: true }); const { getAllByText, getByText, getByRole, userEvent } = render(, { wrapper }); await userEvent.click(getByRole('button')); - expect(getAllByText('Org1')).not.toBeNull(); - expect(getByText(text)).toBeDefined(); + expect(getAllByText('Org1').length).toBeGreaterThan(0); + expect(getByText(text)).toBeInTheDocument(); }); it('opens organization profile when "Manage Organization" is clicked', async () => { diff --git a/packages/clerk-js/src/ui.retheme/elements/__tests__/PlainInput.test.tsx b/packages/clerk-js/src/ui.retheme/elements/__tests__/PlainInput.test.tsx index 8020d3e189..394f04f8dd 100644 --- a/packages/clerk-js/src/ui.retheme/elements/__tests__/PlainInput.test.tsx +++ b/packages/clerk-js/src/ui.retheme/elements/__tests__/PlainInput.test.tsx @@ -1,5 +1,5 @@ import { describe, it } from '@jest/globals'; -import { act, fireEvent, render, waitFor } from '@testing-library/react'; +import { fireEvent, render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { useFormControl } from '../../utils'; @@ -132,15 +132,15 @@ describe('PlainInput', () => { placeholder: 'some placeholder', }); - const { getByRole, getByLabelText, getByText } = render(, { wrapper }); + const { getByRole, getByLabelText, findByText } = render(, { wrapper }); - await act(() => userEvent.click(getByRole('button', { name: /set error/i }))); + await userEvent.click(getByRole('button', { name: /set error/i })); - await waitFor(() => { - expect(getByLabelText('some label')).toHaveAttribute('aria-invalid', 'true'); - expect(getByLabelText('some label')).toHaveAttribute('aria-describedby', 'error-firstname'); - expect(getByText('some error')).toBeInTheDocument(); - }); + expect(await findByText('some error')).toBeInTheDocument(); + + const label = getByLabelText('some label'); + expect(label).toHaveAttribute('aria-invalid', 'true'); + expect(label).toHaveAttribute('aria-describedby', 'error-firstname'); }); it('with info', async () => { @@ -152,10 +152,9 @@ describe('PlainInput', () => { infoText: 'some info', }); - const { getByLabelText, getByText } = render(, { wrapper }); - await act(() => fireEvent.focus(getByLabelText('some label'))); - await waitFor(() => { - expect(getByText('some info')).toBeInTheDocument(); - }); + const { findByLabelText, findByText } = render(, { wrapper }); + + fireEvent.focus(await findByLabelText('some label')); + expect(await findByText('some info')).toBeInTheDocument(); }); }); diff --git a/packages/clerk-js/src/ui.retheme/elements/__tests__/RadioGroup.test.tsx b/packages/clerk-js/src/ui.retheme/elements/__tests__/RadioGroup.test.tsx index dd0d8ea76c..5c10111e64 100644 --- a/packages/clerk-js/src/ui.retheme/elements/__tests__/RadioGroup.test.tsx +++ b/packages/clerk-js/src/ui.retheme/elements/__tests__/RadioGroup.test.tsx @@ -1,5 +1,5 @@ import { describe, it } from '@jest/globals'; -import { act, fireEvent, render, waitFor } from '@testing-library/react'; +import { fireEvent, render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { useFormControl } from '../../utils'; @@ -141,7 +141,7 @@ describe('RadioGroup', () => { const { wrapper } = await createFixtures(); const { Field } = createField('some-radio', 'two'); - const { getAllByRole, getByRole, getByText } = render( + const { getAllByRole, getByRole, findByText } = render( { { wrapper }, ); - await act(() => userEvent.click(getByRole('button', { name: /set error/i }))); + await userEvent.click(getByRole('button', { name: /set error/i })); + expect(await findByText('some error')).toBeInTheDocument(); - await waitFor(() => { - const radios = getAllByRole('radio'); - radios.forEach(radio => { - expect(radio).toHaveAttribute('aria-invalid', 'true'); - expect(radio).toHaveAttribute('aria-describedby', 'error-some-radio'); - }); - expect(getByText('some error')).toBeInTheDocument(); + const radios = getAllByRole('radio'); + radios.forEach(radio => { + expect(radio).toHaveAttribute('aria-invalid', 'true'); + expect(radio).toHaveAttribute('aria-describedby', 'error-some-radio'); }); }); @@ -174,11 +172,9 @@ describe('RadioGroup', () => { infoText: 'some info', }); - const { getByLabelText, getByText } = render(, { wrapper }); + const { findByLabelText, findByText } = render(, { wrapper }); - await act(() => fireEvent.focus(getByLabelText('One'))); - await waitFor(() => { - expect(getByText('some info')).toBeInTheDocument(); - }); + fireEvent.focus(await findByLabelText('One')); + expect(await findByText('some info')).toBeInTheDocument(); }); }); diff --git a/packages/clerk-js/src/ui.retheme/hooks/__tests__/useCoreOrganization.test.tsx b/packages/clerk-js/src/ui.retheme/hooks/__tests__/useCoreOrganization.test.tsx index d02ef9ef9f..d862e65071 100644 --- a/packages/clerk-js/src/ui.retheme/hooks/__tests__/useCoreOrganization.test.tsx +++ b/packages/clerk-js/src/ui.retheme/hooks/__tests__/useCoreOrganization.test.tsx @@ -1,7 +1,7 @@ import { useOrganization } from '@clerk/shared/react'; import { describe } from '@jest/globals'; -import { act, bindCreateFixtures, renderHook, waitFor } from '../../../testUtils'; +import { act, renderHook, waitFor } from '../../../testUtils'; import { createFakeDomain, createFakeOrganizationMembershipRequest, @@ -129,23 +129,22 @@ describe('useOrganization', () => { expect(result.current.memberships?.isFetching).toBe(true); expect(result.current.memberships?.count).toBe(0); - await waitFor(() => { - expect(result.current.memberships?.isLoading).toBe(false); - expect(result.current.memberships?.count).toBe(4); - expect(result.current.memberships?.page).toBe(1); - expect(result.current.memberships?.pageCount).toBe(2); - expect(result.current.memberships?.hasNextPage).toBe(true); - expect(result.current.memberships?.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: '1', - }), - expect.objectContaining({ - id: '2', - }), - ]), - ); - }); + await waitFor(() => expect(result.current.memberships?.isLoading).toBe(false)); + + expect(result.current.memberships?.count).toBe(4); + expect(result.current.memberships?.page).toBe(1); + expect(result.current.memberships?.pageCount).toBe(2); + expect(result.current.memberships?.hasNextPage).toBe(true); + expect(result.current.memberships?.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: '1', + }), + expect.objectContaining({ + id: '2', + }), + ]), + ); fixtures.clerk.organization?.getMemberships.mockReturnValue( Promise.resolve({ @@ -179,35 +178,29 @@ describe('useOrganization', () => { }), ); - act(() => { - result.current.memberships?.fetchNext?.(); - }); - - await waitFor(() => { - expect(result.current.memberships?.isLoading).toBe(true); - }); - - await waitFor(() => { - expect(result.current.memberships?.isLoading).toBe(false); - expect(result.current.memberships?.page).toBe(2); - expect(result.current.memberships?.hasNextPage).toBe(false); - expect(result.current.memberships?.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', - }), - expect.not.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + act(() => result.current.memberships?.fetchNext?.()); + + await waitFor(() => expect(result.current.memberships?.isLoading).toBe(true)); + await waitFor(() => expect(result.current.memberships?.isLoading).toBe(false)); + + expect(result.current.memberships?.page).toBe(2); + expect(result.current.memberships?.hasNextPage).toBe(false); + expect(result.current.memberships?.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); }); @@ -243,25 +236,25 @@ describe('useOrganization', () => { expect(result.current.domains?.isFetching).toBe(true); expect(result.current.domains?.count).toBe(0); - await waitFor(() => { - expect(result.current.domains?.isLoading).toBe(false); - expect(result.current.domains?.count).toBe(4); - expect(result.current.domains?.page).toBe(1); - expect(result.current.domains?.pageCount).toBe(2); - expect(result.current.domains?.hasNextPage).toBe(true); - expect(result.current.domains?.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: '1', - name: 'one.dev', - }), - expect.objectContaining({ - id: '2', - name: 'two.dev', - }), - ]), - ); - }); + await waitFor(() => expect(result.current.domains?.isLoading).toBe(false)); + + expect(result.current.domains?.isLoading).toBe(false); + expect(result.current.domains?.count).toBe(4); + expect(result.current.domains?.page).toBe(1); + expect(result.current.domains?.pageCount).toBe(2); + expect(result.current.domains?.hasNextPage).toBe(true); + expect(result.current.domains?.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: '1', + name: 'one.dev', + }), + expect.objectContaining({ + id: '2', + name: 'two.dev', + }), + ]), + ); fixtures.clerk.organization?.getDomains.mockReturnValue( Promise.resolve({ @@ -281,35 +274,29 @@ describe('useOrganization', () => { }), ); - act(() => { - result.current.domains?.fetchNext?.(); - }); - - await waitFor(() => { - expect(result.current.domains?.isLoading).toBe(true); - }); - - await waitFor(() => { - expect(result.current.domains?.isLoading).toBe(false); - expect(result.current.domains?.page).toBe(2); - expect(result.current.domains?.hasNextPage).toBe(false); - expect(result.current.domains?.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', - }), - expect.not.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + act(() => result.current.domains?.fetchNext?.()); + + await waitFor(() => expect(result.current.domains?.isLoading).toBe(true)); + await waitFor(() => expect(result.current.domains?.isLoading).toBe(false)); + + expect(result.current.domains?.page).toBe(2); + expect(result.current.domains?.hasNextPage).toBe(false); + expect(result.current.domains?.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); }); @@ -351,13 +338,13 @@ describe('useOrganization', () => { expect(result.current.membershipRequests?.isFetching).toBe(true); expect(result.current.membershipRequests?.count).toBe(0); - await waitFor(() => { - expect(result.current.membershipRequests?.isLoading).toBe(false); - expect(result.current.membershipRequests?.count).toBe(4); - expect(result.current.membershipRequests?.page).toBe(1); - expect(result.current.membershipRequests?.pageCount).toBe(2); - expect(result.current.membershipRequests?.hasNextPage).toBe(true); - }); + await waitFor(() => expect(result.current.membershipRequests?.isLoading).toBe(false)); + + expect(result.current.membershipRequests?.isFetching).toBe(false); + expect(result.current.membershipRequests?.count).toBe(4); + expect(result.current.membershipRequests?.page).toBe(1); + expect(result.current.membershipRequests?.pageCount).toBe(2); + expect(result.current.membershipRequests?.hasNextPage).toBe(true); fixtures.clerk.organization?.getMembershipRequests.mockReturnValue( Promise.resolve({ @@ -383,43 +370,37 @@ describe('useOrganization', () => { }), ); - act(() => { - result.current.membershipRequests?.fetchNext?.(); - }); - - await waitFor(() => { - expect(result.current.membershipRequests?.isLoading).toBe(true); - }); - - await waitFor(() => { - expect(result.current.membershipRequests?.isLoading).toBe(false); - expect(result.current.membershipRequests?.page).toBe(2); - expect(result.current.membershipRequests?.hasNextPage).toBe(false); - expect(result.current.membershipRequests?.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', + act(() => result.current.membershipRequests?.fetchNext?.()); + + await waitFor(() => expect(result.current.membershipRequests?.isLoading).toBe(true)); + await waitFor(() => expect(result.current.membershipRequests?.isLoading).toBe(false)); + + expect(result.current.membershipRequests?.page).toBe(2); + expect(result.current.membershipRequests?.hasNextPage).toBe(false); + expect(result.current.membershipRequests?.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + organizationId: '1', + id: '3', + publicUserData: expect.objectContaining({ + userId: 'test_user3', }), - expect.not.objectContaining({ - id: '2', + }), + expect.objectContaining({ + organizationId: '1', + id: '4', + publicUserData: expect.objectContaining({ + userId: 'test_user4', }), - expect.objectContaining({ - organizationId: '1', - id: '3', - publicUserData: expect.objectContaining({ - userId: 'test_user3', - }), - }), - expect.objectContaining({ - organizationId: '1', - id: '4', - publicUserData: expect.objectContaining({ - userId: 'test_user4', - }), - }), - ]), - ); - }); + }), + ]), + ); }); }); }); diff --git a/packages/clerk-js/src/ui.retheme/hooks/__tests__/useCoreOrganizationList.test.tsx b/packages/clerk-js/src/ui.retheme/hooks/__tests__/useCoreOrganizationList.test.tsx index e097b0ed16..1f7a4a4137 100644 --- a/packages/clerk-js/src/ui.retheme/hooks/__tests__/useCoreOrganizationList.test.tsx +++ b/packages/clerk-js/src/ui.retheme/hooks/__tests__/useCoreOrganizationList.test.tsx @@ -100,13 +100,12 @@ describe('useOrganizationList', () => { expect(result.current.userMemberships.isFetching).toBe(true); expect(result.current.userMemberships.count).toBe(0); - await waitFor(() => { - expect(result.current.userMemberships.isLoading).toBe(false); - expect(result.current.userMemberships.count).toBe(4); - expect(result.current.userMemberships.page).toBe(1); - expect(result.current.userMemberships.pageCount).toBe(2); - expect(result.current.userMemberships.hasNextPage).toBe(true); - }); + await waitFor(() => expect(result.current.userMemberships.isLoading).toBe(false)); + + expect(result.current.userMemberships.count).toBe(4); + expect(result.current.userMemberships.page).toBe(1); + expect(result.current.userMemberships.pageCount).toBe(2); + expect(result.current.userMemberships.hasNextPage).toBe(true); fixtures.clerk.user?.getOrganizationMemberships.mockReturnValue( Promise.resolve({ @@ -140,35 +139,29 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userMemberships.fetchNext?.(); - }); + act(() => result.current.userMemberships?.fetchNext?.()); - await waitFor(() => { - expect(result.current.userMemberships.isLoading).toBe(true); - }); + await waitFor(() => expect(result.current.userMemberships?.isLoading).toBe(true)); + await waitFor(() => expect(result.current.userMemberships?.isLoading).toBe(false)); - await waitFor(() => { - expect(result.current.userMemberships.isLoading).toBe(false); - expect(result.current.userMemberships.page).toBe(2); - expect(result.current.userMemberships.hasNextPage).toBe(false); - expect(result.current.userMemberships.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', - }), - expect.not.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + expect(result.current.userMemberships.page).toBe(2); + expect(result.current.userMemberships.hasNextPage).toBe(false); + expect(result.current.userMemberships.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); it('infinite fetch', async () => { @@ -224,10 +217,8 @@ describe('useOrganizationList', () => { expect(result.current.userMemberships.isLoading).toBe(true); expect(result.current.userMemberships.isFetching).toBe(true); - await waitFor(() => { - expect(result.current.userMemberships.isLoading).toBe(false); - expect(result.current.userMemberships.isFetching).toBe(false); - }); + await waitFor(() => expect(result.current.userMemberships.isLoading).toBe(false)); + expect(result.current.userMemberships.isFetching).toBe(false); fixtures.clerk.user?.getOrganizationMemberships.mockReturnValueOnce( Promise.resolve({ @@ -293,34 +284,28 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userMemberships.fetchNext?.(); - }); + act(() => result.current.userMemberships?.fetchNext?.()); - await waitFor(() => { - expect(result.current.userMemberships.isLoading).toBe(false); - expect(result.current.userMemberships.isFetching).toBe(true); - }); + await waitFor(() => expect(result.current.userMemberships?.isFetching).toBe(true)); + expect(result.current.userMemberships?.isLoading).toBe(false); - await waitFor(() => { - expect(result.current.userMemberships.isFetching).toBe(false); - expect(result.current.userMemberships.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: '1', - }), - expect.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + await waitFor(() => expect(result.current.userMemberships?.isFetching).toBe(false)); + expect(result.current.userMemberships.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: '1', + }), + expect.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); }); @@ -349,18 +334,19 @@ describe('useOrganizationList', () => { total_count: 4, }), ); + const { result } = renderHook(defaultRenderer, { wrapper }); + expect(result.current.userInvitations.isLoading).toBe(true); expect(result.current.userInvitations.isFetching).toBe(true); expect(result.current.userInvitations.count).toBe(0); - await waitFor(() => { - expect(result.current.userInvitations.isLoading).toBe(false); - expect(result.current.userInvitations.count).toBe(4); - expect(result.current.userInvitations.page).toBe(1); - expect(result.current.userInvitations.pageCount).toBe(2); - expect(result.current.userInvitations.hasNextPage).toBe(true); - }); + await waitFor(() => expect(result.current.userInvitations.isLoading).toBe(false)); + + expect(result.current.userInvitations.count).toBe(4); + expect(result.current.userInvitations.page).toBe(1); + expect(result.current.userInvitations.pageCount).toBe(2); + expect(result.current.userInvitations.hasNextPage).toBe(true); fixtures.clerk.user?.getOrganizationInvitations.mockReturnValue( Promise.resolve({ @@ -378,35 +364,29 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userInvitations.fetchNext?.(); - }); + act(() => result.current.userInvitations?.fetchNext?.()); - await waitFor(() => { - expect(result.current.userInvitations.isLoading).toBe(true); - }); + await waitFor(() => expect(result.current.userInvitations?.isLoading).toBe(true)); + await waitFor(() => expect(result.current.userInvitations?.isLoading).toBe(false)); - await waitFor(() => { - expect(result.current.userInvitations.isLoading).toBe(false); - expect(result.current.userInvitations.page).toBe(2); - expect(result.current.userInvitations.hasNextPage).toBe(false); - expect(result.current.userInvitations.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', - }), - expect.not.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + expect(result.current.userInvitations.page).toBe(2); + expect(result.current.userInvitations.hasNextPage).toBe(false); + expect(result.current.userInvitations.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); it('infinite fetch', async () => { @@ -443,13 +423,12 @@ describe('useOrganizationList', () => { }), { wrapper }, ); + expect(result.current.userInvitations.isLoading).toBe(true); expect(result.current.userInvitations.isFetching).toBe(true); - await waitFor(() => { - expect(result.current.userInvitations.isLoading).toBe(false); - expect(result.current.userInvitations.isFetching).toBe(false); - }); + await waitFor(() => expect(result.current.userInvitations.isLoading).toBe(false)); + expect(result.current.userInvitations.isFetching).toBe(false); fixtures.clerk.user?.getOrganizationInvitations.mockReturnValueOnce( Promise.resolve({ @@ -483,34 +462,28 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userInvitations.fetchNext?.(); - }); + act(() => result.current.userInvitations.fetchNext?.()); - await waitFor(() => { - expect(result.current.userInvitations.isLoading).toBe(false); - expect(result.current.userInvitations.isFetching).toBe(true); - }); + await waitFor(() => expect(result.current.userInvitations.isFetching).toBe(true)); + expect(result.current.userInvitations.isLoading).toBe(false); - await waitFor(() => { - expect(result.current.userInvitations.isFetching).toBe(false); - expect(result.current.userInvitations.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: '1', - }), - expect.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + await waitFor(() => expect(result.current.userInvitations.isFetching).toBe(false)); + expect(result.current.userInvitations.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: '1', + }), + expect.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); }); @@ -544,13 +517,12 @@ describe('useOrganizationList', () => { expect(result.current.userSuggestions.isFetching).toBe(true); expect(result.current.userSuggestions.count).toBe(0); - await waitFor(() => { - expect(result.current.userSuggestions.isLoading).toBe(false); - expect(result.current.userSuggestions.count).toBe(4); - expect(result.current.userSuggestions.page).toBe(1); - expect(result.current.userSuggestions.pageCount).toBe(2); - expect(result.current.userSuggestions.hasNextPage).toBe(true); - }); + await waitFor(() => expect(result.current.userSuggestions.isLoading).toBe(false)); + + expect(result.current.userSuggestions.count).toBe(4); + expect(result.current.userSuggestions.page).toBe(1); + expect(result.current.userSuggestions.pageCount).toBe(2); + expect(result.current.userSuggestions.hasNextPage).toBe(true); fixtures.clerk.user?.getOrganizationSuggestions.mockReturnValue( Promise.resolve({ @@ -568,35 +540,29 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userSuggestions.fetchNext?.(); - }); + act(() => result.current.userSuggestions.fetchNext?.()); - await waitFor(() => { - expect(result.current.userSuggestions.isLoading).toBe(true); - }); + await waitFor(() => expect(result.current.userSuggestions.isLoading).toBe(true)); + await waitFor(() => expect(result.current.userSuggestions.isLoading).toBe(false)); - await waitFor(() => { - expect(result.current.userSuggestions.isLoading).toBe(false); - expect(result.current.userSuggestions.page).toBe(2); - expect(result.current.userSuggestions.hasNextPage).toBe(false); - expect(result.current.userSuggestions.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', - }), - expect.not.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + expect(result.current.userSuggestions.page).toBe(2); + expect(result.current.userSuggestions.hasNextPage).toBe(false); + expect(result.current.userSuggestions.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); it('infinite fetch', async () => { @@ -636,10 +602,8 @@ describe('useOrganizationList', () => { expect(result.current.userSuggestions.isLoading).toBe(true); expect(result.current.userSuggestions.isFetching).toBe(true); - await waitFor(() => { - expect(result.current.userSuggestions.isLoading).toBe(false); - expect(result.current.userSuggestions.isFetching).toBe(false); - }); + await waitFor(() => expect(result.current.userSuggestions.isLoading).toBe(false)); + expect(result.current.userSuggestions.isFetching).toBe(false); fixtures.clerk.user?.getOrganizationSuggestions.mockReturnValueOnce( Promise.resolve({ @@ -673,34 +637,28 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userSuggestions.fetchNext?.(); - }); + act(() => result.current.userSuggestions.fetchNext?.()); - await waitFor(() => { - expect(result.current.userSuggestions.isLoading).toBe(false); - expect(result.current.userSuggestions.isFetching).toBe(true); - }); + await waitFor(() => expect(result.current.userSuggestions.isFetching).toBe(true)); + expect(result.current.userSuggestions.isLoading).toBe(false); - await waitFor(() => { - expect(result.current.userSuggestions.isFetching).toBe(false); - expect(result.current.userSuggestions.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: '1', - }), - expect.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + await waitFor(() => expect(result.current.userSuggestions.isFetching).toBe(false)); + expect(result.current.userSuggestions.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: '1', + }), + expect.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); }); }); diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/InviteMembersPage.test.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/InviteMembersPage.test.tsx index 9a1b97ce9e..e7f8ba1fe4 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/InviteMembersPage.test.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/InviteMembersPage.test.tsx @@ -1,7 +1,6 @@ import type { MembershipRole, OrganizationInvitationResource } from '@clerk/types'; import { describe } from '@jest/globals'; import { waitFor } from '@testing-library/dom'; -import { act } from '@testing-library/react'; import React from 'react'; import { ClerkAPIResponseError } from '../../../../core/resources'; @@ -15,12 +14,16 @@ describe('InviteMembersPage', () => { it('renders the component', async () => { const { wrapper, fixtures } = await createFixtures(f => { f.withOrganizations(); - f.withUser({ email_addresses: ['test@clerk.com'], organization_memberships: [{ name: 'Org1', role: 'admin' }] }); + f.withUser({ + email_addresses: ['test@clerk.com'], + organization_memberships: [{ name: 'Org1', role: 'admin' }], + }); }); fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { getByText } = await act(() => render(, { wrapper })); - expect(getByText('Invite new members to this organization')).toBeDefined(); + + const { findByText } = render(, { wrapper }); + await waitFor(async () => expect(await findByText('Invite new members to this organization')).toBeInTheDocument()); }); describe('Submitting', () => { @@ -56,14 +59,19 @@ describe('InviteMembersPage', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); fixtures.clerk.organization?.inviteMembers.mockResolvedValueOnce([{}] as OrganizationInvitationResource[]); - const { getByRole, userEvent, getByTestId, getByText } = render(, { wrapper }); + const { getByRole, userEvent, getByTestId, getByText } = render(, { + wrapper, + }); await userEvent.type(getByTestId('tag-input'), 'test+1@clerk.com,'); await userEvent.click(getByRole('button', { name: 'Select an option' })); await userEvent.click(getByText('Member')); await userEvent.click(getByRole('button', { name: 'Send invitations' })); - expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ - emailAddresses: ['test+1@clerk.com'], - role: 'basic_member' as MembershipRole, + + await waitFor(() => { + expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ + emailAddresses: ['test+1@clerk.com'], + role: 'basic_member' as MembershipRole, + }); }); }); @@ -98,9 +106,12 @@ describe('InviteMembersPage', () => { await userEvent.click(getByRole('button', { name: 'Select an option' })); await userEvent.click(getByText('Teacher')); await userEvent.click(getByRole('button', { name: 'Send invitations' })); - expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ - emailAddresses: ['test+1@clerk.com'], - role: 'org:teacher' as MembershipRole, + + await waitFor(() => { + expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ + emailAddresses: ['test+1@clerk.com'], + role: 'org:teacher' as MembershipRole, + }); }); }); @@ -123,9 +134,12 @@ describe('InviteMembersPage', () => { await userEvent.click(getByRole('button', { name: 'Select an option' })); await userEvent.click(getByText('Member')); await userEvent.click(getByRole('button', { name: 'Send invitations' })); - expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ - emailAddresses: ['test+1@clerk.com', 'test+2@clerk.com', 'test+3@clerk.com', 'test+4@clerk.com'], - role: 'basic_member' as MembershipRole, + + await waitFor(() => { + expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ + emailAddresses: ['test+1@clerk.com', 'test+2@clerk.com', 'test+3@clerk.com', 'test+4@clerk.com'], + role: 'basic_member' as MembershipRole, + }); }); }); @@ -145,9 +159,12 @@ describe('InviteMembersPage', () => { await userEvent.click(getByRole('button', { name: 'Select an option' })); await userEvent.click(getByText('Admin')); await userEvent.click(getByRole('button', { name: 'Send invitations' })); - expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ - emailAddresses: ['test+1@clerk.com'], - role: 'admin' as MembershipRole, + + await waitFor(() => { + expect(fixtures.clerk.organization?.inviteMembers).toHaveBeenCalledWith({ + emailAddresses: ['test+1@clerk.com'], + role: 'admin' as MembershipRole, + }); }); }); diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationMembers.test.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationMembers.test.tsx index 4017c0c4b3..556f744704 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationMembers.test.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationMembers.test.tsx @@ -1,35 +1,37 @@ import type { OrganizationInvitationResource, OrganizationMembershipResource } from '@clerk/types'; import { describe } from '@jest/globals'; -import { act, waitFor } from '@testing-library/react'; +import { waitFor, waitForElementToBeRemoved } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { render } from '../../../../testUtils'; import { bindCreateFixtures } from '../../../utils/test/createFixtures'; -import { runFakeTimers } from '../../../utils/test/runFakeTimers'; import { OrganizationMembers } from '../OrganizationMembers'; import { createFakeMember, createFakeOrganizationInvitation, createFakeOrganizationMembershipRequest } from './utils'; const { createFixtures } = bindCreateFixtures('OrganizationProfile'); +async function waitForLoadingCompleted(container: HTMLElement) { + return waitForElementToBeRemoved(() => container.querySelector('span[aria-busy="true"]')); +} + describe('OrganizationMembers', () => { it('renders the Organization Members page', async () => { const { wrapper, fixtures } = await createFixtures(f => { f.withOrganizations(); f.withUser({ email_addresses: ['test@clerk.com'], organization_memberships: ['Org1'] }); }); + fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { getByText, getByRole } = render(, { wrapper }); + const { container, getByText, getByRole } = render(, { wrapper }); - await waitFor(() => { - expect(getByRole('heading', { name: /members/i })).toBeInTheDocument(); - expect(getByText('View and manage organization members')).toBeInTheDocument(); - }); + await waitForLoadingCompleted(container); - await waitFor(() => { - // Tabs - expect(getByRole('tab', { name: 'Members' })).toBeInTheDocument(); - expect(getByRole('tab', { name: 'Invitations' })).toBeInTheDocument(); - }); + expect(getByRole('heading', { name: /members/i })).toBeInTheDocument(); + expect(getByText('View and manage organization members')).toBeInTheDocument(); + + // Tabs + expect(getByRole('tab', { name: 'Members' })).toBeInTheDocument(); + expect(getByRole('tab', { name: 'Invitations' })).toBeInTheDocument(); }); it('shows requests if domains is turned on', async () => { @@ -41,11 +43,11 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { getByRole } = render(, { wrapper }); + const { getByRole, container } = render(, { wrapper }); - await waitFor(() => { - expect(getByRole('tab', { name: 'Requests' })).toBeInTheDocument(); - }); + await waitForLoadingCompleted(container); + + expect(getByRole('tab', { name: 'Requests' })).toBeInTheDocument(); }); it('shows an invite button inside invitations tab if the current user is an admin', async () => { @@ -56,13 +58,11 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { getByRole, getByText } = render(, { wrapper }); + const { getByRole, findByText } = render(, { wrapper }); - await waitFor(async () => { - await userEvent.click(getByRole('tab', { name: 'Invitations' })); - expect(getByText('Invited')).toBeDefined(); - expect(getByRole('button', { name: 'Invite' })).toBeDefined(); - }); + await userEvent.click(getByRole('tab', { name: 'Invitations' })); + expect(await findByText('Invited')).toBeInTheDocument(); + expect(getByRole('button', { name: 'Invite' })).toBeInTheDocument(); }); it('does not show invitations and requests if user is not an admin', async () => { @@ -76,13 +76,13 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { queryByRole } = render(, { wrapper }); + const { container, queryByRole } = render(, { wrapper }); - await waitFor(() => { - expect(queryByRole('tab', { name: 'Members' })).toBeInTheDocument(); - expect(queryByRole('tab', { name: 'Invitations' })).not.toBeInTheDocument(); - expect(queryByRole('tab', { name: 'Requests' })).not.toBeInTheDocument(); - }); + await waitForLoadingCompleted(container); + + expect(queryByRole('tab', { name: 'Members' })).toBeInTheDocument(); + expect(queryByRole('tab', { name: 'Invitations' })).not.toBeInTheDocument(); + expect(queryByRole('tab', { name: 'Requests' })).not.toBeInTheDocument(); }); it('does not show members tab or navbar route if user is lacking permissions', async () => { @@ -98,11 +98,9 @@ describe('OrganizationMembers', () => { const { queryByRole } = render(, { wrapper }); - await waitFor(() => { - expect(queryByRole('tab', { name: 'Members' })).not.toBeInTheDocument(); - expect(queryByRole('tab', { name: 'Invitations' })).not.toBeInTheDocument(); - expect(queryByRole('tab', { name: 'Requests' })).not.toBeInTheDocument(); - }); + expect(queryByRole('tab', { name: 'Members' })).not.toBeInTheDocument(); + expect(queryByRole('tab', { name: 'Invitations' })).not.toBeInTheDocument(); + expect(queryByRole('tab', { name: 'Requests' })).not.toBeInTheDocument(); }); it('navigates to invite screen when user clicks on Invite button', async () => { @@ -113,13 +111,14 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { getByRole } = render(, { wrapper }); + const { container, getByRole } = render(, { wrapper }); - await waitFor(async () => { - await userEvent.click(getByRole('tab', { name: 'Invitations' })); - await userEvent.click(getByRole('button', { name: 'Invite' })); - expect(fixtures.router.navigate).toHaveBeenCalledWith('invite-members'); - }); + await waitForLoadingCompleted(container); + + await userEvent.click(getByRole('tab', { name: 'Invitations' })); + await userEvent.click(getByRole('button', { name: 'Invite' })); + + expect(fixtures.router.navigate).toHaveBeenCalledWith('invite-members'); }); it('lists all the members of the Organization', async () => { @@ -176,20 +175,23 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { queryByText, queryAllByRole } = render(, { wrapper }); + const { container, queryByText, queryAllByRole } = render(, { wrapper }); - await waitFor(() => { - expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled(); - expect(fixtures.clerk.organization?.getInvitations).not.toHaveBeenCalled(); - expect(fixtures.clerk.organization?.getMembershipRequests).not.toHaveBeenCalled(); - expect(queryByText('test_user1')).toBeInTheDocument(); - expect(queryByText('First1 Last1')).toBeInTheDocument(); - const buttons = queryAllByRole('button', { name: 'Admin' }); - buttons.forEach(button => expect(button).not.toBeDisabled()); - expect(queryByText('test_user2')).toBeInTheDocument(); - expect(queryByText('First2 Last2')).toBeInTheDocument(); - expect(queryByText('Member')).toBeInTheDocument(); - }); + await waitForLoadingCompleted(container); + + expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled(); + expect(fixtures.clerk.organization?.getInvitations).not.toHaveBeenCalled(); + expect(fixtures.clerk.organization?.getMembershipRequests).not.toHaveBeenCalled(); + + expect(queryByText('test_user1')).toBeInTheDocument(); + expect(queryByText('First1 Last1')).toBeInTheDocument(); + + const buttons = queryAllByRole('button', { name: 'Admin' }); + buttons.forEach(button => expect(button).not.toBeDisabled()); + + expect(queryByText('test_user2')).toBeInTheDocument(); + expect(queryByText('First2 Last2')).toBeInTheDocument(); + expect(queryByText('Member')).toBeInTheDocument(); }); it('display pagination counts for 2 pages', async () => { @@ -210,26 +212,19 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { queryByText, getByText } = render(, { wrapper }); + const { container, getByText } = render(, { wrapper }); - await waitFor(async () => { - expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled(); - expect(fixtures.clerk.organization?.getInvitations).not.toHaveBeenCalled(); - expect(fixtures.clerk.organization?.getMembershipRequests).not.toHaveBeenCalled(); - - expect(queryByText(/displaying/i)).toBeInTheDocument(); + await waitForLoadingCompleted(container); - expect(queryByText(/1 – 10/i)).toBeInTheDocument(); - expect(queryByText(/of/i)).toBeInTheDocument(); - expect(queryByText(/^14/i)).toBeInTheDocument(); - }); + expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled(); + expect(fixtures.clerk.organization?.getInvitations).not.toHaveBeenCalled(); + expect(fixtures.clerk.organization?.getMembershipRequests).not.toHaveBeenCalled(); - await act(async () => await userEvent.click(getByText(/next/i))); + await userEvent.click(getByText(/next/i)); await waitFor(async () => { - expect(queryByText(/11 – 14/i)).toBeInTheDocument(); - expect(queryByText(/of/i)).toBeInTheDocument(); - expect(queryByText(/^14/i)).toBeInTheDocument(); + const pagination = getByText(/displaying/i).closest('p'); + expect(pagination?.textContent).toEqual('Displaying 11 – 14 of 14'); }); }); @@ -251,15 +246,13 @@ describe('OrganizationMembers', () => { fixtures.clerk.organization?.getRoles.mockRejectedValue(null); - const { queryByText, getByText } = render(, { wrapper }); + const { container, getByText } = render(, { wrapper }); - await waitFor(async () => { - expect(queryByText(/displaying/i)).toBeInTheDocument(); - expect(queryByText(/1 – 5/i)).toBeInTheDocument(); - expect(queryByText(/of/i)).toBeInTheDocument(); - expect(queryByText(/^5/i)).toBeInTheDocument(); - expect(getByText(/next/i)).toBeDisabled(); - }); + await waitForLoadingCompleted(container); + + const pagination = getByText(/displaying/i).closest('p'); + expect(pagination?.textContent).toEqual('Displaying 1 – 5 of 5'); + expect(getByText(/next/i)).toBeDisabled(); }); // TODO: Bring this test back once we can determine the last admin by permissions. @@ -328,12 +321,8 @@ describe('OrganizationMembers', () => { }), ); - await runFakeTimers(async () => { - const { getByText } = render(, { wrapper }); - await waitFor(() => { - expect(getByText('2')).toBeInTheDocument(); - }); - }); + const { findByText } = render(, { wrapper }); + expect(await findByText('2')).toBeInTheDocument(); }); it.todo('removes member from organization when clicking the respective button on a user row'); @@ -371,13 +360,17 @@ describe('OrganizationMembers', () => { total_count: 2, }), ); - const { queryByText, findByRole } = render(, { wrapper }); - await userEvent.click(await findByRole('tab', { name: 'Invitations' })); + + const { container, getByRole, getByText, findByText } = render(, { wrapper }); + + await waitForLoadingCompleted(container); + await userEvent.click(getByRole('tab', { name: 'Invitations' })); + + expect(await findByText('admin1@clerk.com')).toBeInTheDocument(); + expect(getByText('Admin')).toBeInTheDocument(); + expect(getByText('member2@clerk.com')).toBeInTheDocument(); + expect(getByText('Member')).toBeInTheDocument(); expect(fixtures.clerk.organization?.getInvitations).toHaveBeenCalled(); - expect(queryByText('admin1@clerk.com')).toBeInTheDocument(); - expect(queryByText('Admin')).toBeInTheDocument(); - expect(queryByText('member2@clerk.com')).toBeInTheDocument(); - expect(queryByText('Member')).toBeInTheDocument(); }); it('changes tab and renders pending requests', async () => { @@ -460,8 +453,11 @@ describe('OrganizationMembers', () => { }), ); - const { findByText } = await act(() => render(, { wrapper })); - await waitFor(() => expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled()); - expect(await findByText('You')).toBeInTheDocument(); + const { container, getByText } = render(, { wrapper }); + + await waitForLoadingCompleted(container); + + expect(fixtures.clerk.organization?.getMemberships).toHaveBeenCalled(); + expect(getByText('You')).toBeInTheDocument(); }); }); diff --git a/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx b/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx index ea4b3036fd..78c2af5c66 100644 --- a/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationProfile/__tests__/OrganizationProfile.test.tsx @@ -16,9 +16,9 @@ describe('OrganizationProfile', () => { }); const { getByText } = render(, { wrapper }); - expect(getByText('Org1')).toBeDefined(); - expect(getByText('Members')).toBeDefined(); - expect(getByText('Settings')).toBeDefined(); + expect(getByText('Org1')).toBeInTheDocument(); + expect(getByText('Members')).toBeInTheDocument(); + expect(getByText('Settings')).toBeInTheDocument(); }); it('includes custom nav items', async () => { @@ -47,11 +47,11 @@ describe('OrganizationProfile', () => { props.setProps({ customPages }); const { getByText } = render(, { wrapper }); - expect(getByText('Org1')).toBeDefined(); - expect(getByText('Members')).toBeDefined(); - expect(getByText('Settings')).toBeDefined(); - expect(getByText('Custom1')).toBeDefined(); - expect(getByText('ExternalLink')).toBeDefined(); + expect(getByText('Org1')).toBeInTheDocument(); + expect(getByText('Members')).toBeInTheDocument(); + expect(getByText('Settings')).toBeInTheDocument(); + expect(getByText('Custom1')).toBeInTheDocument(); + expect(getByText('ExternalLink')).toBeInTheDocument(); }); it('removes member nav item if user is lacking permissions', async () => { diff --git a/packages/clerk-js/src/ui/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx b/packages/clerk-js/src/ui/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx index 251bf8e0f9..b93ee5d136 100644 --- a/packages/clerk-js/src/ui/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationSwitcher/__tests__/OrganizationSwitcher.test.tsx @@ -1,7 +1,7 @@ import type { MembershipRole } from '@clerk/types'; import { describe } from '@jest/globals'; -import { act, render, runFakeTimers, waitFor } from '../../../../testUtils'; +import { act, render, waitFor } from '../../../../testUtils'; import { bindCreateFixtures } from '../../../utils/test/createFixtures'; import { OrganizationSwitcher } from '../OrganizationSwitcher'; import { @@ -18,8 +18,8 @@ describe('OrganizationSwitcher', () => { f.withOrganizations(); f.withUser({ email_addresses: ['test@clerk.com'] }); }); - const { queryByRole } = await act(() => render(, { wrapper })); - expect(queryByRole('button')).toBeDefined(); + const { getByRole } = await act(() => render(, { wrapper })); + expect(getByRole('button')).toBeInTheDocument(); }); describe('Personal Workspace', () => { @@ -30,7 +30,7 @@ describe('OrganizationSwitcher', () => { }); props.setProps({ hidePersonal: false }); const { getByText } = await act(() => render(, { wrapper })); - expect(getByText('Personal account')).toBeDefined(); + expect(getByText('Personal account')).toBeInTheDocument(); }); it('does not show the personal workspace when disabled', async () => { @@ -42,7 +42,7 @@ describe('OrganizationSwitcher', () => { const { queryByText, getByRole, userEvent, getByText } = render(, { wrapper }); await userEvent.click(getByRole('button')); expect(queryByText('Personal Workspace')).toBeNull(); - expect(getByText('No organization selected')).toBeDefined(); + expect(getByText('No organization selected')).toBeInTheDocument(); }); }); @@ -70,13 +70,8 @@ describe('OrganizationSwitcher', () => { }), ); - await runFakeTimers(async () => { - const { getByText } = render(, { wrapper }); - - await waitFor(() => { - expect(getByText('5')).toBeInTheDocument(); - }); - }); + const { findByText } = render(, { wrapper }); + expect(await findByText('5')).toBeInTheDocument(); }); it('shows the counter for pending suggestions and invitations and membership requests', async () => { @@ -109,14 +104,8 @@ describe('OrganizationSwitcher', () => { total_count: 3, }), ); - - await runFakeTimers(async () => { - const { getByText } = render(, { wrapper }); - - await waitFor(() => { - expect(getByText('7')).toBeInTheDocument(); - }); - }); + const { findByText } = render(, { wrapper }); + expect(await findByText('7')).toBeInTheDocument(); }); }); @@ -130,7 +119,7 @@ describe('OrganizationSwitcher', () => { props.setProps({ hidePersonal: true }); const { getByText, getByRole, userEvent } = render(, { wrapper }); await userEvent.click(getByRole('button')); - expect(getByText('Create Organization')).toBeDefined(); + expect(getByText('Create Organization')).toBeInTheDocument(); }); it('lists all organizations the user belongs to', async () => { @@ -175,8 +164,8 @@ describe('OrganizationSwitcher', () => { const { getAllByText, getByText, getByRole, userEvent } = render(, { wrapper }); await userEvent.click(getByRole('button')); expect(getAllByText('Org1')).not.toBeNull(); - expect(getByText('Personal account')).toBeDefined(); - expect(getByText('Org2')).toBeDefined(); + expect(getByText('Personal account')).toBeInTheDocument(); + expect(getByText('Org2')).toBeInTheDocument(); }); it.each([ @@ -195,8 +184,8 @@ describe('OrganizationSwitcher', () => { props.setProps({ hidePersonal: true }); const { getAllByText, getByText, getByRole, userEvent } = render(, { wrapper }); await userEvent.click(getByRole('button')); - expect(getAllByText('Org1')).not.toBeNull(); - expect(getByText(text)).toBeDefined(); + expect(getAllByText('Org1').length).toBeGreaterThan(0); + expect(getByText(text)).toBeInTheDocument(); }); it('opens organization profile when "Manage Organization" is clicked', async () => { diff --git a/packages/clerk-js/src/ui/elements/__tests__/PlainInput.test.tsx b/packages/clerk-js/src/ui/elements/__tests__/PlainInput.test.tsx index 8020d3e189..2043a9e7bc 100644 --- a/packages/clerk-js/src/ui/elements/__tests__/PlainInput.test.tsx +++ b/packages/clerk-js/src/ui/elements/__tests__/PlainInput.test.tsx @@ -1,5 +1,5 @@ import { describe, it } from '@jest/globals'; -import { act, fireEvent, render, waitFor } from '@testing-library/react'; +import { fireEvent, render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { useFormControl } from '../../utils'; @@ -132,15 +132,15 @@ describe('PlainInput', () => { placeholder: 'some placeholder', }); - const { getByRole, getByLabelText, getByText } = render(, { wrapper }); + const { getByRole, getByLabelText, findByText } = render(, { wrapper }); - await act(() => userEvent.click(getByRole('button', { name: /set error/i }))); + await userEvent.click(getByRole('button', { name: /set error/i })); - await waitFor(() => { - expect(getByLabelText('some label')).toHaveAttribute('aria-invalid', 'true'); - expect(getByLabelText('some label')).toHaveAttribute('aria-describedby', 'error-firstname'); - expect(getByText('some error')).toBeInTheDocument(); - }); + expect(await findByText('some error')).toBeInTheDocument(); + + const label = getByLabelText('some label'); + expect(label).toHaveAttribute('aria-invalid', 'true'); + expect(label).toHaveAttribute('aria-describedby', 'error-firstname'); }); it('with info', async () => { @@ -152,10 +152,9 @@ describe('PlainInput', () => { infoText: 'some info', }); - const { getByLabelText, getByText } = render(, { wrapper }); - await act(() => fireEvent.focus(getByLabelText('some label'))); - await waitFor(() => { - expect(getByText('some info')).toBeInTheDocument(); - }); + const { findByLabelText, findByText } = render(, { wrapper }); + + fireEvent.focus(await findByLabelText('some label')); + expect(await findByText('some info')).toBeInTheDocument(); }); }); diff --git a/packages/clerk-js/src/ui/elements/__tests__/RadioGroup.test.tsx b/packages/clerk-js/src/ui/elements/__tests__/RadioGroup.test.tsx index dd0d8ea76c..5c10111e64 100644 --- a/packages/clerk-js/src/ui/elements/__tests__/RadioGroup.test.tsx +++ b/packages/clerk-js/src/ui/elements/__tests__/RadioGroup.test.tsx @@ -1,5 +1,5 @@ import { describe, it } from '@jest/globals'; -import { act, fireEvent, render, waitFor } from '@testing-library/react'; +import { fireEvent, render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { useFormControl } from '../../utils'; @@ -141,7 +141,7 @@ describe('RadioGroup', () => { const { wrapper } = await createFixtures(); const { Field } = createField('some-radio', 'two'); - const { getAllByRole, getByRole, getByText } = render( + const { getAllByRole, getByRole, findByText } = render( { { wrapper }, ); - await act(() => userEvent.click(getByRole('button', { name: /set error/i }))); + await userEvent.click(getByRole('button', { name: /set error/i })); + expect(await findByText('some error')).toBeInTheDocument(); - await waitFor(() => { - const radios = getAllByRole('radio'); - radios.forEach(radio => { - expect(radio).toHaveAttribute('aria-invalid', 'true'); - expect(radio).toHaveAttribute('aria-describedby', 'error-some-radio'); - }); - expect(getByText('some error')).toBeInTheDocument(); + const radios = getAllByRole('radio'); + radios.forEach(radio => { + expect(radio).toHaveAttribute('aria-invalid', 'true'); + expect(radio).toHaveAttribute('aria-describedby', 'error-some-radio'); }); }); @@ -174,11 +172,9 @@ describe('RadioGroup', () => { infoText: 'some info', }); - const { getByLabelText, getByText } = render(, { wrapper }); + const { findByLabelText, findByText } = render(, { wrapper }); - await act(() => fireEvent.focus(getByLabelText('One'))); - await waitFor(() => { - expect(getByText('some info')).toBeInTheDocument(); - }); + fireEvent.focus(await findByLabelText('One')); + expect(await findByText('some info')).toBeInTheDocument(); }); }); diff --git a/packages/clerk-js/src/ui/hooks/__tests__/useCoreOrganization.test.tsx b/packages/clerk-js/src/ui/hooks/__tests__/useCoreOrganization.test.tsx index d02ef9ef9f..d862e65071 100644 --- a/packages/clerk-js/src/ui/hooks/__tests__/useCoreOrganization.test.tsx +++ b/packages/clerk-js/src/ui/hooks/__tests__/useCoreOrganization.test.tsx @@ -1,7 +1,7 @@ import { useOrganization } from '@clerk/shared/react'; import { describe } from '@jest/globals'; -import { act, bindCreateFixtures, renderHook, waitFor } from '../../../testUtils'; +import { act, renderHook, waitFor } from '../../../testUtils'; import { createFakeDomain, createFakeOrganizationMembershipRequest, @@ -129,23 +129,22 @@ describe('useOrganization', () => { expect(result.current.memberships?.isFetching).toBe(true); expect(result.current.memberships?.count).toBe(0); - await waitFor(() => { - expect(result.current.memberships?.isLoading).toBe(false); - expect(result.current.memberships?.count).toBe(4); - expect(result.current.memberships?.page).toBe(1); - expect(result.current.memberships?.pageCount).toBe(2); - expect(result.current.memberships?.hasNextPage).toBe(true); - expect(result.current.memberships?.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: '1', - }), - expect.objectContaining({ - id: '2', - }), - ]), - ); - }); + await waitFor(() => expect(result.current.memberships?.isLoading).toBe(false)); + + expect(result.current.memberships?.count).toBe(4); + expect(result.current.memberships?.page).toBe(1); + expect(result.current.memberships?.pageCount).toBe(2); + expect(result.current.memberships?.hasNextPage).toBe(true); + expect(result.current.memberships?.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: '1', + }), + expect.objectContaining({ + id: '2', + }), + ]), + ); fixtures.clerk.organization?.getMemberships.mockReturnValue( Promise.resolve({ @@ -179,35 +178,29 @@ describe('useOrganization', () => { }), ); - act(() => { - result.current.memberships?.fetchNext?.(); - }); - - await waitFor(() => { - expect(result.current.memberships?.isLoading).toBe(true); - }); - - await waitFor(() => { - expect(result.current.memberships?.isLoading).toBe(false); - expect(result.current.memberships?.page).toBe(2); - expect(result.current.memberships?.hasNextPage).toBe(false); - expect(result.current.memberships?.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', - }), - expect.not.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + act(() => result.current.memberships?.fetchNext?.()); + + await waitFor(() => expect(result.current.memberships?.isLoading).toBe(true)); + await waitFor(() => expect(result.current.memberships?.isLoading).toBe(false)); + + expect(result.current.memberships?.page).toBe(2); + expect(result.current.memberships?.hasNextPage).toBe(false); + expect(result.current.memberships?.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); }); @@ -243,25 +236,25 @@ describe('useOrganization', () => { expect(result.current.domains?.isFetching).toBe(true); expect(result.current.domains?.count).toBe(0); - await waitFor(() => { - expect(result.current.domains?.isLoading).toBe(false); - expect(result.current.domains?.count).toBe(4); - expect(result.current.domains?.page).toBe(1); - expect(result.current.domains?.pageCount).toBe(2); - expect(result.current.domains?.hasNextPage).toBe(true); - expect(result.current.domains?.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: '1', - name: 'one.dev', - }), - expect.objectContaining({ - id: '2', - name: 'two.dev', - }), - ]), - ); - }); + await waitFor(() => expect(result.current.domains?.isLoading).toBe(false)); + + expect(result.current.domains?.isLoading).toBe(false); + expect(result.current.domains?.count).toBe(4); + expect(result.current.domains?.page).toBe(1); + expect(result.current.domains?.pageCount).toBe(2); + expect(result.current.domains?.hasNextPage).toBe(true); + expect(result.current.domains?.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: '1', + name: 'one.dev', + }), + expect.objectContaining({ + id: '2', + name: 'two.dev', + }), + ]), + ); fixtures.clerk.organization?.getDomains.mockReturnValue( Promise.resolve({ @@ -281,35 +274,29 @@ describe('useOrganization', () => { }), ); - act(() => { - result.current.domains?.fetchNext?.(); - }); - - await waitFor(() => { - expect(result.current.domains?.isLoading).toBe(true); - }); - - await waitFor(() => { - expect(result.current.domains?.isLoading).toBe(false); - expect(result.current.domains?.page).toBe(2); - expect(result.current.domains?.hasNextPage).toBe(false); - expect(result.current.domains?.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', - }), - expect.not.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + act(() => result.current.domains?.fetchNext?.()); + + await waitFor(() => expect(result.current.domains?.isLoading).toBe(true)); + await waitFor(() => expect(result.current.domains?.isLoading).toBe(false)); + + expect(result.current.domains?.page).toBe(2); + expect(result.current.domains?.hasNextPage).toBe(false); + expect(result.current.domains?.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); }); @@ -351,13 +338,13 @@ describe('useOrganization', () => { expect(result.current.membershipRequests?.isFetching).toBe(true); expect(result.current.membershipRequests?.count).toBe(0); - await waitFor(() => { - expect(result.current.membershipRequests?.isLoading).toBe(false); - expect(result.current.membershipRequests?.count).toBe(4); - expect(result.current.membershipRequests?.page).toBe(1); - expect(result.current.membershipRequests?.pageCount).toBe(2); - expect(result.current.membershipRequests?.hasNextPage).toBe(true); - }); + await waitFor(() => expect(result.current.membershipRequests?.isLoading).toBe(false)); + + expect(result.current.membershipRequests?.isFetching).toBe(false); + expect(result.current.membershipRequests?.count).toBe(4); + expect(result.current.membershipRequests?.page).toBe(1); + expect(result.current.membershipRequests?.pageCount).toBe(2); + expect(result.current.membershipRequests?.hasNextPage).toBe(true); fixtures.clerk.organization?.getMembershipRequests.mockReturnValue( Promise.resolve({ @@ -383,43 +370,37 @@ describe('useOrganization', () => { }), ); - act(() => { - result.current.membershipRequests?.fetchNext?.(); - }); - - await waitFor(() => { - expect(result.current.membershipRequests?.isLoading).toBe(true); - }); - - await waitFor(() => { - expect(result.current.membershipRequests?.isLoading).toBe(false); - expect(result.current.membershipRequests?.page).toBe(2); - expect(result.current.membershipRequests?.hasNextPage).toBe(false); - expect(result.current.membershipRequests?.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', + act(() => result.current.membershipRequests?.fetchNext?.()); + + await waitFor(() => expect(result.current.membershipRequests?.isLoading).toBe(true)); + await waitFor(() => expect(result.current.membershipRequests?.isLoading).toBe(false)); + + expect(result.current.membershipRequests?.page).toBe(2); + expect(result.current.membershipRequests?.hasNextPage).toBe(false); + expect(result.current.membershipRequests?.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + organizationId: '1', + id: '3', + publicUserData: expect.objectContaining({ + userId: 'test_user3', }), - expect.not.objectContaining({ - id: '2', + }), + expect.objectContaining({ + organizationId: '1', + id: '4', + publicUserData: expect.objectContaining({ + userId: 'test_user4', }), - expect.objectContaining({ - organizationId: '1', - id: '3', - publicUserData: expect.objectContaining({ - userId: 'test_user3', - }), - }), - expect.objectContaining({ - organizationId: '1', - id: '4', - publicUserData: expect.objectContaining({ - userId: 'test_user4', - }), - }), - ]), - ); - }); + }), + ]), + ); }); }); }); diff --git a/packages/clerk-js/src/ui/hooks/__tests__/useCoreOrganizationList.test.tsx b/packages/clerk-js/src/ui/hooks/__tests__/useCoreOrganizationList.test.tsx index e097b0ed16..1f7a4a4137 100644 --- a/packages/clerk-js/src/ui/hooks/__tests__/useCoreOrganizationList.test.tsx +++ b/packages/clerk-js/src/ui/hooks/__tests__/useCoreOrganizationList.test.tsx @@ -100,13 +100,12 @@ describe('useOrganizationList', () => { expect(result.current.userMemberships.isFetching).toBe(true); expect(result.current.userMemberships.count).toBe(0); - await waitFor(() => { - expect(result.current.userMemberships.isLoading).toBe(false); - expect(result.current.userMemberships.count).toBe(4); - expect(result.current.userMemberships.page).toBe(1); - expect(result.current.userMemberships.pageCount).toBe(2); - expect(result.current.userMemberships.hasNextPage).toBe(true); - }); + await waitFor(() => expect(result.current.userMemberships.isLoading).toBe(false)); + + expect(result.current.userMemberships.count).toBe(4); + expect(result.current.userMemberships.page).toBe(1); + expect(result.current.userMemberships.pageCount).toBe(2); + expect(result.current.userMemberships.hasNextPage).toBe(true); fixtures.clerk.user?.getOrganizationMemberships.mockReturnValue( Promise.resolve({ @@ -140,35 +139,29 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userMemberships.fetchNext?.(); - }); + act(() => result.current.userMemberships?.fetchNext?.()); - await waitFor(() => { - expect(result.current.userMemberships.isLoading).toBe(true); - }); + await waitFor(() => expect(result.current.userMemberships?.isLoading).toBe(true)); + await waitFor(() => expect(result.current.userMemberships?.isLoading).toBe(false)); - await waitFor(() => { - expect(result.current.userMemberships.isLoading).toBe(false); - expect(result.current.userMemberships.page).toBe(2); - expect(result.current.userMemberships.hasNextPage).toBe(false); - expect(result.current.userMemberships.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', - }), - expect.not.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + expect(result.current.userMemberships.page).toBe(2); + expect(result.current.userMemberships.hasNextPage).toBe(false); + expect(result.current.userMemberships.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); it('infinite fetch', async () => { @@ -224,10 +217,8 @@ describe('useOrganizationList', () => { expect(result.current.userMemberships.isLoading).toBe(true); expect(result.current.userMemberships.isFetching).toBe(true); - await waitFor(() => { - expect(result.current.userMemberships.isLoading).toBe(false); - expect(result.current.userMemberships.isFetching).toBe(false); - }); + await waitFor(() => expect(result.current.userMemberships.isLoading).toBe(false)); + expect(result.current.userMemberships.isFetching).toBe(false); fixtures.clerk.user?.getOrganizationMemberships.mockReturnValueOnce( Promise.resolve({ @@ -293,34 +284,28 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userMemberships.fetchNext?.(); - }); + act(() => result.current.userMemberships?.fetchNext?.()); - await waitFor(() => { - expect(result.current.userMemberships.isLoading).toBe(false); - expect(result.current.userMemberships.isFetching).toBe(true); - }); + await waitFor(() => expect(result.current.userMemberships?.isFetching).toBe(true)); + expect(result.current.userMemberships?.isLoading).toBe(false); - await waitFor(() => { - expect(result.current.userMemberships.isFetching).toBe(false); - expect(result.current.userMemberships.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: '1', - }), - expect.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + await waitFor(() => expect(result.current.userMemberships?.isFetching).toBe(false)); + expect(result.current.userMemberships.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: '1', + }), + expect.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); }); @@ -349,18 +334,19 @@ describe('useOrganizationList', () => { total_count: 4, }), ); + const { result } = renderHook(defaultRenderer, { wrapper }); + expect(result.current.userInvitations.isLoading).toBe(true); expect(result.current.userInvitations.isFetching).toBe(true); expect(result.current.userInvitations.count).toBe(0); - await waitFor(() => { - expect(result.current.userInvitations.isLoading).toBe(false); - expect(result.current.userInvitations.count).toBe(4); - expect(result.current.userInvitations.page).toBe(1); - expect(result.current.userInvitations.pageCount).toBe(2); - expect(result.current.userInvitations.hasNextPage).toBe(true); - }); + await waitFor(() => expect(result.current.userInvitations.isLoading).toBe(false)); + + expect(result.current.userInvitations.count).toBe(4); + expect(result.current.userInvitations.page).toBe(1); + expect(result.current.userInvitations.pageCount).toBe(2); + expect(result.current.userInvitations.hasNextPage).toBe(true); fixtures.clerk.user?.getOrganizationInvitations.mockReturnValue( Promise.resolve({ @@ -378,35 +364,29 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userInvitations.fetchNext?.(); - }); + act(() => result.current.userInvitations?.fetchNext?.()); - await waitFor(() => { - expect(result.current.userInvitations.isLoading).toBe(true); - }); + await waitFor(() => expect(result.current.userInvitations?.isLoading).toBe(true)); + await waitFor(() => expect(result.current.userInvitations?.isLoading).toBe(false)); - await waitFor(() => { - expect(result.current.userInvitations.isLoading).toBe(false); - expect(result.current.userInvitations.page).toBe(2); - expect(result.current.userInvitations.hasNextPage).toBe(false); - expect(result.current.userInvitations.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', - }), - expect.not.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + expect(result.current.userInvitations.page).toBe(2); + expect(result.current.userInvitations.hasNextPage).toBe(false); + expect(result.current.userInvitations.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); it('infinite fetch', async () => { @@ -443,13 +423,12 @@ describe('useOrganizationList', () => { }), { wrapper }, ); + expect(result.current.userInvitations.isLoading).toBe(true); expect(result.current.userInvitations.isFetching).toBe(true); - await waitFor(() => { - expect(result.current.userInvitations.isLoading).toBe(false); - expect(result.current.userInvitations.isFetching).toBe(false); - }); + await waitFor(() => expect(result.current.userInvitations.isLoading).toBe(false)); + expect(result.current.userInvitations.isFetching).toBe(false); fixtures.clerk.user?.getOrganizationInvitations.mockReturnValueOnce( Promise.resolve({ @@ -483,34 +462,28 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userInvitations.fetchNext?.(); - }); + act(() => result.current.userInvitations.fetchNext?.()); - await waitFor(() => { - expect(result.current.userInvitations.isLoading).toBe(false); - expect(result.current.userInvitations.isFetching).toBe(true); - }); + await waitFor(() => expect(result.current.userInvitations.isFetching).toBe(true)); + expect(result.current.userInvitations.isLoading).toBe(false); - await waitFor(() => { - expect(result.current.userInvitations.isFetching).toBe(false); - expect(result.current.userInvitations.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: '1', - }), - expect.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + await waitFor(() => expect(result.current.userInvitations.isFetching).toBe(false)); + expect(result.current.userInvitations.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: '1', + }), + expect.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); }); @@ -544,13 +517,12 @@ describe('useOrganizationList', () => { expect(result.current.userSuggestions.isFetching).toBe(true); expect(result.current.userSuggestions.count).toBe(0); - await waitFor(() => { - expect(result.current.userSuggestions.isLoading).toBe(false); - expect(result.current.userSuggestions.count).toBe(4); - expect(result.current.userSuggestions.page).toBe(1); - expect(result.current.userSuggestions.pageCount).toBe(2); - expect(result.current.userSuggestions.hasNextPage).toBe(true); - }); + await waitFor(() => expect(result.current.userSuggestions.isLoading).toBe(false)); + + expect(result.current.userSuggestions.count).toBe(4); + expect(result.current.userSuggestions.page).toBe(1); + expect(result.current.userSuggestions.pageCount).toBe(2); + expect(result.current.userSuggestions.hasNextPage).toBe(true); fixtures.clerk.user?.getOrganizationSuggestions.mockReturnValue( Promise.resolve({ @@ -568,35 +540,29 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userSuggestions.fetchNext?.(); - }); + act(() => result.current.userSuggestions.fetchNext?.()); - await waitFor(() => { - expect(result.current.userSuggestions.isLoading).toBe(true); - }); + await waitFor(() => expect(result.current.userSuggestions.isLoading).toBe(true)); + await waitFor(() => expect(result.current.userSuggestions.isLoading).toBe(false)); - await waitFor(() => { - expect(result.current.userSuggestions.isLoading).toBe(false); - expect(result.current.userSuggestions.page).toBe(2); - expect(result.current.userSuggestions.hasNextPage).toBe(false); - expect(result.current.userSuggestions.data).toEqual( - expect.arrayContaining([ - expect.not.objectContaining({ - id: '1', - }), - expect.not.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + expect(result.current.userSuggestions.page).toBe(2); + expect(result.current.userSuggestions.hasNextPage).toBe(false); + expect(result.current.userSuggestions.data).toEqual( + expect.arrayContaining([ + expect.not.objectContaining({ + id: '1', + }), + expect.not.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); it('infinite fetch', async () => { @@ -636,10 +602,8 @@ describe('useOrganizationList', () => { expect(result.current.userSuggestions.isLoading).toBe(true); expect(result.current.userSuggestions.isFetching).toBe(true); - await waitFor(() => { - expect(result.current.userSuggestions.isLoading).toBe(false); - expect(result.current.userSuggestions.isFetching).toBe(false); - }); + await waitFor(() => expect(result.current.userSuggestions.isLoading).toBe(false)); + expect(result.current.userSuggestions.isFetching).toBe(false); fixtures.clerk.user?.getOrganizationSuggestions.mockReturnValueOnce( Promise.resolve({ @@ -673,34 +637,28 @@ describe('useOrganizationList', () => { }), ); - act(() => { - result.current.userSuggestions.fetchNext?.(); - }); + act(() => result.current.userSuggestions.fetchNext?.()); - await waitFor(() => { - expect(result.current.userSuggestions.isLoading).toBe(false); - expect(result.current.userSuggestions.isFetching).toBe(true); - }); + await waitFor(() => expect(result.current.userSuggestions.isFetching).toBe(true)); + expect(result.current.userSuggestions.isLoading).toBe(false); - await waitFor(() => { - expect(result.current.userSuggestions.isFetching).toBe(false); - expect(result.current.userSuggestions.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - id: '1', - }), - expect.objectContaining({ - id: '2', - }), - expect.objectContaining({ - id: '3', - }), - expect.objectContaining({ - id: '4', - }), - ]), - ); - }); + await waitFor(() => expect(result.current.userSuggestions.isFetching).toBe(false)); + expect(result.current.userSuggestions.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: '1', + }), + expect.objectContaining({ + id: '2', + }), + expect.objectContaining({ + id: '3', + }), + expect.objectContaining({ + id: '4', + }), + ]), + ); }); }); });