From bc6034cf841f8cfb048751ea26efcff64903bd48 Mon Sep 17 00:00:00 2001 From: Josh <37798644+joshuaellis@users.noreply.github.com> Date: Mon, 19 Jun 2023 10:22:38 +0100 Subject: [PATCH] chore: remove history & clean up some U&P tests (#16992) --- .../Permissions/PermissionRow/SubCategory.js | 22 +- .../admin/src/hooks/index.js | 4 +- .../admin/src/hooks/usePlugins.js | 71 + .../admin/src/hooks/usePlugins/index.js | 70 - .../admin/src/hooks/usePlugins/init.js | 5 - .../admin/src/hooks/usePlugins/reducer.js | 34 - .../src/hooks/usePlugins/tests/init.test.js | 32 - .../hooks/usePlugins/tests/reducer.test.js | 96 -- .../AdvancedSettings/tests/index.test.js | 9 - .../AdvancedSettings/tests/utils/server.js | 26 - .../pages/EmailTemplates/tests/index.test.js | 9 - .../EmailTemplates/tests/utils/server.js | 41 - .../src/pages/Providers/tests/index.test.js | 8 - .../admin/src/pages/Providers/tests/server.js | 26 - .../{CreatePage/index.js => CreatePage.js} | 16 +- .../Roles/CreatePage/tests/index.test.js | 1059 -------------- .../pages/Roles/CreatePage/tests/server.js | 65 - .../Roles/{EditPage/index.js => EditPage.js} | 34 +- .../pages/Roles/EditPage/tests/index.test.js | 1221 ----------------- .../src/pages/Roles/EditPage/tests/server.js | 95 -- .../src/pages/Roles/EditPage/utils/schema.js | 9 - .../pages/Roles/ListPage/tests/index.test.js | 763 +--------- .../src/pages/Roles/ListPage/tests/server.js | 33 - .../src/pages/Roles/ListPage/utils/api.js | 2 +- .../index.js => ProtectedCreatePage.js} | 5 +- .../index.js => ProtectedEditPage.js} | 5 +- .../index.js => ProtectedListPage.js} | 5 +- .../utils/schema.js => constants.js} | 4 +- .../src/pages/Roles/tests/CreatePage.test.js | 108 ++ .../src/pages/Roles/tests/EditPage.test.js | 155 +++ .../users-permissions/jest.config.front.js | 1 + .../plugins/users-permissions/package.json | 1 - .../plugins/users-permissions/tests/server.js | 191 +++ .../plugins/users-permissions/tests/setup.js | 15 + yarn.lock | 1 - 35 files changed, 671 insertions(+), 3570 deletions(-) create mode 100644 packages/plugins/users-permissions/admin/src/hooks/usePlugins.js delete mode 100644 packages/plugins/users-permissions/admin/src/hooks/usePlugins/index.js delete mode 100644 packages/plugins/users-permissions/admin/src/hooks/usePlugins/init.js delete mode 100644 packages/plugins/users-permissions/admin/src/hooks/usePlugins/reducer.js delete mode 100644 packages/plugins/users-permissions/admin/src/hooks/usePlugins/tests/init.test.js delete mode 100644 packages/plugins/users-permissions/admin/src/hooks/usePlugins/tests/reducer.test.js delete mode 100644 packages/plugins/users-permissions/admin/src/pages/AdvancedSettings/tests/utils/server.js delete mode 100644 packages/plugins/users-permissions/admin/src/pages/EmailTemplates/tests/utils/server.js delete mode 100644 packages/plugins/users-permissions/admin/src/pages/Providers/tests/server.js rename packages/plugins/users-permissions/admin/src/pages/Roles/{CreatePage/index.js => CreatePage.js} (94%) delete mode 100644 packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/tests/index.test.js delete mode 100644 packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/tests/server.js rename packages/plugins/users-permissions/admin/src/pages/Roles/{EditPage/index.js => EditPage.js} (95%) delete mode 100644 packages/plugins/users-permissions/admin/src/pages/Roles/EditPage/tests/index.test.js delete mode 100644 packages/plugins/users-permissions/admin/src/pages/Roles/EditPage/tests/server.js delete mode 100644 packages/plugins/users-permissions/admin/src/pages/Roles/EditPage/utils/schema.js delete mode 100644 packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/server.js rename packages/plugins/users-permissions/admin/src/pages/Roles/{ProtectedCreatePage/index.js => ProtectedCreatePage.js} (74%) rename packages/plugins/users-permissions/admin/src/pages/Roles/{ProtectedEditPage/index.js => ProtectedEditPage.js} (75%) rename packages/plugins/users-permissions/admin/src/pages/Roles/{ProtectedListPage/index.js => ProtectedListPage.js} (76%) rename packages/plugins/users-permissions/admin/src/pages/Roles/{CreatePage/utils/schema.js => constants.js} (78%) create mode 100644 packages/plugins/users-permissions/admin/src/pages/Roles/tests/CreatePage.test.js create mode 100644 packages/plugins/users-permissions/admin/src/pages/Roles/tests/EditPage.test.js create mode 100644 packages/plugins/users-permissions/tests/server.js create mode 100644 packages/plugins/users-permissions/tests/setup.js diff --git a/packages/plugins/users-permissions/admin/src/components/Permissions/PermissionRow/SubCategory.js b/packages/plugins/users-permissions/admin/src/components/Permissions/PermissionRow/SubCategory.js index 924883932d..a9a91bdffc 100644 --- a/packages/plugins/users-permissions/admin/src/components/Permissions/PermissionRow/SubCategory.js +++ b/packages/plugins/users-permissions/admin/src/components/Permissions/PermissionRow/SubCategory.js @@ -1,6 +1,14 @@ import React, { useCallback, useMemo } from 'react'; -import { Box, Checkbox, Flex, Grid, GridItem, Typography } from '@strapi/design-system'; +import { + Box, + Checkbox, + Flex, + Typography, + Grid, + GridItem, + VisuallyHidden, +} from '@strapi/design-system'; import { Cog as CogIcon } from '@strapi/icons'; import get from 'lodash/get'; import PropTypes from 'prop-types'; @@ -90,10 +98,20 @@ const SubCategory = ({ subCategory }) => { diff --git a/packages/plugins/users-permissions/admin/src/hooks/index.js b/packages/plugins/users-permissions/admin/src/hooks/index.js index 3b6a597d15..9988733f3f 100644 --- a/packages/plugins/users-permissions/admin/src/hooks/index.js +++ b/packages/plugins/users-permissions/admin/src/hooks/index.js @@ -1,5 +1,5 @@ // eslint-disable-next-line import/prefer-default-export -export { default as useFetchRole } from './useFetchRole'; export { default as useForm } from './useForm'; -export { default as usePlugins } from './usePlugins'; export { default as useRolesList } from './useRolesList'; +export * from './usePlugins'; +export { default as useFetchRole } from './useFetchRole'; diff --git a/packages/plugins/users-permissions/admin/src/hooks/usePlugins.js b/packages/plugins/users-permissions/admin/src/hooks/usePlugins.js new file mode 100644 index 0000000000..ce1f0e8d23 --- /dev/null +++ b/packages/plugins/users-permissions/admin/src/hooks/usePlugins.js @@ -0,0 +1,71 @@ +import { useEffect } from 'react'; + +import { useNotification, useFetchClient, useAPIErrorHandler } from '@strapi/helper-plugin'; +import { useQueries } from 'react-query'; + +import pluginId from '../pluginId'; +import { cleanPermissions, getTrad } from '../utils'; + +export const usePlugins = () => { + const toggleNotification = useNotification(); + const { get } = useFetchClient(); + const { formatAPIError } = useAPIErrorHandler(getTrad); + + const [ + { + data: permissions, + isLoading: isLoadingPermissions, + error: permissionsError, + refetch: refetchPermissions, + }, + { data: routes, isLoading: isLoadingRoutes, error: routesError, refetch: refetchRoutes }, + ] = useQueries([ + { + queryKey: [pluginId, 'permissions'], + async queryFn() { + const res = await get(`/${pluginId}/permissions`); + + return res.data.permissions; + }, + }, + { + queryKey: [pluginId, 'routes'], + async queryFn() { + const res = await get(`/${pluginId}/routes`); + + return res.data.routes; + }, + }, + ]); + + const refetchQueries = async () => { + await Promise.all([refetchPermissions(), refetchRoutes()]); + }; + + useEffect(() => { + if (permissionsError) { + toggleNotification({ + type: 'warning', + message: formatAPIError(permissionsError), + }); + } + }, [toggleNotification, permissionsError, formatAPIError]); + + useEffect(() => { + if (routesError) { + toggleNotification({ + type: 'warning', + message: formatAPIError(routesError), + }); + } + }, [toggleNotification, routesError, formatAPIError]); + + const isLoading = isLoadingPermissions || isLoadingRoutes; + + return { + permissions: permissions ? cleanPermissions(permissions) : {}, + routes: routes ?? {}, + getData: refetchQueries, + isLoading, + }; +}; diff --git a/packages/plugins/users-permissions/admin/src/hooks/usePlugins/index.js b/packages/plugins/users-permissions/admin/src/hooks/usePlugins/index.js deleted file mode 100644 index d1abd28af5..0000000000 --- a/packages/plugins/users-permissions/admin/src/hooks/usePlugins/index.js +++ /dev/null @@ -1,70 +0,0 @@ -import { useCallback, useEffect, useReducer } from 'react'; - -import { useFetchClient, useNotification } from '@strapi/helper-plugin'; -import get from 'lodash/get'; - -import pluginId from '../../pluginId'; -import { cleanPermissions } from '../../utils'; - -import init from './init'; -import reducer, { initialState } from './reducer'; - -const usePlugins = (shouldFetchData = true) => { - const toggleNotification = useNotification(); - const [{ permissions, routes, isLoading }, dispatch] = useReducer(reducer, initialState, () => - init(initialState, shouldFetchData) - ); - const fetchClient = useFetchClient(); - - const fetchPlugins = useCallback(async () => { - try { - dispatch({ - type: 'GET_DATA', - }); - - const [{ permissions }, { routes }] = await Promise.all( - [`/${pluginId}/permissions`, `/${pluginId}/routes`].map(async (endpoint) => { - const res = await fetchClient.get(endpoint); - - return res.data; - }) - ); - - dispatch({ - type: 'GET_DATA_SUCCEEDED', - permissions: cleanPermissions(permissions), - routes, - }); - } catch (err) { - const message = get(err, ['response', 'payload', 'message'], 'An error occured'); - - dispatch({ - type: 'GET_DATA_ERROR', - }); - - if (message !== 'Forbidden') { - toggleNotification({ - type: 'warning', - message, - }); - } - } - - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [toggleNotification]); - - useEffect(() => { - if (shouldFetchData) { - fetchPlugins(); - } - }, [fetchPlugins, shouldFetchData]); - - return { - permissions, - routes, - getData: fetchPlugins, - isLoading, - }; -}; - -export default usePlugins; diff --git a/packages/plugins/users-permissions/admin/src/hooks/usePlugins/init.js b/packages/plugins/users-permissions/admin/src/hooks/usePlugins/init.js deleted file mode 100644 index dfe71d9376..0000000000 --- a/packages/plugins/users-permissions/admin/src/hooks/usePlugins/init.js +++ /dev/null @@ -1,5 +0,0 @@ -const init = (initialState, shouldFetchData) => { - return { ...initialState, isLoading: shouldFetchData }; -}; - -export default init; diff --git a/packages/plugins/users-permissions/admin/src/hooks/usePlugins/reducer.js b/packages/plugins/users-permissions/admin/src/hooks/usePlugins/reducer.js deleted file mode 100644 index 8a19db2dd2..0000000000 --- a/packages/plugins/users-permissions/admin/src/hooks/usePlugins/reducer.js +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable consistent-return */ -import produce from 'immer'; - -export const initialState = { - permissions: {}, - routes: {}, - isLoading: true, -}; - -const reducer = (state, action) => - produce(state, (draftState) => { - switch (action.type) { - case 'GET_DATA': { - draftState.isLoading = true; - draftState.permissions = {}; - draftState.routes = {}; - break; - } - case 'GET_DATA_SUCCEEDED': { - draftState.permissions = action.permissions; - draftState.routes = action.routes; - draftState.isLoading = false; - break; - } - case 'GET_DATA_ERROR': { - draftState.isLoading = false; - break; - } - default: - return draftState; - } - }); - -export default reducer; diff --git a/packages/plugins/users-permissions/admin/src/hooks/usePlugins/tests/init.test.js b/packages/plugins/users-permissions/admin/src/hooks/usePlugins/tests/init.test.js deleted file mode 100644 index 9900a6bcb3..0000000000 --- a/packages/plugins/users-permissions/admin/src/hooks/usePlugins/tests/init.test.js +++ /dev/null @@ -1,32 +0,0 @@ -import init from '../init'; - -describe('USERS PERMISSIONS | HOOKS | usePlugins | init', () => { - it('should return the initial state and set the isLoading key to true', () => { - const initialState = { - ok: true, - }; - - const expected = { - ok: true, - isLoading: true, - }; - - expect(init(initialState, true)).toEqual(expected); - }); - - it('should return the initial state and set the isLoading key to false', () => { - const initialState = { - permissions: {}, - routes: {}, - isLoading: null, - }; - - const expected = { - permissions: {}, - routes: {}, - isLoading: false, - }; - - expect(init(initialState, false)).toEqual(expected); - }); -}); diff --git a/packages/plugins/users-permissions/admin/src/hooks/usePlugins/tests/reducer.test.js b/packages/plugins/users-permissions/admin/src/hooks/usePlugins/tests/reducer.test.js deleted file mode 100644 index c9e62e2942..0000000000 --- a/packages/plugins/users-permissions/admin/src/hooks/usePlugins/tests/reducer.test.js +++ /dev/null @@ -1,96 +0,0 @@ -import reducer from '../reducer'; - -describe('USERS PERMISSIONS | HOOKS | usePlugins | reducer', () => { - describe('DEFAULT_ACTION', () => { - it('should return the initialState', () => { - const state = { - test: true, - }; - - expect(reducer(state, {})).toEqual(state); - }); - }); - - describe('GET_DATA', () => { - it('should set the isLoading key to true', () => { - const state = { - permissions: { ok: true }, - routes: { ok: true }, - isLoading: false, - }; - - const action = { - type: 'GET_DATA', - }; - - const expected = { - permissions: {}, - routes: {}, - isLoading: true, - }; - - expect(reducer(state, action)).toEqual(expected); - }); - }); - - describe('GET_DATA_ERROR', () => { - it('should set isLoading to false is an error occured', () => { - const action = { - type: 'GET_DATA_ERROR', - }; - const initialState = { - permissions: {}, - routes: {}, - isLoading: true, - }; - const expected = { - permissions: {}, - routes: {}, - isLoading: false, - }; - - expect(reducer(initialState, action)).toEqual(expected); - }); - }); - - describe('GET_DATA_SUCCEEDED', () => { - it('should return the state with the permissions list', () => { - const action = { - type: 'GET_DATA_SUCCEEDED', - permissions: { - application: { - controllers: { - address: { - count: { enabled: false }, - }, - }, - }, - }, - routes: { - application: [{ method: 'GET', path: '/addresses' }], - }, - }; - const initialState = { - permissions: {}, - isLoading: true, - }; - const expected = { - permissions: { - application: { - controllers: { - address: { - count: { enabled: false }, - }, - }, - }, - }, - routes: { - application: [{ method: 'GET', path: '/addresses' }], - }, - isLoading: false, - }; - - expect(reducer(initialState, action)).toEqual(expected); - }); - }); -}); diff --git a/packages/plugins/users-permissions/admin/src/pages/AdvancedSettings/tests/index.test.js b/packages/plugins/users-permissions/admin/src/pages/AdvancedSettings/tests/index.test.js index db3cf66616..5b487fb47b 100644 --- a/packages/plugins/users-permissions/admin/src/pages/AdvancedSettings/tests/index.test.js +++ b/packages/plugins/users-permissions/admin/src/pages/AdvancedSettings/tests/index.test.js @@ -8,8 +8,6 @@ import { QueryClient, QueryClientProvider } from 'react-query'; import ProtectedAdvancedSettingsPage from '../index'; -import server from './utils/server'; - jest.mock('@strapi/helper-plugin', () => ({ ...jest.requireActual('@strapi/helper-plugin'), useNotification: jest.fn(), @@ -38,19 +36,12 @@ const App = ( ); describe('ADMIN | Pages | Settings | Advanced Settings', () => { - beforeAll(() => server.listen()); - beforeEach(() => { jest.clearAllMocks(); }); - afterEach(() => { - server.resetHandlers(); - }); - afterAll(() => { jest.resetAllMocks(); - server.close(); }); it('renders and matches the snapshot', async () => { diff --git a/packages/plugins/users-permissions/admin/src/pages/AdvancedSettings/tests/utils/server.js b/packages/plugins/users-permissions/admin/src/pages/AdvancedSettings/tests/utils/server.js deleted file mode 100644 index 644d99cfce..0000000000 --- a/packages/plugins/users-permissions/admin/src/pages/AdvancedSettings/tests/utils/server.js +++ /dev/null @@ -1,26 +0,0 @@ -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; - -const handlers = [ - rest.get('*/advanced', (req, res, ctx) => { - return res( - ctx.delay(100), - ctx.status(200), - ctx.json({ - roles: [{ name: 'Authenticated', type: 'authenticated' }], - settings: { - allow_register: false, - default_role: 'authenticated', - email_confirmation: false, - email_confirmation_redirection: '', - email_reset_password: 'https://cat-bounce.com/', - unique_email: false, - }, - }) - ); - }), -]; - -const server = setupServer(...handlers); - -export default server; diff --git a/packages/plugins/users-permissions/admin/src/pages/EmailTemplates/tests/index.test.js b/packages/plugins/users-permissions/admin/src/pages/EmailTemplates/tests/index.test.js index 4568143899..49af90dcc3 100644 --- a/packages/plugins/users-permissions/admin/src/pages/EmailTemplates/tests/index.test.js +++ b/packages/plugins/users-permissions/admin/src/pages/EmailTemplates/tests/index.test.js @@ -8,8 +8,6 @@ import { QueryClient, QueryClientProvider } from 'react-query'; import ProtectedEmailTemplatesPage from '../index'; -import server from './utils/server'; - jest.mock('@strapi/helper-plugin', () => ({ ...jest.requireActual('@strapi/helper-plugin'), useNotification: jest.fn(), @@ -38,19 +36,12 @@ const App = ( ); describe('ADMIN | Pages | Settings | Email Templates', () => { - beforeAll(() => server.listen()); - beforeEach(() => { jest.clearAllMocks(); }); - afterEach(() => { - server.resetHandlers(); - }); - afterAll(() => { jest.resetAllMocks(); - server.close(); }); it('renders and matches the snapshot', async () => { diff --git a/packages/plugins/users-permissions/admin/src/pages/EmailTemplates/tests/utils/server.js b/packages/plugins/users-permissions/admin/src/pages/EmailTemplates/tests/utils/server.js deleted file mode 100644 index e01d131332..0000000000 --- a/packages/plugins/users-permissions/admin/src/pages/EmailTemplates/tests/utils/server.js +++ /dev/null @@ -1,41 +0,0 @@ -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; - -const handlers = [ - rest.get('*/email-templates', (req, res, ctx) => { - return res( - ctx.delay(100), - ctx.status(200), - ctx.json({ - email_confirmation: { - display: 'Email.template.email_confirmation', - options: { - from: { - email: 'mochoko@strapi.io', - name: 'Administration Panel', - }, - message: 'Thank you for registering. Please click on the link below.', - object: 'Account confirmation', - response_email: '', - }, - }, - reset_password: { - display: 'Email.template.reset_password', - options: { - from: { - email: 'mochoko@strapi.io', - name: 'Administration Panel', - }, - message: 'We heard that you lost your password. Sorry about that!', - object: 'Reset password', - response_email: '', - }, - }, - }) - ); - }), -]; - -const server = setupServer(...handlers); - -export default server; diff --git a/packages/plugins/users-permissions/admin/src/pages/Providers/tests/index.test.js b/packages/plugins/users-permissions/admin/src/pages/Providers/tests/index.test.js index 549b297511..a63aee292d 100644 --- a/packages/plugins/users-permissions/admin/src/pages/Providers/tests/index.test.js +++ b/packages/plugins/users-permissions/admin/src/pages/Providers/tests/index.test.js @@ -8,8 +8,6 @@ import { QueryClient, QueryClientProvider } from 'react-query'; import { ProvidersPage } from '../index'; -import server from './server'; - jest.mock('@strapi/helper-plugin', () => ({ ...jest.requireActual('@strapi/helper-plugin'), useNotification: jest.fn(), @@ -36,16 +34,10 @@ const App = ( ); describe('Admin | containers | ProvidersPage', () => { - beforeAll(() => server.listen()); - beforeEach(() => { jest.clearAllMocks(); }); - afterEach(() => server.resetHandlers()); - - afterAll(() => server.close()); - it('renders and matches the snapshot', () => { useRBAC.mockImplementation(() => ({ isLoading: true, diff --git a/packages/plugins/users-permissions/admin/src/pages/Providers/tests/server.js b/packages/plugins/users-permissions/admin/src/pages/Providers/tests/server.js deleted file mode 100644 index 16125084e6..0000000000 --- a/packages/plugins/users-permissions/admin/src/pages/Providers/tests/server.js +++ /dev/null @@ -1,26 +0,0 @@ -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; - -const handlers = [ - rest.get('*/providers', (req, res, ctx) => { - return res( - ctx.delay(1000), - ctx.status(200), - ctx.json({ - email: { enabled: true, icon: 'envelope' }, - discord: { - callback: '/auth/discord/callback', - enabled: false, - icon: 'discord', - key: '', - scope: ['identify', 'email'], - secret: '', - }, - }) - ); - }), -]; - -const server = setupServer(...handlers); - -export default server; diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/index.js b/packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage.js similarity index 94% rename from packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/index.js rename to packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage.js index 9744ec4630..15888f7ffc 100644 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/index.js +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage.js @@ -26,14 +26,14 @@ import { Formik } from 'formik'; import { useIntl } from 'react-intl'; import { useHistory } from 'react-router-dom'; -import UsersPermissions from '../../../components/UsersPermissions'; -import { usePlugins } from '../../../hooks'; -import pluginId from '../../../pluginId'; -import getTrad from '../../../utils/getTrad'; +import UsersPermissions from '../../components/UsersPermissions'; +import { usePlugins } from '../../hooks'; +import pluginId from '../../pluginId'; +import getTrad from '../../utils/getTrad'; -import schema from './utils/schema'; +import { createRoleSchema } from './constants'; -const EditPage = () => { +const CreatePage = () => { const { formatMessage } = useIntl(); const [isSubmitting, setIsSubmitting] = useState(false); const toggleNotification = useNotification(); @@ -85,7 +85,7 @@ const EditPage = () => { enableReinitialize initialValues={{ name: '', description: '' }} onSubmit={handleCreateRoleSubmit} - validationSchema={schema} + validationSchema={createRoleSchema} > {({ handleSubmit, values, handleChange, errors }) => (
@@ -182,4 +182,4 @@ const EditPage = () => { ); }; -export default EditPage; +export default CreatePage; diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/tests/index.test.js b/packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/tests/index.test.js deleted file mode 100644 index b50e69d1ef..0000000000 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/tests/index.test.js +++ /dev/null @@ -1,1059 +0,0 @@ -import React from 'react'; - -import { lightTheme, ThemeProvider } from '@strapi/design-system'; -import { act, render, waitFor } from '@testing-library/react'; -import { createMemoryHistory } from 'history'; -import { IntlProvider } from 'react-intl'; -import { Route, Router, Switch } from 'react-router-dom'; - -import RolesCreatePage from '..'; -import pluginId from '../../../../pluginId'; - -import server from './server'; - -jest.mock('@strapi/helper-plugin', () => { - // Make sure the references of the mock functions stay the same, otherwise we get an endless loop - const mockToggleNotification = jest.fn(); - const mockUseNotification = jest.fn(() => { - return mockToggleNotification; - }); - - return { - ...jest.requireActual('@strapi/helper-plugin'), - useNotification: mockUseNotification, - useOverlayBlocker: jest.fn(() => ({ lockApp: jest.fn(), unlockApp: jest.fn() })), - }; -}); - -function makeAndRenderApp() { - const history = createMemoryHistory(); - const app = ( - - - - - - - - - - ); - const renderResult = render(app); - act(() => history.push(`/settings/${pluginId}/roles/new`)); - - return renderResult; -} - -describe('Admin | containers | RoleCreatePage', () => { - beforeAll(() => server.listen()); - - beforeEach(() => jest.clearAllMocks()); - - afterEach(() => server.resetHandlers()); - - afterAll(() => server.close()); - - it('renders users-permissions create role and matches snapshot', async () => { - const { container, getByText, getByRole } = makeAndRenderApp(); - await waitFor(() => - expect(getByRole('heading', { name: /create a role/i })).toBeInTheDocument() - ); - await waitFor(() => { - expect( - getByText(/define all allowed actions for the api::address plugin/i) - ).toBeInTheDocument(); - }); - - expect(container.firstChild).toMatchInlineSnapshot(` - .c7 { - font-weight: 600; - font-size: 2rem; - line-height: 1.25; - color: #32324d; - } - - .c13 { - font-size: 1rem; - line-height: 1.5; - color: #666687; - } - - .c18 { - font-weight: 500; - font-size: 1rem; - line-height: 1.25; - color: #32324d; - } - - .c22 { - font-size: 0.75rem; - line-height: 1.33; - font-weight: 600; - color: #32324d; - } - - .c12 { - font-size: 0.75rem; - line-height: 1.33; - font-weight: 600; - line-height: 0; - color: #ffffff; - } - - .c36 { - font-size: 0.875rem; - line-height: 1.43; - color: #666687; - } - - .c46 { - font-size: 0.75rem; - line-height: 1.33; - color: #4945ff; - } - - .c47 { - font-weight: 500; - font-size: 1rem; - line-height: 1.25; - display: block; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - color: #4a4a6a; - } - - .c1 { - background: #f6f6f9; - padding-top: 40px; - padding-right: 56px; - padding-bottom: 40px; - padding-left: 56px; - } - - .c4 { - min-width: 0; - } - - .c14 { - padding-right: 56px; - padding-left: 56px; - } - - .c16 { - background: #ffffff; - padding-top: 24px; - padding-right: 32px; - padding-bottom: 24px; - padding-left: 32px; - border-radius: 4px; - box-shadow: 0px 1px 4px rgba(33,33,52,0.1); - } - - .c26 { - border-radius: 4px; - border-color: #dcdce4; - border: 1px solid #dcdce4; - } - - .c28 { - font-size: 0.875rem; - background: #ffffff; - color: #32324d; - padding: 16px; - border-radius: 4px; - width: 100%; - height: 6.5625rem; - line-height: 1.43; - } - - .c8 { - background: #4945ff; - padding: 8px; - padding-right: 16px; - padding-left: 16px; - border-radius: 4px; - border-color: #4945ff; - border: 1px solid #4945ff; - cursor: pointer; - } - - .c30 { - background: #ffffff; - border-radius: 4px; - box-shadow: 0px 1px 4px rgba(33,33,52,0.1); - } - - .c32 { - padding-top: 24px; - padding-right: 32px; - padding-bottom: 24px; - padding-left: 32px; - } - - .c37 { - border-radius: 4px; - } - - .c39 { - background: #f6f6f9; - padding-top: 24px; - padding-right: 24px; - padding-bottom: 24px; - padding-left: 24px; - } - - .c41 { - max-width: 100%; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - } - - .c43 { - background: transparent; - min-width: 0; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - } - - .c48 { - background: #dcdce4; - border-radius: 50%; - width: 2rem; - height: 2rem; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; - cursor: pointer; - } - - .c50 { - color: #666687; - width: 0.6875rem; - } - - .c52 { - background: #eaeaef; - padding-top: 24px; - padding-right: 32px; - padding-bottom: 24px; - padding-left: 32px; - } - - .c3 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - } - - .c5 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - } - - .c15 { - -webkit-align-items: stretch; - -webkit-box-align: stretch; - -ms-flex-align: stretch; - align-items: stretch; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - gap: 32px; - } - - .c17 { - -webkit-align-items: stretch; - -webkit-box-align: stretch; - -ms-flex-align: stretch; - align-items: stretch; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - gap: 16px; - } - - .c21 { - -webkit-align-items: stretch; - -webkit-box-align: stretch; - -ms-flex-align: stretch; - align-items: stretch; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - gap: 4px; - } - - .c9 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - gap: 8px; - } - - .c34 { - -webkit-align-items: stretch; - -webkit-box-align: stretch; - -ms-flex-align: stretch; - align-items: stretch; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - gap: 24px; - } - - .c35 { - -webkit-align-items: stretch; - -webkit-box-align: stretch; - -ms-flex-align: stretch; - align-items: stretch; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - gap: 8px; - } - - .c42 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - gap: 12px; - } - - .c49 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - } - - .c38 { - border: 1px solid #f6f6f9; - } - - .c38:hover:not([aria-disabled='true']) { - border: 1px solid #4945ff; - } - - .c38:hover:not([aria-disabled='true']) .c6 { - color: #4945ff; - } - - .c38:hover:not([aria-disabled='true']) > .c2 { - background: #f0f0ff; - } - - .c38:hover:not([aria-disabled='true']) [data-strapi-dropdown='true'] { - background: #d9d8ff; - } - - .c44 { - border: none; - position: relative; - outline: none; - } - - .c44[aria-disabled='true'] { - pointer-events: none; - } - - .c44[aria-disabled='true'] svg path { - fill: #666687; - } - - .c44 svg path { - fill: #4945ff; - } - - .c44:after { - -webkit-transition-property: all; - transition-property: all; - -webkit-transition-duration: 0.2s; - transition-duration: 0.2s; - border-radius: 8px; - content: ''; - position: absolute; - top: -4px; - bottom: -4px; - left: -4px; - right: -4px; - border: 2px solid transparent; - } - - .c44:focus-visible { - outline: none; - } - - .c44:focus-visible:after { - border-radius: 8px; - content: ''; - position: absolute; - top: -5px; - bottom: -5px; - left: -5px; - right: -5px; - border: 2px solid #4945ff; - } - - .c51 path { - fill: #666687; - } - - .c45 { - text-align: left; - } - - .c45 > span { - max-width: 100%; - } - - .c45 svg { - width: 0.875rem; - height: 0.875rem; - } - - .c45 svg path { - fill: #8e8ea9; - } - - .c40 { - min-height: 5.5rem; - border-radius: 4px; - } - - .c40:hover svg path { - fill: #4945ff; - } - - .c10 { - position: relative; - outline: none; - } - - .c10 > svg { - height: 12px; - width: 12px; - } - - .c10 > svg > g, - .c10 > svg path { - fill: #ffffff; - } - - .c10[aria-disabled='true'] { - pointer-events: none; - } - - .c10:after { - -webkit-transition-property: all; - transition-property: all; - -webkit-transition-duration: 0.2s; - transition-duration: 0.2s; - border-radius: 8px; - content: ''; - position: absolute; - top: -4px; - bottom: -4px; - left: -4px; - right: -4px; - border: 2px solid transparent; - } - - .c10:focus-visible { - outline: none; - } - - .c10:focus-visible:after { - border-radius: 8px; - content: ''; - position: absolute; - top: -5px; - bottom: -5px; - left: -5px; - right: -5px; - border: 2px solid #4945ff; - } - - .c11 { - height: 2rem; - } - - .c11 svg { - height: 0.75rem; - width: auto; - } - - .c11[aria-disabled='true'] { - border: 1px solid #dcdce4; - background: #eaeaef; - } - - .c11[aria-disabled='true'] .c6 { - color: #666687; - } - - .c11[aria-disabled='true'] svg > g,.c11[aria-disabled='true'] svg path { - fill: #666687; - } - - .c11[aria-disabled='true']:active { - border: 1px solid #dcdce4; - background: #eaeaef; - } - - .c11[aria-disabled='true']:active .c6 { - color: #666687; - } - - .c11[aria-disabled='true']:active svg > g,.c11[aria-disabled='true']:active svg path { - fill: #666687; - } - - .c11:hover { - border: 1px solid #7b79ff; - background: #7b79ff; - } - - .c11:active { - border: 1px solid #4945ff; - background: #4945ff; - } - - .c11 svg > g, - .c11 svg path { - fill: #ffffff; - } - - .c23 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - } - - .c25 { - border: none; - border-radius: 4px; - padding-bottom: 0.65625rem; - padding-left: 16px; - padding-right: 16px; - padding-top: 0.65625rem; - color: #32324d; - font-weight: 400; - font-size: 0.875rem; - display: block; - width: 100%; - background: inherit; - } - - .c25::-webkit-input-placeholder { - color: #8e8ea9; - opacity: 1; - } - - .c25::-moz-placeholder { - color: #8e8ea9; - opacity: 1; - } - - .c25:-ms-input-placeholder { - color: #8e8ea9; - opacity: 1; - } - - .c25::placeholder { - color: #8e8ea9; - opacity: 1; - } - - .c25[aria-disabled='true'] { - color: inherit; - } - - .c25:focus { - outline: none; - box-shadow: none; - } - - .c24 { - border: 1px solid #dcdce4; - border-radius: 4px; - background: #ffffff; - outline: none; - box-shadow: 0; - -webkit-transition-property: border-color,box-shadow,fill; - transition-property: border-color,box-shadow,fill; - -webkit-transition-duration: 0.2s; - transition-duration: 0.2s; - } - - .c24:focus-within { - border: 1px solid #4945ff; - box-shadow: #4945ff 0px 0px 0px 2px; - } - - .c19 { - display: grid; - grid-template-columns: repeat(12,1fr); - gap: 16px; - } - - .c31 { - display: grid; - grid-template-columns: repeat(12,1fr); - } - - .c20 { - grid-column: span 6; - max-width: 100%; - } - - .c33 { - grid-column: span 7; - max-width: 100%; - } - - .c53 { - grid-column: span 5; - max-width: 100%; - } - - .c0:focus-visible { - outline: none; - } - - .c27 { - outline: none; - box-shadow: 0; - -webkit-transition-property: border-color,box-shadow,fill; - transition-property: border-color,box-shadow,fill; - -webkit-transition-duration: 0.2s; - transition-duration: 0.2s; - } - - .c27:focus-within { - border: 1px solid #4945ff; - box-shadow: #4945ff 0px 0px 0px 2px; - } - - .c29 { - border: none; - resize: none; - } - - .c29::-webkit-input-placeholder { - color: #8e8ea9; - font-size: 0.875rem; - color: #8e8ea9; - opacity: 1; - } - - .c29::-moz-placeholder { - color: #8e8ea9; - font-size: 0.875rem; - color: #8e8ea9; - opacity: 1; - } - - .c29:-ms-input-placeholder { - color: #8e8ea9; - font-size: 0.875rem; - color: #8e8ea9; - opacity: 1; - } - - .c29::placeholder { - color: #8e8ea9; - font-size: 0.875rem; - color: #8e8ea9; - opacity: 1; - } - - .c29:focus-within { - outline: none; - } - - @media (max-width:68.75rem) { - .c20 { - grid-column: span; - } - } - - @media (max-width:34.375rem) { - .c20 { - grid-column: span; - } - } - - @media (max-width:68.75rem) { - .c33 { - grid-column: span; - } - } - - @media (max-width:34.375rem) { - .c33 { - grid-column: span; - } - } - - @media (max-width:68.75rem) { - .c53 { - grid-column: span; - } - } - - @media (max-width:34.375rem) { - .c53 { - grid-column: span; - } - } - -
- -
-
-
-
-

- Create a role -

-
- -
-

- Define the rights given to the role -

-
-
-
-
-
-
-

- Role details -

-
-
-
-
-
- -
- -
-
-
-
-
-
-
-
- -
- -
-
-
-
-
-
-
-
-
-
-
-

- Permissions -

-

- Only actions bound by a route are listed below. -

-
-
-
-
-
- -
- -
-
-
-
-
-
-
-
-
-

- Advanced settings -

-

- Select the application's actions or the plugin's actions and click on the cog icon to display the bound route -

-
-
-
-
-
- -
- `); - }); - - it("can edit a users-permissions role's name and description", async () => { - const { getByLabelText, getByRole, getByTestId, getAllByText } = makeAndRenderApp(); - const user = userEvent.setup(); - - // Check loading screen - const loader = getByTestId('loader'); - expect(loader).toBeInTheDocument(); - - // After loading, check other elements - await waitForElementToBeRemoved(loader); - const saveButton = getByRole('button', { name: /save/i }); - expect(saveButton).toBeInTheDocument(); - const nameField = getByLabelText(/name/i); - expect(nameField).toBeInTheDocument(); - const descriptionField = getByLabelText(/description/i); - expect(descriptionField).toBeInTheDocument(); - - // Shows error when name is missing - await user.clear(nameField); - expect(nameField).toHaveValue(''); - await user.clear(descriptionField); - expect(descriptionField).toHaveValue(''); - - // Show errors after form submit - await user.click(saveButton); - await waitFor(() => expect(saveButton).not.toBeDisabled()); - const errorMessages = await getAllByText(/invalid value/i); - errorMessages.forEach((errorMessage) => expect(errorMessage).toBeInTheDocument()); - }); - - it('can toggle the permissions accordions and actions', async () => { - const user = userEvent.setup(); - // Create app and wait for loading - const { getByLabelText, getByRole, queryByText, getByTestId, getByText, getAllByRole } = - makeAndRenderApp(); - const loader = getByTestId('loader'); - await waitForElementToBeRemoved(loader); - - // Open the collapse - const collapse = getByText(/define all allowed actions for the api::address plugin/i); - await user.click(collapse); - expect(getByLabelText(/select all/i)).toBeInTheDocument(); - - // Display the selected action's bound route - const actionCogButton = getByTestId('action-cog'); - await user.click(actionCogButton); - expect(getByText(/bound route to/i)).toBeInTheDocument(); - expect(getByText('POST')).toBeInTheDocument(); - expect(getByText('/addresses')).toBeInTheDocument(); - - expect(getByRole('checkbox', { name: 'Select all' }).checked).toBe(false); - - await user.click(getByRole('checkbox', { name: 'Select all' })); - - getAllByRole('checkbox') - .slice(1, -1) - .forEach((actionCheckbox) => { - console.log(actionCheckbox.checked); - expect(actionCheckbox.checked).toBe(true); - }); - - // Close the collapse - await user.click(collapse); - expect(queryByText(/select all/i)).not.toBeInTheDocument(); - }); -}); diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/EditPage/tests/server.js b/packages/plugins/users-permissions/admin/src/pages/Roles/EditPage/tests/server.js deleted file mode 100644 index 917c012e35..0000000000 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/EditPage/tests/server.js +++ /dev/null @@ -1,95 +0,0 @@ -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; - -import pluginId from '../../../../pluginId'; - -const handlers = [ - // Mock get role route - rest.get(`*/${pluginId}/roles/:roleId`, (req, res, ctx) => { - return res( - ctx.delay(100), - ctx.status(200), - ctx.json({ - role: { - id: req.params.roleId, - name: 'Authenticated', - description: 'Default role given to authenticated user.', - type: 'authenticated', - createdAt: '2021-09-08T16:26:18.061Z', - updatedAt: '2021-09-08T16:26:18.061Z', - permissions: { - 'api::address': { - controllers: { - address: { - create: { - enabled: false, - policy: '', - }, - }, - }, - }, - }, - }, - }) - ); - }), - - // Mock edit role route - rest.put(`*/${pluginId}/roles/:roleId`, (req, res, ctx) => { - return res(ctx.delay(500), ctx.status(200), ctx.json({ ok: true })); - }), - - // Mock get all routes route - rest.get(`*/${pluginId}/routes`, (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - routes: { - 'api::address': [ - { - method: 'POST', - path: '/addresses', - handler: 'address.create', - config: { - policies: [], - auth: { - scope: 'api::address.address.create', - }, - }, - info: { - apiName: 'address', - type: 'content-api', - }, - }, - ], - }, - }) - ); - }), - - // Mock permissions route - rest.get(`*/${pluginId}/permissions`, (req, res, ctx) => { - return res( - ctx.delay(100), - ctx.status(200), - ctx.json({ - permissions: { - 'api::address': { - controllers: { - address: { - create: { - enabled: false, - policy: '', - }, - }, - }, - }, - }, - }) - ); - }), -]; - -const server = setupServer(...handlers); - -export default server; diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/EditPage/utils/schema.js b/packages/plugins/users-permissions/admin/src/pages/Roles/EditPage/utils/schema.js deleted file mode 100644 index c3bcd9cf28..0000000000 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/EditPage/utils/schema.js +++ /dev/null @@ -1,9 +0,0 @@ -import { translatedErrors } from '@strapi/helper-plugin'; -import * as yup from 'yup'; - -const schema = yup.object().shape({ - name: yup.string().required(translatedErrors.required), - description: yup.string().required(translatedErrors.required), -}); - -export default schema; diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/index.test.js b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/index.test.js index b7904d9ad5..c603e9228d 100644 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/index.test.js +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/index.test.js @@ -2,724 +2,105 @@ import React from 'react'; -import { lightTheme, ThemeProvider } from '@strapi/design-system'; -import { TrackingProvider, useRBAC } from '@strapi/helper-plugin'; -import { render, screen, waitFor } from '@testing-library/react'; -import { createMemoryHistory } from 'history'; +import { ThemeProvider, lightTheme } from '@strapi/design-system'; +import { render as renderRTL, waitForElementToBeRemoved } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { IntlProvider } from 'react-intl'; import { QueryClient, QueryClientProvider } from 'react-query'; -import { Router } from 'react-router-dom'; +import { MemoryRouter, Route } from 'react-router-dom'; import RoleListPage from '../index'; -import server from './server'; +jest.mock('@strapi/design-system', () => ({ + ...jest.requireActual('@strapi/design-system'), + useNotifyAT: () => ({ + notifyStatus: jest.fn(), + }), +})); jest.mock('@strapi/helper-plugin', () => ({ ...jest.requireActual('@strapi/helper-plugin'), - useNotification: jest.fn(), - useRBAC: jest.fn(), + useNotification: jest.fn().mockImplementation(() => jest.fn()), + useRBAC: jest + .fn() + .mockImplementation(() => ({ isLoading: false, allowedActions: { canRead: true } })), CheckPermissions: jest.fn(({ children }) => children), })); -const client = new QueryClient({ - defaultOptions: { - queries: { - retry: false, +let testLocation; + +const render = () => ({ + ...renderRTL(, { + wrapper({ children }) { + const client = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, + }); + + return ( + + + + + {children} + + + + { + testLocation = location; + + return null; + }} + /> + + ); }, - }, + }), + user: userEvent.setup(), }); -const makeApp = (history) => ( - - - - - - - - - - - -); - -describe('Plugin | Users and Permissions | RoleListPage', () => { - beforeAll(() => server.listen()); - +describe('Roles – ListPage', () => { beforeEach(() => { jest.clearAllMocks(); }); - afterEach(() => server.resetHandlers()); + it('renders as expected with headers, actions and a table', async () => { + const { getByRole, queryByText, getByText } = render(); - afterAll(() => server.close()); + expect(queryByText('Loading content.')).toBeInTheDocument(); - it('renders and matches the snapshot', () => { - useRBAC.mockImplementation(() => ({ isLoading: false, allowedActions: { canRead: true } })); - const history = createMemoryHistory(); - const App = makeApp(history); - const { - container: { firstChild }, - } = render(App); + expect(getByRole('heading', { name: 'Roles' })).toBeInTheDocument(); + expect(getByText('List of roles')).toBeInTheDocument(); + expect(getByRole('button', { name: 'Add new role' })).toBeInTheDocument(); + expect(getByRole('button', { name: 'Search' })).toBeInTheDocument(); - expect(firstChild).toMatchInlineSnapshot(` - .c22 { - border: 0; - -webkit-clip: rect(0 0 0 0); - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; - } + await waitForElementToBeRemoved(() => queryByText('Loading content.')); - .c9 { - font-weight: 600; - font-size: 2rem; - line-height: 1.25; - color: #32324d; - } - - .c14 { - font-size: 0.75rem; - line-height: 1.33; - font-weight: 600; - line-height: 0; - color: #ffffff; - } - - .c15 { - font-size: 1rem; - line-height: 1.5; - color: #666687; - } - - .c36 { - font-weight: 500; - font-size: 1rem; - line-height: 1.25; - color: #666687; - text-align: center; - } - - .c1 { - padding-bottom: 56px; - } - - .c4 { - background: #f6f6f9; - padding-top: 40px; - padding-right: 56px; - padding-bottom: 40px; - padding-left: 56px; - } - - .c6 { - min-width: 0; - } - - .c10 { - background: #4945ff; - padding: 8px; - padding-right: 16px; - padding-left: 16px; - border-radius: 4px; - border-color: #4945ff; - border: 1px solid #4945ff; - cursor: pointer; - } - - .c16 { - padding-right: 56px; - padding-bottom: 16px; - padding-left: 56px; - } - - .c19 { - background: #ffffff; - padding: 8px; - border-radius: 4px; - border-color: #dcdce4; - border: 1px solid #dcdce4; - width: 2rem; - height: 2rem; - cursor: pointer; - } - - .c23 { - color: #32324d; - } - - .c25 { - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; - } - - .c27 { - padding-right: 56px; - padding-left: 56px; - } - - .c31 { - background: #ffffff; - padding: 64px; - border-radius: 4px; - box-shadow: 0px 1px 4px rgba(33,33,52,0.1); - } - - .c33 { - padding-bottom: 24px; - } - - .c35 { - padding-bottom: 16px; - } - - .c5 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - } - - .c7 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - } - - .c11 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - gap: 8px; - } - - .c17 { - -webkit-align-items: flex-start; - -webkit-box-align: flex-start; - -ms-flex-align: flex-start; - align-items: flex-start; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - } - - .c18 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - gap: 8px; - } - - .c20 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - } - - .c26 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - gap: 8px; - } - - .c28 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-box-pack: space-around; - -webkit-justify-content: space-around; - -ms-flex-pack: space-around; - justify-content: space-around; - } - - .c32 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - } - - .c24 path { - fill: #32324d; - } - - .c12 { - position: relative; - outline: none; - } - - .c12 > svg { - height: 12px; - width: 12px; - } - - .c12 > svg > g, - .c12 > svg path { - fill: #ffffff; - } - - .c12[aria-disabled='true'] { - pointer-events: none; - } - - .c12:after { - -webkit-transition-property: all; - transition-property: all; - -webkit-transition-duration: 0.2s; - transition-duration: 0.2s; - border-radius: 8px; - content: ''; - position: absolute; - top: -4px; - bottom: -4px; - left: -4px; - right: -4px; - border: 2px solid transparent; - } - - .c12:focus-visible { - outline: none; - } - - .c12:focus-visible:after { - border-radius: 8px; - content: ''; - position: absolute; - top: -5px; - bottom: -5px; - left: -5px; - right: -5px; - border: 2px solid #4945ff; - } - - .c13 { - height: 2rem; - } - - .c13 svg { - height: 0.75rem; - width: auto; - } - - .c13[aria-disabled='true'] { - border: 1px solid #dcdce4; - background: #eaeaef; - } - - .c13[aria-disabled='true'] .c8 { - color: #666687; - } - - .c13[aria-disabled='true'] svg > g,.c13[aria-disabled='true'] svg path { - fill: #666687; - } - - .c13[aria-disabled='true']:active { - border: 1px solid #dcdce4; - background: #eaeaef; - } - - .c13[aria-disabled='true']:active .c8 { - color: #666687; - } - - .c13[aria-disabled='true']:active svg > g,.c13[aria-disabled='true']:active svg path { - fill: #666687; - } - - .c13:hover { - border: 1px solid #7b79ff; - background: #7b79ff; - } - - .c13:active { - border: 1px solid #4945ff; - background: #4945ff; - } - - .c13 svg > g, - .c13 svg path { - fill: #ffffff; - } - - .c30 { - -webkit-animation: gzYjWD 1s infinite linear; - animation: gzYjWD 1s infinite linear; - will-change: transform; - } - - .c34 svg { - height: 5.5rem; - } - - .c21 svg > g, - .c21 svg path { - fill: #8e8ea9; - } - - .c21:hover svg > g, - .c21:hover svg path { - fill: #666687; - } - - .c21:active svg > g, - .c21:active svg path { - fill: #a5a5ba; - } - - .c21[aria-disabled='true'] svg path { - fill: #666687; - } - - .c0 { - display: grid; - grid-template-columns: 1fr; - } - - .c2 { - overflow-x: hidden; - } - - .c3:focus-visible { - outline: none; - } - - .c29 { - height: 100vh; - } - -
-
-
-
-
-
-
-

- Roles -

-
- -
-

- List of roles -

-
-
-
-
- - - -
-
-
-
-
-
-
- Loading content. -
- -
-
-
- -
-

- You don't have any roles yet. -

-
-
-
-
-
-
- `); + expect(getByRole('grid')).toBeInTheDocument(); + expect(getByRole('gridcell', { name: 'Authenticated' })).toBeInTheDocument(); + expect(getByRole('gridcell', { name: 'Public' })).toBeInTheDocument(); }); - it('should show a loader when fetching data', () => { - const history = createMemoryHistory(); - const App = makeApp(history); - render(App); + it('should direct me to the new user page when I press the add a new role button', async () => { + const { getByRole } = render(); - expect(screen.getByTestId('loader')).toBeInTheDocument(); + await userEvent.click(getByRole('button', { name: 'Add new role' })); + + expect(testLocation.pathname).toBe('/settings/users-permissions/roles/new'); }); - it('should show a list of roles', async () => { - const history = createMemoryHistory(); - const App = makeApp(history); - render(App); + it('should direct me to the edit view of a selected role if I click the edit role button', async () => { + const { getByRole, queryByText } = render(); - await waitFor(() => { - expect(screen.getByText('Authenticated')).toBeInTheDocument(); - expect(screen.getByText('Public')).toBeInTheDocument(); - }); + await waitForElementToBeRemoved(() => queryByText('Loading content.')); + + await userEvent.click(getByRole('button', { name: 'Edit Authenticated', hidden: true })); + + expect(testLocation.pathname).toBe('/settings/users-permissions/roles/1'); }); }); diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/server.js b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/server.js deleted file mode 100644 index dde6e1ef0a..0000000000 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/tests/server.js +++ /dev/null @@ -1,33 +0,0 @@ -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; - -const handlers = [ - rest.get('*/roles', (req, res, ctx) => { - return res( - ctx.delay(1000), - ctx.status(200), - ctx.json({ - roles: [ - { - id: 1, - name: 'Authenticated', - description: 'Default role given to authenticated user.', - type: 'authenticated', - nb_users: 0, - }, - { - id: 2, - name: 'Public', - description: 'Default role given to unauthenticated user.', - type: 'public', - nb_users: 0, - }, - ], - }) - ); - }), -]; - -const server = setupServer(...handlers); - -export default server; diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/utils/api.js b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/utils/api.js index 9c4d2f22ca..67fb5e706e 100644 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/utils/api.js +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/ListPage/utils/api.js @@ -15,7 +15,7 @@ export const fetchData = async (toggleNotification, notifyStatus) => { message: { id: 'notification.error' }, }); - throw new Error('error'); + throw new Error(err); } }; diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedCreatePage/index.js b/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedCreatePage.js similarity index 74% rename from packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedCreatePage/index.js rename to packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedCreatePage.js index 2ed1c26346..be2a0d1441 100644 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedCreatePage/index.js +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedCreatePage.js @@ -2,8 +2,9 @@ import React from 'react'; import { CheckPagePermissions } from '@strapi/helper-plugin'; -import pluginPermissions from '../../../permissions'; -import RolesCreatePage from '../CreatePage'; +import pluginPermissions from '../../permissions'; + +import RolesCreatePage from './CreatePage'; const ProtectedRolesCreatePage = () => ( diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedEditPage/index.js b/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedEditPage.js similarity index 75% rename from packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedEditPage/index.js rename to packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedEditPage.js index 01d37685aa..c3e0691b07 100644 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedEditPage/index.js +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedEditPage.js @@ -2,8 +2,9 @@ import React from 'react'; import { CheckPagePermissions } from '@strapi/helper-plugin'; -import pluginPermissions from '../../../permissions'; -import RolesEditPage from '../EditPage'; +import pluginPermissions from '../../permissions'; + +import RolesEditPage from './EditPage'; const ProtectedRolesEditPage = () => ( diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedListPage/index.js b/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedListPage.js similarity index 76% rename from packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedListPage/index.js rename to packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedListPage.js index 6476f6f5a5..867a72be07 100644 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedListPage/index.js +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/ProtectedListPage.js @@ -2,8 +2,9 @@ import React from 'react'; import { CheckPagePermissions } from '@strapi/helper-plugin'; -import pluginPermissions from '../../../permissions'; -import RolesListPage from '../ListPage'; +import pluginPermissions from '../../permissions'; + +import RolesListPage from './ListPage'; const ProtectedRolesListPage = () => { return ( diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/utils/schema.js b/packages/plugins/users-permissions/admin/src/pages/Roles/constants.js similarity index 78% rename from packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/utils/schema.js rename to packages/plugins/users-permissions/admin/src/pages/Roles/constants.js index c3bcd9cf28..51bd2c31b3 100644 --- a/packages/plugins/users-permissions/admin/src/pages/Roles/CreatePage/utils/schema.js +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/constants.js @@ -1,9 +1,7 @@ import { translatedErrors } from '@strapi/helper-plugin'; import * as yup from 'yup'; -const schema = yup.object().shape({ +export const createRoleSchema = yup.object().shape({ name: yup.string().required(translatedErrors.required), description: yup.string().required(translatedErrors.required), }); - -export default schema; diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/tests/CreatePage.test.js b/packages/plugins/users-permissions/admin/src/pages/Roles/tests/CreatePage.test.js new file mode 100644 index 0000000000..032064f349 --- /dev/null +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/tests/CreatePage.test.js @@ -0,0 +1,108 @@ +import React from 'react'; + +import { ThemeProvider, lightTheme } from '@strapi/design-system'; +import { NotificationsProvider } from '@strapi/helper-plugin'; +import { fireEvent, render as renderRTL, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { IntlProvider } from 'react-intl'; +import { QueryClient, QueryClientProvider } from 'react-query'; +import { MemoryRouter, Switch, Route } from 'react-router-dom'; + +import pluginId from '../../../pluginId'; +import RolesCreatePage from '../CreatePage'; + +jest.mock('@strapi/helper-plugin', () => ({ + ...jest.requireActual('@strapi/helper-plugin'), + useOverlayBlocker: jest.fn(() => ({ lockApp: jest.fn(), unlockApp: jest.fn() })), +})); + +const render = () => ({ + ...renderRTL(, { + wrapper({ children }) { + const client = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, + }); + + return ( + + + + + + {children} + + + + + + ); + }, + }), + user: userEvent.setup(), +}); + +describe('Roles – CreatePage', () => { + beforeEach(() => jest.clearAllMocks()); + + it('renders correctly', async () => { + const { getByRole, user } = render(); + + expect(getByRole('heading', { name: 'Create a role' })).toBeInTheDocument(); + expect(getByRole('heading', { name: 'Role details' })).toBeInTheDocument(); + + /** + * This means the `usePlugins` hook has finished fetching + */ + await waitFor(() => expect(getByRole('heading', { name: 'Permissions' })).toBeInTheDocument()); + + expect(getByRole('heading', { name: 'Advanced settings' })).toBeInTheDocument(); + + expect(getByRole('button', { name: 'Save' })).toBeInTheDocument(); + + expect(getByRole('textbox', { name: 'Name' })).toBeInTheDocument(); + expect(getByRole('textbox', { name: 'Description' })).toBeInTheDocument(); + + await user.click(getByRole('button', { name: 'Address' })); + + expect(getByRole('region', { name: 'Address' })).toBeInTheDocument(); + + expect(getByRole('checkbox', { name: 'Select all' })).toBeInTheDocument(); + expect(getByRole('checkbox', { name: 'create' })).toBeInTheDocument(); + }); + + it('will show an error if the user does not fill the name or description field', async () => { + const { getByRole, getAllByText } = render(); + + await waitFor(() => expect(getByRole('heading', { name: 'Permissions' })).toBeInTheDocument()); + + fireEvent.click(getByRole('button', { name: 'Save' })); + + await waitFor(() => + expect(getByRole('textbox', { name: 'Name' })).toHaveAttribute('aria-invalid', 'true') + ); + + expect(getByRole('textbox', { name: 'Description' })).toHaveAttribute('aria-invalid', 'true'); + + expect(getAllByText('Invalid value')).toHaveLength(2); + }); + + it('can create a new role and show a notification', async () => { + const { getByRole, getByText, user } = render(); + + await waitFor(() => expect(getByRole('heading', { name: 'Permissions' })).toBeInTheDocument()); + + await user.type(getByRole('textbox', { name: 'Name' }), 'Test role'); + await user.type(getByRole('textbox', { name: 'Description' }), 'This is a test role'); + + await user.click(getByRole('button', { name: 'Address' })); + await user.click(getByRole('checkbox', { name: 'create' })); + + fireEvent.click(getByRole('button', { name: 'Save' })); + + await waitFor(() => expect(getByText('Role created')).toBeInTheDocument()); + }); +}); diff --git a/packages/plugins/users-permissions/admin/src/pages/Roles/tests/EditPage.test.js b/packages/plugins/users-permissions/admin/src/pages/Roles/tests/EditPage.test.js new file mode 100644 index 0000000000..a0d2cf6846 --- /dev/null +++ b/packages/plugins/users-permissions/admin/src/pages/Roles/tests/EditPage.test.js @@ -0,0 +1,155 @@ +import React from 'react'; + +import { ThemeProvider, lightTheme } from '@strapi/design-system'; +import { NotificationsProvider } from '@strapi/helper-plugin'; +import { + fireEvent, + render as renderRTL, + waitFor, + waitForElementToBeRemoved, +} from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { IntlProvider } from 'react-intl'; +import { QueryClient, QueryClientProvider } from 'react-query'; +import { MemoryRouter, Switch, Route } from 'react-router-dom'; + +import pluginId from '../../../pluginId'; +import RolesEditPage from '../EditPage'; + +jest.mock('@strapi/helper-plugin', () => ({ + ...jest.requireActual('@strapi/helper-plugin'), + useOverlayBlocker: jest.fn(() => ({ lockApp: jest.fn(), unlockApp: jest.fn() })), +})); + +const render = () => ({ + ...renderRTL(, { + wrapper({ children }) { + const client = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, + }); + + return ( + + + + + + {children} + + + + + + ); + }, + }), + user: userEvent.setup(), +}); + +describe('Roles – EditPage', () => { + beforeEach(() => jest.clearAllMocks()); + + it('renders correctly', async () => { + const { getByTestId, getByRole, user } = render(); + + await waitForElementToBeRemoved(() => getByTestId('loader')); + + expect(getByRole('link', { name: 'Back' })).toBeInTheDocument(); + + expect(getByRole('heading', { name: 'Authenticated' })).toBeInTheDocument(); + expect(getByRole('heading', { name: 'Role details' })).toBeInTheDocument(); + expect(getByRole('heading', { name: 'Permissions' })).toBeInTheDocument(); + expect(getByRole('heading', { name: 'Advanced settings' })).toBeInTheDocument(); + + expect(getByRole('button', { name: 'Save' })).toBeInTheDocument(); + + expect(getByRole('textbox', { name: 'Name' })).toBeInTheDocument(); + expect(getByRole('textbox', { name: 'Description' })).toBeInTheDocument(); + + await user.click(getByRole('button', { name: 'Address' })); + + expect(getByRole('region', { name: 'Address' })).toBeInTheDocument(); + + expect(getByRole('checkbox', { name: 'Select all' })).toBeInTheDocument(); + expect(getByRole('checkbox', { name: 'create' })).toBeInTheDocument(); + }); + + it('will show an error if the user does not fill the name field', async () => { + const { getByRole, user, getByTestId, getByText } = render(); + + await waitForElementToBeRemoved(() => getByTestId('loader')); + + await user.clear(getByRole('textbox', { name: 'Name' })); + + await user.click(getByRole('button', { name: 'Save' })); + + expect(getByRole('textbox', { name: 'Name' })).toHaveAttribute('aria-invalid', 'true'); + expect(getByText('Invalid value')).toBeInTheDocument(); + }); + + it('will show an error if the user does not fill out the description field', async () => { + const { getByRole, user, getByTestId, getByText } = render(); + + await waitForElementToBeRemoved(() => getByTestId('loader')); + + await user.clear(getByRole('textbox', { name: 'Description' })); + + await user.click(getByRole('button', { name: 'Save' })); + + expect(getByRole('textbox', { name: 'Description' })).toHaveAttribute('aria-invalid', 'true'); + expect(getByText('Invalid value')).toBeInTheDocument(); + }); + + it("can update a role's name and description", async () => { + const { getByRole, user, getByTestId, getByText } = render(); + + await waitForElementToBeRemoved(() => getByTestId('loader')); + + await user.type(getByRole('textbox', { name: 'Name' }), 'test'); + await user.type(getByRole('textbox', { name: 'Description' }), 'testing'); + + /** + * @note user.click will not trigger the form. + */ + fireEvent.click(getByRole('button', { name: 'Save' })); + + await waitFor(() => expect(getByText('Role edited')).toBeInTheDocument()); + }); + + it("can update a role's permissions", async () => { + const { getByRole, user, getByText, getByTestId } = render(); + + await waitForElementToBeRemoved(() => getByTestId('loader')); + + await user.click(getByRole('button', { name: 'Address' })); + + await user.click(getByRole('checkbox', { name: 'create' })); + + /** + * @note user.click will not trigger the form. + */ + fireEvent.click(getByRole('button', { name: 'Save' })); + + await waitFor(() => expect(getByText('Role edited')).toBeInTheDocument()); + }); + + it('will update the Advanced Settings panel when you click on the cog icon of a specific permission', async () => { + const { getByRole, user, getByText, getByTestId } = render(); + + await waitForElementToBeRemoved(() => getByTestId('loader')); + + await user.click(getByRole('button', { name: 'Address' })); + + await user.hover(getByRole('checkbox', { name: 'create' })); + + await user.click(getByRole('button', { name: /Show bound route/i })); + + expect(getByRole('heading', { name: 'Bound route to address .create' })).toBeInTheDocument(); + expect(getByText('POST')).toBeInTheDocument(); + expect(getByText('/addresses')).toBeInTheDocument(); + }); +}); diff --git a/packages/plugins/users-permissions/jest.config.front.js b/packages/plugins/users-permissions/jest.config.front.js index c4f1adbda6..3e8054a997 100644 --- a/packages/plugins/users-permissions/jest.config.front.js +++ b/packages/plugins/users-permissions/jest.config.front.js @@ -3,4 +3,5 @@ module.exports = { preset: '../../../jest-preset.front.js', displayName: 'Users & Permissions plugin', + setupFilesAfterEnv: ['./tests/setup.js'], }; diff --git a/packages/plugins/users-permissions/package.json b/packages/plugins/users-permissions/package.json index 31643adacd..75f4d3d237 100644 --- a/packages/plugins/users-permissions/package.json +++ b/packages/plugins/users-permissions/package.json @@ -54,7 +54,6 @@ "@testing-library/dom": "9.2.0", "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.4.3", - "history": "^4.9.0", "msw": "1.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/packages/plugins/users-permissions/tests/server.js b/packages/plugins/users-permissions/tests/server.js new file mode 100644 index 0000000000..bdc45ba202 --- /dev/null +++ b/packages/plugins/users-permissions/tests/server.js @@ -0,0 +1,191 @@ +'use strict'; + +const { setupServer } = require('msw/node'); +const { rest } = require('msw'); +const pluginId = require('../admin/src/pluginId').default; + +const handlers = [ + // Mock get role route + rest.get(`*/${pluginId}/roles/:roleId`, (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + role: { + id: req.params.roleId, + name: 'Authenticated', + description: 'Default role given to authenticated user.', + type: 'authenticated', + createdAt: '2021-09-08T16:26:18.061Z', + updatedAt: '2021-09-08T16:26:18.061Z', + permissions: { + 'api::address': { + controllers: { + address: { + create: { + enabled: false, + policy: '', + }, + }, + }, + }, + }, + }, + }) + ); + }), + + // Mock edit role route + rest.put(`*/${pluginId}/roles/:roleId`, (req, res, ctx) => { + return res(ctx.status(200), ctx.json({ ok: true })); + }), + + // Mock create role route + rest.post(`*/${pluginId}/roles`, (req, res, ctx) => { + return res(ctx.status(200), ctx.json({ ok: true })); + }), + + // Mock get all routes route + rest.get(`*/${pluginId}/routes`, (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + routes: { + 'api::address': [ + { + method: 'POST', + path: '/addresses', + handler: 'address.create', + config: { + policies: [], + auth: { + scope: 'api::address.address.create', + }, + }, + info: { + apiName: 'address', + type: 'content-api', + }, + }, + ], + }, + }) + ); + }), + + // Mock permissions route + rest.get(`*/${pluginId}/permissions`, (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + permissions: { + 'api::address': { + controllers: { + address: { + create: { + enabled: false, + policy: '', + }, + }, + }, + }, + }, + }) + ); + }), + + rest.get('*/roles', (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + roles: [ + { + id: 1, + name: 'Authenticated', + description: 'Default role given to authenticated user.', + type: 'authenticated', + nb_users: 0, + }, + { + id: 2, + name: 'Public', + description: 'Default role given to unauthenticated user.', + type: 'public', + nb_users: 0, + }, + ], + }) + ); + }), + + rest.get('*/providers', (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + email: { enabled: true, icon: 'envelope' }, + discord: { + callback: '/auth/discord/callback', + enabled: false, + icon: 'discord', + key: '', + scope: ['identify', 'email'], + secret: '', + }, + }) + ); + }), + + rest.get('*/email-templates', (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + email_confirmation: { + display: 'Email.template.email_confirmation', + options: { + from: { + email: 'mochoko@strapi.io', + name: 'Administration Panel', + }, + message: 'Thank you for registering. Please click on the link below.', + object: 'Account confirmation', + response_email: '', + }, + }, + reset_password: { + display: 'Email.template.reset_password', + options: { + from: { + email: 'mochoko@strapi.io', + name: 'Administration Panel', + }, + message: 'We heard that you lost your password. Sorry about that!', + object: 'Reset password', + response_email: '', + }, + }, + }) + ); + }), + + rest.get('*/advanced', (req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + roles: [{ name: 'Authenticated', type: 'authenticated' }], + settings: { + allow_register: false, + default_role: 'authenticated', + email_confirmation: false, + email_confirmation_redirection: '', + email_reset_password: 'https://cat-bounce.com/', + unique_email: false, + }, + }) + ); + }), +]; + +const server = setupServer(...handlers); + +module.exports = { + server, +}; diff --git a/packages/plugins/users-permissions/tests/setup.js b/packages/plugins/users-permissions/tests/setup.js new file mode 100644 index 0000000000..2727d42e3a --- /dev/null +++ b/packages/plugins/users-permissions/tests/setup.js @@ -0,0 +1,15 @@ +'use strict'; + +const { server } = require('./server'); + +beforeAll(() => { + server.listen(); +}); + +afterEach(() => { + server.resetHandlers(); +}); + +afterAll(() => { + server.close(); +}); diff --git a/yarn.lock b/yarn.lock index e81ba5ce41..f5f8a4d1e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8514,7 +8514,6 @@ __metadata: bcryptjs: 2.4.3 formik: 2.4.0 grant-koa: 5.4.8 - history: ^4.9.0 immer: 9.0.19 jsonwebtoken: 9.0.0 jwk-to-pem: 2.0.5