diff --git a/packages/core/admin/ee/admin/hooks/useLicenseLimitNotification/index.js b/packages/core/admin/ee/admin/hooks/useLicenseLimitNotification/index.js
index 7768ba4fc7..2fa8786289 100644
--- a/packages/core/admin/ee/admin/hooks/useLicenseLimitNotification/index.js
+++ b/packages/core/admin/ee/admin/hooks/useLicenseLimitNotification/index.js
@@ -19,18 +19,18 @@ const BILLING_SELF_HOSTED_URL = 'https://strapi.io/billing/request-seats';
const useLicenseLimitNotification = () => {
const { formatMessage } = useIntl();
- let { license } = useLicenseLimits();
+ let { license, isError, isLoading } = useLicenseLimits();
const toggleNotification = useNotification();
const { pathname } = useLocation();
+ const { enforcementUserCount, permittedSeats, licenseLimitStatus, isHostedOnStrapiCloud } =
+ license;
+
useEffect(() => {
- if (!license?.data) {
+ if (isError || isLoading) {
return;
}
- const { enforcementUserCount, permittedSeats, licenseLimitStatus, isHostedOnStrapiCloud } =
- license?.data ?? {};
-
const shouldDisplayNotification =
!isNil(permittedSeats) &&
!window.sessionStorage.getItem(`${STORAGE_KEY_PREFIX}-${pathname}`) &&
@@ -84,7 +84,18 @@ const useLicenseLimitNotification = () => {
},
});
}
- }, [toggleNotification, license.data, pathname, formatMessage]);
+ }, [
+ toggleNotification,
+ license,
+ pathname,
+ formatMessage,
+ isLoading,
+ permittedSeats,
+ licenseLimitStatus,
+ enforcementUserCount,
+ isHostedOnStrapiCloud,
+ isError,
+ ]);
};
export default useLicenseLimitNotification;
diff --git a/packages/core/admin/ee/admin/hooks/useLicenseLimitNotification/tests/index.test.js b/packages/core/admin/ee/admin/hooks/useLicenseLimitNotification/tests/index.test.js
index 0570e986aa..c06bfdafc9 100644
--- a/packages/core/admin/ee/admin/hooks/useLicenseLimitNotification/tests/index.test.js
+++ b/packages/core/admin/ee/admin/hooks/useLicenseLimitNotification/tests/index.test.js
@@ -54,9 +54,7 @@ describe('useLicenseLimitNotification', () => {
it('should return if no license info is available', () => {
useLicenseLimits.mockImplementationOnce(() => ({
- license: {
- data: {},
- },
+ license: {},
}));
renderHook(() => useLicenseLimitNotification());
@@ -66,10 +64,8 @@ describe('useLicenseLimitNotification', () => {
it('should not display notification if permittedSeat info is missing', () => {
useLicenseLimits.mockImplementationOnce(() => ({
license: {
- data: {
- ...baseLicenseInfo,
- permittedSeats: undefined,
- },
+ ...baseLicenseInfo,
+ permittedSeats: undefined,
},
}));
@@ -80,10 +76,8 @@ describe('useLicenseLimitNotification', () => {
it('should not display notification if status is not AT_LIMIT or OVER_LIMIT', () => {
useLicenseLimits.mockImplementationOnce(() => ({
license: {
- data: {
- ...baseLicenseInfo,
- licenseLimitStatus: 'SOME_STRING',
- },
+ ...baseLicenseInfo,
+ licenseLimitStatus: 'SOME_STRING',
},
}));
@@ -117,10 +111,8 @@ describe('useLicenseLimitNotification', () => {
it('should display a warning notification when license limit is at limit', () => {
useLicenseLimits.mockImplementationOnce(() => ({
license: {
- data: {
- ...baseLicenseInfo,
- licenseLimitStatus: 'OVER_LIMIT',
- },
+ ...baseLicenseInfo,
+ licenseLimitStatus: 'OVER_LIMIT',
},
}));
@@ -144,10 +136,8 @@ describe('useLicenseLimitNotification', () => {
it('should have cloud billing url if is hosted on strapi cloud', () => {
useLicenseLimits.mockImplementationOnce(() => ({
license: {
- data: {
- ...baseLicenseInfo,
- isHostedOnStrapiCloud: true,
- },
+ ...baseLicenseInfo,
+ isHostedOnStrapiCloud: true,
},
}));
diff --git a/packages/core/admin/ee/admin/hooks/useLicenseLimits/index.js b/packages/core/admin/ee/admin/hooks/useLicenseLimits/index.js
index 9d2a0ff734..0d1a1aaf2f 100644
--- a/packages/core/admin/ee/admin/hooks/useLicenseLimits/index.js
+++ b/packages/core/admin/ee/admin/hooks/useLicenseLimits/index.js
@@ -1,34 +1,3 @@
-import { useFetchClient, useRBAC } from '@strapi/helper-plugin';
-import { useQuery } from 'react-query';
-import { useSelector } from 'react-redux';
-
-import { selectAdminPermissions } from '../../../../admin/src/pages/App/selectors';
-
-const useLicenseLimits = () => {
- const permissions = useSelector(selectAdminPermissions);
- const rbac = useRBAC(permissions.settings.users);
-
- const {
- isLoading: isRBACLoading,
- allowedActions: { canRead, canCreate, canUpdate, canDelete },
- } = rbac;
-
- const isRBACAllowed = canRead && canCreate && canUpdate && canDelete;
-
- const { get } = useFetchClient();
- const fetchLicenseLimitInfo = async () => {
- const {
- data: { data },
- } = await get('/admin/license-limit-information');
-
- return data;
- };
-
- const license = useQuery(['ee', 'license-limit-info'], fetchLicenseLimitInfo, {
- enabled: !isRBACLoading && isRBACAllowed,
- });
-
- return { license };
-};
+import { useLicenseLimits } from './useLicenseLimits';
export default useLicenseLimits;
diff --git a/packages/core/admin/ee/admin/hooks/useLicenseLimits/tests/index.test.js b/packages/core/admin/ee/admin/hooks/useLicenseLimits/tests/index.test.js
index a01fa47b60..09172a416a 100644
--- a/packages/core/admin/ee/admin/hooks/useLicenseLimits/tests/index.test.js
+++ b/packages/core/admin/ee/admin/hooks/useLicenseLimits/tests/index.test.js
@@ -1,19 +1,32 @@
import React from 'react';
import { fixtures } from '@strapi/admin-test-utils';
-import { useFetchClient } from '@strapi/helper-plugin';
-import { renderHook } from '@testing-library/react';
-import { useQuery } from 'react-query';
+import { useRBAC } from '@strapi/helper-plugin';
+import { renderHook, waitFor } from '@testing-library/react';
+import { rest } from 'msw';
+import { setupServer } from 'msw/node';
+import { QueryClient, QueryClientProvider } from 'react-query';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import useLicenseLimits from '..';
+const server = setupServer(
+ ...[
+ rest.get('*/license-limit-information', (req, res, ctx) => {
+ return res(
+ ctx.json({
+ data: {
+ attribute: 1,
+ },
+ })
+ );
+ }),
+ ]
+);
+
jest.mock('@strapi/helper-plugin', () => ({
- // TODO: Replace with msw
- useFetchClient: jest.fn(() => ({
- get: jest.fn(),
- })),
+ ...jest.requireActual('@strapi/helper-plugin'),
useRBAC: jest.fn(() => ({
isLoading: false,
allowedActions: {
@@ -25,55 +38,71 @@ jest.mock('@strapi/helper-plugin', () => ({
})),
}));
-// TODO: Replace with msw
-jest.mock('react-query', () => ({
- useQuery: jest.fn(),
-}));
-
const setup = (...args) =>
renderHook(() => useLicenseLimits(...args), {
wrapper({ children }) {
+ const client = new QueryClient({
+ defaultOptions: {
+ queries: {
+ refetchOnWindowFocus: false,
+ },
+ },
+ });
+
return (
state, {
admin_app: { permissions: fixtures.permissions.app },
})}
>
- {children}
+ {children}
);
},
});
describe('useLicenseLimits', () => {
+ beforeAll(() => server.listen());
+
+ afterEach(() => {
+ server.resetHandlers();
+ jest.clearAllMocks();
+ });
+
it('should fetch the license limit information', async () => {
- const data = { data: { id: 1, name: 'Test License' } };
- useQuery.mockReturnValue({
- data: { id: 1, name: 'Test License' },
- isLoading: false,
- });
-
const { result } = setup();
- expect(useFetchClient).toHaveBeenCalled();
- expect(useQuery).toHaveBeenCalledWith(['ee', 'license-limit-info'], expect.any(Function), {
- enabled: true,
+ expect(result.current.license).toEqual({});
+
+ await waitFor(() => expect(result.current.isLoading).toBeFalsy());
+
+ expect(result.current.license).toEqual({
+ attribute: 1,
});
- expect(result.current.license.data).toEqual(data.data);
});
- it('data should be undefined if there is an API error', async () => {
- // const data = { data: { id: 1, name: 'Test License' } };
- useQuery.mockReturnValue({
- isError: true,
- });
+ it.each(['canRead', 'canCreate', 'canUpdate', 'canDelete'])(
+ 'should not fetch the license limit information, when the user does not have the %s permissions',
+ async (permission) => {
+ const allowedActions = {
+ canRead: true,
+ canCreate: true,
+ canUpdate: true,
+ canDelete: true,
+ };
- const { result } = setup();
+ allowedActions[permission] = false;
- expect(useFetchClient).toHaveBeenCalled();
- expect(useQuery).toHaveBeenCalledWith(['ee', 'license-limit-info'], expect.any(Function), {
- enabled: true,
- });
- expect(result.current.license.data).toEqual(undefined);
- });
+ useRBAC.mockReturnValue({
+ isLoading: false,
+ allowedActions,
+ });
+
+ const { result } = setup();
+
+ await waitFor(() => expect(result.current.isLoading).toBeFalsy());
+
+ expect(result.current.license).toEqual({});
+ }
+ );
});
diff --git a/packages/core/admin/ee/admin/hooks/useLicenseLimits/useLicenseLimits.js b/packages/core/admin/ee/admin/hooks/useLicenseLimits/useLicenseLimits.js
new file mode 100644
index 0000000000..ae6b705936
--- /dev/null
+++ b/packages/core/admin/ee/admin/hooks/useLicenseLimits/useLicenseLimits.js
@@ -0,0 +1,31 @@
+import { useFetchClient, useRBAC } from '@strapi/helper-plugin';
+import { useQuery } from 'react-query';
+import { useSelector } from 'react-redux';
+
+import { selectAdminPermissions } from '../../../../admin/src/pages/App/selectors';
+
+export function useLicenseLimits() {
+ const permissions = useSelector(selectAdminPermissions);
+ const { get } = useFetchClient();
+ const {
+ isLoading: isRBACLoading,
+ allowedActions: { canRead, canCreate, canUpdate, canDelete },
+ } = useRBAC(permissions.settings.users);
+ const hasPermissions = canRead && canCreate && canUpdate && canDelete;
+
+ const { data, isError, isLoading } = useQuery(
+ ['ee', 'license-limit-info'],
+ async () => {
+ const {
+ data: { data },
+ } = await get('/admin/license-limit-information');
+
+ return data;
+ },
+ {
+ enabled: !isRBACLoading && hasPermissions,
+ }
+ );
+
+ return { license: data ?? {}, isError, isLoading };
+}
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js
index 019acddc83..08a1cd3f63 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/ApplicationInfosPage/components/AdminSeatInfo/index.js
@@ -13,11 +13,13 @@ const BILLING_SELF_HOSTED_URL = 'https://strapi.io/billing/request-seats';
const AdminSeatInfo = () => {
const { formatMessage } = useIntl();
- const { license } = useLicenseLimits();
- const { licenseLimitStatus, enforcementUserCount, permittedSeats, isHostedOnStrapiCloud } =
- license?.data ?? {};
+ const {
+ license: { licenseLimitStatus, enforcementUserCount, permittedSeats, isHostedOnStrapiCloud },
+ isError,
+ isLoading,
+ } = useLicenseLimits();
- if (!permittedSeats) {
+ if (isError || isLoading) {
return null;
}
diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js
index 0ab9df51d5..ff701c16cf 100644
--- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js
+++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js
@@ -10,8 +10,15 @@ import { useLicenseLimits } from '../../../../../../hooks';
const CreateAction = ({ onClick }) => {
const { formatMessage } = useIntl();
- const { license } = useLicenseLimits();
- const { permittedSeats, shouldStopCreate } = license?.data ?? {};
+ const {
+ license: { permittedSeats, shouldStopCreate },
+ isError,
+ isLoading,
+ } = useLicenseLimits();
+
+ if (isError || isLoading) {
+ return null;
+ }
return (