Skip to content

Commit

Permalink
fix(shared): Invitations depends on wrong options (useOrganization) (#…
Browse files Browse the repository at this point in the history
…2472) (#2481)

* fix(shared): Invitations depends on wrong options (useOrganization) (#2472)

* fix(shared): Invitations depends on wrong options (useOrganization)

* fix(shared): Invitations is depending on wrong options

* test(clerk-js): Add unit test

* chore(clerk-js): Update changeset

(cherry picked from commit 38d8b3e)

* fix(clerk-js): Use useCoreOrganization

---------

Co-authored-by: panteliselef <panteliselef@outlook.com>
  • Loading branch information
clerk-cookie and panteliselef committed Jan 4, 2024
1 parent 58094ca commit 65332d7
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/thirty-cooks-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/shared': patch
---

Fixes a bug where Invitations from `useOrganization` incorrectly depended on options for memberships.
204 changes: 204 additions & 0 deletions packages/clerk-js/src/ui/hooks/__tests__/useCoreOrganization.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { describe } from '@jest/globals';
import { act, bindCreateFixtures, renderHook, waitFor } from '../../../testUtils';
import {
createFakeDomain,
createFakeOrganizationInvitation,
createFakeOrganizationMembershipRequest,
} from '../../components/OrganizationProfile/__tests__/utils';
import { createFakeUserOrganizationMembership } from '../../components/OrganizationSwitcher/__tests__/utlis';
Expand All @@ -15,6 +16,9 @@ const defaultRenderer = () =>
domains: {
pageSize: 2,
},
invitations: {
pageSize: 2,
},
membershipRequests: {
pageSize: 2,
},
Expand Down Expand Up @@ -427,4 +431,204 @@ describe('useOrganization', () => {
});
});
});

describe('invitations', () => {
it('fetch with pages', async () => {
const { wrapper, fixtures } = await createFixtures(f => {
f.withOrganizations();
f.withUser({
email_addresses: ['test@clerk.com'],
organization_memberships: [{ name: 'Org1', role: 'basic_member' }],
});
});

fixtures.clerk.organization?.getInvitations.mockReturnValue(
Promise.resolve({
data: [
createFakeOrganizationInvitation({
id: '1',
emailAddress: 'admin1@clerk.com',
organizationId: '1',
createdAt: new Date('2022-01-01'),
}),
createFakeOrganizationInvitation({
id: '2',
emailAddress: 'member2@clerk.com',
organizationId: '1',
createdAt: new Date('2022-01-01'),
}),
],
total_count: 4,
}),
);
const { result } = renderHook(defaultRenderer, { wrapper });
expect(result.current.invitations?.isLoading).toBe(true);
expect(result.current.invitations?.isFetching).toBe(true);
expect(result.current.invitations?.count).toBe(0);

await waitFor(() => expect(result.current.invitations?.isLoading).toBe(false));

expect(result.current.invitations?.isFetching).toBe(false);
expect(result.current.invitations?.count).toBe(4);
expect(result.current.invitations?.page).toBe(1);
expect(result.current.invitations?.pageCount).toBe(2);
expect(result.current.invitations?.hasNextPage).toBe(true);

fixtures.clerk.organization?.getInvitations.mockReturnValue(
Promise.resolve({
data: [
createFakeOrganizationInvitation({
id: '3',
emailAddress: 'admin3@clerk.com',
organizationId: '1',
createdAt: new Date('2022-01-01'),
}),
createFakeOrganizationInvitation({
id: '4',
emailAddress: 'member4@clerk.com',
organizationId: '1',
createdAt: new Date('2022-01-01'),
}),
],
total_count: 4,
}),
);

act(() => result.current.invitations?.fetchNext?.());

await waitFor(() => expect(result.current.invitations?.isLoading).toBe(true));
await waitFor(() => expect(result.current.invitations?.isLoading).toBe(false));

expect(result.current.invitations?.page).toBe(2);
expect(result.current.invitations?.hasNextPage).toBe(false);
expect(result.current.invitations?.data).toEqual(
expect.arrayContaining([
expect.not.objectContaining({
id: '1',
}),
expect.not.objectContaining({
id: '2',
}),
expect.objectContaining({
organizationId: '1',
id: '3',
emailAddress: 'admin3@clerk.com',
}),
expect.objectContaining({
organizationId: '1',
id: '4',
emailAddress: 'member4@clerk.com',
}),
]),
);
});

it('infinite fetch', async () => {
const { wrapper, fixtures } = await createFixtures(f => {
f.withOrganizations();
f.withUser({
email_addresses: ['test@clerk.com'],
organization_memberships: [{ name: 'Org1', role: 'basic_member' }],
});
});

fixtures.clerk.organization?.getInvitations.mockReturnValueOnce(
Promise.resolve({
data: [
createFakeOrganizationInvitation({
id: '1',
emailAddress: 'admin1@clerk.com',
organizationId: '1',
createdAt: new Date('2022-01-01'),
}),
createFakeOrganizationInvitation({
id: '2',
emailAddress: 'member2@clerk.com',
organizationId: '1',
createdAt: new Date('2022-01-01'),
}),
],
total_count: 4,
}),
);
const { result } = renderHook(
() =>
useCoreOrganization({
invitations: {
pageSize: 2,
infinite: true,
},
}),
{ wrapper },
);
expect(result.current.invitations?.isLoading).toBe(true);
expect(result.current.invitations?.isFetching).toBe(true);

await waitFor(() => expect(result.current.invitations?.isLoading).toBe(false));
expect(result.current.invitations?.isFetching).toBe(false);

fixtures.clerk.organization?.getInvitations.mockReturnValueOnce(
Promise.resolve({
data: [
createFakeOrganizationInvitation({
id: '1',
emailAddress: 'admin1@clerk.com',
organizationId: '1',
createdAt: new Date('2022-01-01'),
}),
createFakeOrganizationInvitation({
id: '2',
emailAddress: 'member2@clerk.com',
organizationId: '1',
createdAt: new Date('2022-01-01'),
}),
],
total_count: 4,
}),
);

fixtures.clerk.organization?.getInvitations.mockReturnValueOnce(
Promise.resolve({
data: [
createFakeOrganizationInvitation({
id: '3',
emailAddress: 'admin3@clerk.com',
organizationId: '1',
createdAt: new Date('2022-01-01'),
}),
createFakeOrganizationInvitation({
id: '4',
emailAddress: 'member4@clerk.com',
organizationId: '1',
createdAt: new Date('2022-01-01'),
}),
],
total_count: 4,
}),
);

act(() => result.current.invitations?.fetchNext?.());

await waitFor(() => expect(result.current.invitations?.isFetching).toBe(true));
expect(result.current.invitations?.isLoading).toBe(false);

await waitFor(() => expect(result.current.invitations?.isFetching).toBe(false));
expect(result.current.invitations?.data).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: '1',
}),
expect.objectContaining({
id: '2',
}),
expect.objectContaining({
id: '3',
}),
expect.objectContaining({
id: '4',
}),
]),
);
});
});
});
4 changes: 2 additions & 2 deletions packages/shared/src/react/hooks/useOrganization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ export const useOrganization: UseOrganization = params => {
},
organization?.getInvitations,
{
keepPreviousData: membersSafeValues.keepPreviousData,
infinite: membersSafeValues.infinite,
keepPreviousData: invitationsSafeValues.keepPreviousData,
infinite: invitationsSafeValues.infinite,
enabled: !!invitationsParams,
},
{
Expand Down

0 comments on commit 65332d7

Please sign in to comment.