diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/init.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/init.js deleted file mode 100644 index a9ba8b9377..0000000000 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/init.js +++ /dev/null @@ -1,13 +0,0 @@ -import { transformPermissionsData } from './utils'; - -const init = (state, permissions = []) => { - return { - ...state, - selectedAction: null, - routes: [], - selectedActions: [], - data: transformPermissionsData(permissions), - }; -}; - -export default init; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/reducer.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/reducer.js deleted file mode 100644 index 58fcbeaa1d..0000000000 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/reducer.js +++ /dev/null @@ -1,72 +0,0 @@ -/* eslint-disable consistent-return */ -import produce from 'immer'; -import { pull } from 'lodash'; -import { transformPermissionsData } from './utils'; - -export const initialState = { - data: {}, - selectedActions: [], -}; - -const reducer = (state, action) => - produce(state, (draftState) => { - switch (action.type) { - case 'ON_CHANGE': { - if (draftState.selectedActions.includes(action.value)) { - pull(draftState.selectedActions, action.value); - } else { - draftState.selectedActions.push(action.value); - } - break; - } - case 'SELECT_ALL_IN_PERMISSION': { - const areAllSelected = action.value.every((item) => - draftState.selectedActions.includes(item.actionId) - ); - - if (areAllSelected) { - action.value.forEach((item) => { - pull(draftState.selectedActions, item.actionId); - }); - } else { - action.value.forEach((item) => { - draftState.selectedActions.push(item.actionId); - }); - } - break; - } - - case 'SELECT_ALL_ACTIONS': { - draftState.selectedActions = [...draftState.data.allActionsIds]; - - break; - } - case 'ON_CHANGE_READ_ONLY': { - const onlyReadOnlyActions = draftState.data.allActionsIds.filter( - (actionId) => actionId.includes('find') || actionId.includes('findOne') - ); - draftState.selectedActions = [...onlyReadOnlyActions]; - break; - } - case 'UPDATE_PERMISSIONS_LAYOUT': { - draftState.data = transformPermissionsData(action.value); - break; - } - case 'UPDATE_ROUTES': { - draftState.routes = { ...action.value }; - break; - } - case 'UPDATE_PERMISSIONS': { - draftState.selectedActions = [...action.value]; - break; - } - case 'SET_SELECTED_ACTION': { - draftState.selectedAction = action.value; - break; - } - default: - return draftState; - } - }); - -export default reducer; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/tests/__snapshots__/index.test.js.snap b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/tests/__snapshots__/index.test.js.snap new file mode 100644 index 0000000000..9a81a652d5 --- /dev/null +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/tests/__snapshots__/index.test.js.snap @@ -0,0 +1,2138 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ADMIN | Pages | TRANSFER TOKENS | EditView renders and matches the snapshot when creating token 1`] = ` +.c42 { + 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; +} + +.c2 { + background: #f6f6f9; + padding-top: 24px; + padding-right: 56px; + padding-bottom: 40px; + padding-left: 56px; +} + +.c3 { + padding-bottom: 8px; +} + +.c5 { + padding-right: 8px; +} + +.c17 { + padding-right: 56px; + padding-left: 56px; +} + +.c20 { + 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); +} + +.c36 { + padding-right: 16px; + padding-left: 16px; +} + +.c38 { + padding-left: 12px; +} + +.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; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; +} + +.c10 { + -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; +} + +.c18 { + -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; +} + +.c8 { + font-size: 0.875rem; + line-height: 1.43; + color: #4945ff; +} + +.c11 { + font-weight: 600; + font-size: 2rem; + line-height: 1.25; + color: #32324d; +} + +.c16 { + font-size: 0.75rem; + line-height: 1.33; + font-weight: 600; + color: #32324d; +} + +.c22 { + font-weight: 500; + font-size: 1rem; + line-height: 1.25; + color: #32324d; +} + +.c26 { + font-size: 0.875rem; + line-height: 1.43; + color: #d02b20; +} + +.c37 { + font-size: 0.875rem; + line-height: 1.43; + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + color: #666687; +} + +.c41 { + font-size: 0.75rem; + line-height: 1.33; + color: #666687; +} + +.c19 > * { + margin-top: 0; + margin-bottom: 0; +} + +.c19 > * + * { + margin-top: 24px; +} + +.c21 > * { + margin-top: 0; + margin-bottom: 0; +} + +.c21 > * + * { + margin-top: 16px; +} + +.c25 > * { + margin-top: 0; + margin-bottom: 0; +} + +.c25 > * + * { + margin-top: 4px; +} + +.c12 > * { + margin-left: 0; + margin-right: 0; +} + +.c12 > * + * { + margin-left: 8px; +} + +.c13 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + cursor: pointer; + padding: 8px; + border-radius: 4px; + background: #ffffff; + border: 1px solid #dcdce4; + position: relative; + outline: none; +} + +.c13 svg { + height: 12px; + width: 12px; +} + +.c13 svg > g, +.c13 svg path { + fill: #ffffff; +} + +.c13[aria-disabled='true'] { + pointer-events: none; +} + +.c13: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; +} + +.c13:focus-visible { + outline: none; +} + +.c13:focus-visible:after { + border-radius: 8px; + content: ''; + position: absolute; + top: -5px; + bottom: -5px; + left: -5px; + right: -5px; + border: 2px solid #4945ff; +} + +.c15 { + height: 100%; +} + +.c14 { + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: #4945ff; + border: 1px solid #4945ff; + height: 2rem; + padding-left: 16px; + padding-right: 16px; +} + +.c14 .c1 { + 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; +} + +.c14 .c7 { + color: #ffffff; +} + +.c14[aria-disabled='true'] { + border: 1px solid #dcdce4; + background: #eaeaef; +} + +.c14[aria-disabled='true'] .c7 { + color: #666687; +} + +.c14[aria-disabled='true'] svg > g,.c14[aria-disabled='true'] svg path { + fill: #666687; +} + +.c14[aria-disabled='true']:active { + border: 1px solid #dcdce4; + background: #eaeaef; +} + +.c14[aria-disabled='true']:active .c7 { + color: #666687; +} + +.c14[aria-disabled='true']:active svg > g,.c14[aria-disabled='true']:active svg path { + fill: #666687; +} + +.c14:hover { + border: 1px solid #7b79ff; + background: #7b79ff; +} + +.c14:active { + border: 1px solid #4945ff; + background: #4945ff; +} + +.c14 svg > g, +.c14 svg path { + fill: #ffffff; +} + +.c34 { + position: absolute; + left: 0; + right: 0; + bottom: 0; + top: 0; + width: 100%; + background: transparent; + border: none; +} + +.c34:focus { + outline: none; +} + +.c34[aria-disabled='true'] { + cursor: not-allowed; +} + +.c27 { + line-height: 0; +} + +.c29 { + 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; +} + +.c29::-webkit-input-placeholder { + color: #8e8ea9; + opacity: 1; +} + +.c29::-moz-placeholder { + color: #8e8ea9; + opacity: 1; +} + +.c29:-ms-input-placeholder { + color: #8e8ea9; + opacity: 1; +} + +.c29::placeholder { + color: #8e8ea9; + opacity: 1; +} + +.c29[aria-disabled='true'] { + color: inherit; +} + +.c29:focus { + outline: none; + box-shadow: none; +} + +.c28 { + 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; +} + +.c28:focus-within { + border: 1px solid #4945ff; + box-shadow: #4945ff 0px 0px 0px 2px; +} + +.c33 { + position: relative; + border: 1px solid #dcdce4; + padding-right: 12px; + border-radius: 4px; + background: #ffffff; + overflow: hidden; + min-height: 2.5rem; + 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; +} + +.c33:focus-within { + border: 1px solid #4945ff; + box-shadow: #4945ff 0px 0px 0px 2px; +} + +.c39 { + background: transparent; + border: none; + position: relative; + z-index: 1; +} + +.c39 svg { + height: 0.6875rem; + width: 0.6875rem; +} + +.c39 svg path { + fill: #666687; +} + +.c40 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + background: none; + border: none; +} + +.c40 svg { + width: 0.375rem; +} + +.c35 { + width: 100%; +} + +.c4 { + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-text-decoration: none; + text-decoration: none; + position: relative; + outline: none; +} + +.c4 svg path { + fill: #4945ff; +} + +.c4 svg { + font-size: 0.625rem; +} + +.c4: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; +} + +.c4:focus-visible { + outline: none; +} + +.c4:focus-visible:after { + border-radius: 8px; + content: ''; + position: absolute; + top: -5px; + bottom: -5px; + left: -5px; + right: -5px; + border: 2px solid #4945ff; +} + +.c6 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; +} + +.c0:focus-visible { + outline: none; +} + +.c23 { + display: grid; + grid-template-columns: repeat(12,1fr); + gap: 20px; +} + +.c24 { + grid-column: span 6; + max-width: 100%; +} + +.c31 { + border: 1px solid #dcdce4; + border-radius: 4px; + padding-left: 16px; + padding-right: 16px; + padding-top: 12px; + padding-bottom: 12px; + 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; +} + +.c31:focus-within { + border: 1px solid #4945ff; + box-shadow: #4945ff 0px 0px 0px 2px; +} + +.c32 { + display: block; + width: 100%; + font-weight: 400; + font-size: 0.875rem; + border: none; + color: #32324d; + resize: none; + background: inherit; +} + +.c32::-webkit-input-placeholder { + color: #8e8ea9; + opacity: 1; +} + +.c32::-moz-placeholder { + color: #8e8ea9; + opacity: 1; +} + +.c32:-ms-input-placeholder { + color: #8e8ea9; + opacity: 1; +} + +.c32::placeholder { + color: #8e8ea9; + opacity: 1; +} + +.c32:focus-within { + outline: none; +} + +.c30 textarea { + height: 5rem; + line-height: 1.25rem; +} + +.c30 textarea::-webkit-input-placeholder { + font-weight: 400; + font-size: 0.875rem; + line-height: 1.43; + color: #8e8ea9; + opacity: 1; +} + +.c30 textarea::-moz-placeholder { + font-weight: 400; + font-size: 0.875rem; + line-height: 1.43; + color: #8e8ea9; + opacity: 1; +} + +.c30 textarea:-ms-input-placeholder { + font-weight: 400; + font-size: 0.875rem; + line-height: 1.43; + color: #8e8ea9; + opacity: 1; +} + +.c30 textarea::placeholder { + font-weight: 400; + font-size: 0.875rem; + line-height: 1.43; + color: #8e8ea9; + opacity: 1; +} + +@media (max-width:68.75rem) { + .c24 { + grid-column: span; + } +} + +@media (max-width:34.375rem) { + .c24 { + grid-column: span 12; + } +} + +
+
+
+
+
+ +
+
+

+ Create API Token +

+
+
+ +
+
+
+
+
+
+
+
+

+ Details +

+
+
+
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + Expiration date: Unlimited + +
+
+
+
+
+
+ + + +
+

+

+

+ +`; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/tests/index.test.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/tests/index.test.js new file mode 100644 index 0000000000..841961c905 --- /dev/null +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/tests/index.test.js @@ -0,0 +1,114 @@ +import React from 'react'; +import { render, waitFor } from '@testing-library/react'; +import { IntlProvider } from 'react-intl'; +import { Router, Route } from 'react-router-dom'; +import { createMemoryHistory } from 'history'; +import { QueryClient, QueryClientProvider } from 'react-query'; +import { lightTheme, darkTheme } from '@strapi/design-system'; +import Theme from '../../../../../../components/Theme'; +import ThemeToggleProvider from '../../../../../../components/ThemeToggleProvider'; +import EditView from '../index'; +import { data } from '../utils/tests/dataMock'; + +jest.mock('@strapi/helper-plugin', () => ({ + ...jest.requireActual('@strapi/helper-plugin'), + useNotification: jest.fn(), + useFocusWhenNavigate: jest.fn(), + useTracking: jest.fn(() => ({ trackUsage: jest.fn() })), + useRBAC: jest.fn(() => ({ + allowedActions: { + canCreate: true, + canDelete: true, + canRead: true, + canUpdate: true, + canRegenerate: true, + }, + })), + useGuidedTour: jest.fn(() => ({ + startSection: jest.fn(), + })), + useOverlayBlocker: jest.fn(() => ({ + lockApp: jest.fn(), + unlockApp: jest.fn(), + })), + useFetchClient: jest.fn().mockReturnValue({ + get: jest.fn().mockImplementation((path) => { + if (path === '/admin/content-api/permissions') { + return { data }; + } + + return { + data: { + data: { + id: '1', + name: 'My super token', + description: 'This describe my super token', + type: 'read-only', + createdAt: '2021-11-15T00:00:00.000Z', + permissions: [], + }, + }, + }; + }), + }), +})); + +jest.spyOn(Date, 'now').mockImplementation(() => new Date('2015-10-01T08:00:00.000Z')); + +const client = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + }, + }, +}); + +const makeApp = (history) => { + return ( + + + + + + + + + + + + + + ); +}; + +describe('ADMIN | Pages | TRANSFER TOKENS | EditView', () => { + afterAll(() => { + jest.resetAllMocks(); + }); + + it('renders and matches the snapshot when creating token', async () => { + const history = createMemoryHistory(); + const App = makeApp(history); + const { container } = render(App); + + history.push('/settings/transfer-tokens/create'); + + expect(container).toMatchSnapshot(); + }); + + it('renders and matches the snapshot when editing existing token', async () => { + const history = createMemoryHistory(); + const App = makeApp(history); + const { container, getByText } = render(App); + + history.push('/settings/transfer-tokens/1'); + + await waitFor(() => { + expect(getByText('My super token')).toBeInTheDocument(); + expect(getByText('This describe my super token')).toBeInTheDocument(); + expect(getByText('Regenerate')).toBeInTheDocument(); + }); + + expect(container).toMatchSnapshot(); + }); +}); diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/index.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/index.js index b88422c87e..827bafb35e 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/index.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/index.js @@ -1,5 +1,4 @@ import getDateOfExpiration from './getDateOfExpiration'; import schema from './schema'; -import transformPermissionsData from './transformPermissionsData'; -export { getDateOfExpiration, schema, transformPermissionsData }; +export { getDateOfExpiration, schema }; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/tests/dataMock.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/tests/dataMock.js new file mode 100644 index 0000000000..8f23118000 --- /dev/null +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/tests/dataMock.js @@ -0,0 +1,14 @@ +export const data = { + data: { + 'api::address': { + controllers: { + address: ['find', 'findOne'], + }, + }, + 'api::category': { + controllers: { + category: ['find', 'findOne', 'create', 'update', 'delete', 'createLocalization'], + }, + }, + }, +}; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/tests/getDateOfExpiration.test.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/tests/getDateOfExpiration.test.js new file mode 100644 index 0000000000..9eb0ba3e27 --- /dev/null +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/tests/getDateOfExpiration.test.js @@ -0,0 +1,14 @@ +import getDateOfExpiration from '../getDateOfExpiration'; + +const createdAt = '2022-07-05T12:16:56.821Z'; +const duration = 604800000; + +describe('ADMIN | Pages | TRANSFER TOKENS | EditView', () => { + it('should return a formated date of expiration', () => { + expect(getDateOfExpiration(createdAt, duration)).toBe('July 12th, 2022'); + }); + + it('should return a formated date in french', () => { + expect(getDateOfExpiration(createdAt, duration, 'fr')).toBe('12 juillet 2022'); + }); +}); diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/transformPermissionsData.js b/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/transformPermissionsData.js deleted file mode 100644 index 6576c63306..0000000000 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/transformPermissionsData.js +++ /dev/null @@ -1,36 +0,0 @@ -import { flatten } from 'lodash'; - -const transformPermissionsData = (data) => { - const layout = { - allActionsIds: [], - permissions: [], - }; - - layout.permissions = Object.keys(data).map((apiId) => ({ - apiId, - label: apiId.split('::')[1], - controllers: flatten( - Object.keys(data[apiId].controllers).map((controller) => ({ - controller, - actions: flatten( - data[apiId].controllers[controller].map((action) => { - const actionId = `${apiId}.${controller}.${action}`; - - if (apiId.includes('api::')) { - layout.allActionsIds.push(actionId); - } - - return { - action, - actionId, - }; - }) - ), - })) - ), - })); - - return layout; -}; - -export default transformPermissionsData;