From 54429517a901b9184d839324a2fecd60bdd405d7 Mon Sep 17 00:00:00 2001 From: soupette Date: Wed, 1 Sep 2021 07:55:48 +0200 Subject: [PATCH] Add tests Signed-off-by: soupette --- .../TableHead/index.js | 2 +- .../TableRows/index.js | 0 .../ListPage/{Table => DynamicTable}/index.js | 3 +- .../ListPage/DynamicTable/tests/index.test.js | 575 ++++++++++++++++++ .../admin/src/pages/Users/ListPage/index.js | 13 +- .../pages/Users/ListPage/tests/index.test.js | 395 ++++++++++++ .../pages/Users/ListPage/tests/init.test.js | 11 - .../Users/ListPage/tests/utils/server.js | 54 ++ .../Users/ListPage/utils/tableHeaders.js | 8 + .../Webhooks/ListView/tests/index.test.js | 71 +-- .../src/components/EmptyBodyTable/index.js | 4 +- .../src/components/EmptyStateLayout/index.js | 8 +- .../src/pages/Providers/tests/index.test.js | 70 +-- 13 files changed, 1124 insertions(+), 90 deletions(-) rename packages/core/admin/admin/src/pages/Users/ListPage/{Table => DynamicTable}/TableHead/index.js (98%) rename packages/core/admin/admin/src/pages/Users/ListPage/{Table => DynamicTable}/TableRows/index.js (100%) rename packages/core/admin/admin/src/pages/Users/ListPage/{Table => DynamicTable}/index.js (96%) create mode 100644 packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/tests/index.test.js create mode 100644 packages/core/admin/admin/src/pages/Users/ListPage/tests/index.test.js delete mode 100644 packages/core/admin/admin/src/pages/Users/ListPage/tests/init.test.js create mode 100644 packages/core/admin/admin/src/pages/Users/ListPage/tests/utils/server.js diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/Table/TableHead/index.js b/packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/TableHead/index.js similarity index 98% rename from packages/core/admin/admin/src/pages/Users/ListPage/Table/TableHead/index.js rename to packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/TableHead/index.js index a1797904ee..22812a5110 100644 --- a/packages/core/admin/admin/src/pages/Users/ListPage/Table/TableHead/index.js +++ b/packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/TableHead/index.js @@ -21,7 +21,7 @@ const TableHead = ({ withBulkActions, }) => { const [{ query }, setQuery] = useQueryParams(); - const sort = query.sort; + const sort = query.sort || ''; const [sortBy, sortOrder] = sort.split(':'); const isIndeterminate = !areAllEntriesSelected && entriesToDelete.length; diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/Table/TableRows/index.js b/packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/TableRows/index.js similarity index 100% rename from packages/core/admin/admin/src/pages/Users/ListPage/Table/TableRows/index.js rename to packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/TableRows/index.js diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/Table/index.js b/packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/index.js similarity index 96% rename from packages/core/admin/admin/src/pages/Users/ListPage/Table/index.js rename to packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/index.js index 3d0845d9c9..6055873365 100644 --- a/packages/core/admin/admin/src/pages/Users/ListPage/Table/index.js +++ b/packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/index.js @@ -9,7 +9,7 @@ const Table = ({ canDelete, canUpdate, headers, rows, withBulkActions, withMainA const [entriesToDelete, setEntriesToDelete] = useState([]); const [{ query }] = useQueryParams(); const ROW_COUNT = rows.length + 1; - const COL_COUNT = 7; + const COL_COUNT = headers.length + (withBulkActions ? 1 : 0) + (withMainAction ? 1 : 0); const hasFilters = query.filters !== undefined; const areAllEntriesSelected = entriesToDelete.length === rows.length && rows.length > 0; @@ -56,7 +56,6 @@ const Table = ({ canDelete, canUpdate, headers, rows, withBulkActions, withMainA canDelete={canDelete} canUpdate={canUpdate} entriesToDelete={entriesToDelete} - data={rows} headers={headers} onSelectRow={handleSelectRow} rows={rows} diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/tests/index.test.js b/packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/tests/index.test.js new file mode 100644 index 0000000000..9fd53fa5cf --- /dev/null +++ b/packages/core/admin/admin/src/pages/Users/ListPage/DynamicTable/tests/index.test.js @@ -0,0 +1,575 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { IntlProvider } from 'react-intl'; +import { Router } from 'react-router-dom'; +import { createMemoryHistory } from 'history'; +import { useQueryParams } from '@strapi/helper-plugin'; +import Theme from '../../../../../components/Theme'; +import DynamicTable from '../index'; + +jest.mock('@strapi/helper-plugin', () => ({ + ...jest.requireActual('@strapi/helper-plugin'), + useQueryParams: jest.fn(() => [{ query: {} }, jest.fn()]), +})); + +// eslint-disable-next-line react/prop-types +const makeApp = ({ + canDelete = true, + canUpdate = true, + headers, + rows = [], + withBulkActions = true, + withMainAction = true, +}) => ( + + + + + + + +); + +describe('DynamicTable', () => { + it('renders and matches the snapshot', () => { + const headers = [ + { + name: 'firstname', + key: 'firstname', + metadatas: { label: 'Name', sortable: true }, + }, + { + key: 'email', + name: 'email', + metadatas: { label: 'Email', sortable: true }, + }, + ]; + const app = makeApp({ headers }); + const { container, getByText } = render(app); + + expect(container.firstChild).toMatchInlineSnapshot(` + .c24 { + font-weight: 500; + font-size: 1rem; + line-height: 1.25; + color: #666687; + } + + .c19 { + background: #ffffff; + padding: 64px; + } + + .c21 { + padding-bottom: 24px; + } + + .c23 { + padding-bottom: 16px; + } + + .c20 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + text-align: center; + } + + .c22 svg { + height: 5.5rem; + } + + .c16 tr:last-of-type { + border-bottom: none; + } + + .c17 { + border-bottom: 1px solid #eaeaef; + } + + .c17 td, + .c17 th { + padding: 16px; + } + + .c17 td:first-of-type, + .c17 th:first-of-type { + padding: 0 4px; + } + + .c18 { + vertical-align: middle; + text-align: left; + color: #666687; + outline-offset: -4px; + } + + .c18 input { + vertical-align: sub; + } + + .c12 { + font-weight: 400; + font-size: 0.875rem; + line-height: 1.43; + color: #32324d; + } + + .c13 { + font-weight: 600; + line-height: 1.14; + } + + .c14 { + font-weight: 600; + font-size: 0.6875rem; + line-height: 1.45; + text-transform: uppercase; + } + + .c0 { + box-shadow: 0px 1px 4px rgba(33,33,52,0.1); + } + + .c1 { + background: #ffffff; + } + + .c3 { + padding-right: 24px; + padding-left: 24px; + } + + .c9 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + } + + .c10 { + margin: 0; + height: 18px; + min-width: 18px; + border-radius: 4px; + border: 1px solid #c0c0cf; + -webkit-appearance: none; + background-color: #ffffff; + } + + .c10:checked { + background-color: #4945ff; + border: 1px solid #4945ff; + } + + .c10:checked:after { + content: ''; + display: block; + position: relative; + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iOCIgdmlld0JveD0iMCAwIDEwIDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGgKICAgIGQ9Ik04LjU1MzIzIDAuMzk2OTczQzguNjMxMzUgMC4zMTYzNTUgOC43NjA1MSAwLjMxNTgxMSA4LjgzOTMxIDAuMzk1NzY4TDkuODYyNTYgMS40MzQwN0M5LjkzODkzIDEuNTExNTcgOS45MzkzNSAxLjYzNTkgOS44NjM0OSAxLjcxMzlMNC4wNjQwMSA3LjY3NzI0QzMuOTg1OSA3Ljc1NzU1IDMuODU3MDcgNy43NTgwNSAzLjc3ODM0IDcuNjc4MzRMMC4xMzg2NiAzLjk5MzMzQzAuMDYxNzc5OCAzLjkxNTQ5IDAuMDYxNzEwMiAzLjc5MDMyIDAuMTM4NTA0IDMuNzEyNEwxLjE2MjEzIDIuNjczNzJDMS4yNDAzOCAyLjU5NDMyIDEuMzY4NDMgMi41OTQyMiAxLjQ0NjggMi42NzM0OEwzLjkyMTc0IDUuMTc2NDdMOC41NTMyMyAwLjM5Njk3M1oiCiAgICBmaWxsPSJ3aGl0ZSIKICAvPgo8L3N2Zz4=) no-repeat no-repeat center center; + width: 10px; + height: 10px; + left: 50%; + top: 50%; + -webkit-transform: translateX(-50%) translateY(-50%); + -ms-transform: translateX(-50%) translateY(-50%); + transform: translateX(-50%) translateY(-50%); + } + + .c10:checked:disabled:after { + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iOCIgdmlld0JveD0iMCAwIDEwIDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGgKICAgIGQ9Ik04LjU1MzIzIDAuMzk2OTczQzguNjMxMzUgMC4zMTYzNTUgOC43NjA1MSAwLjMxNTgxMSA4LjgzOTMxIDAuMzk1NzY4TDkuODYyNTYgMS40MzQwN0M5LjkzODkzIDEuNTExNTcgOS45MzkzNSAxLjYzNTkgOS44NjM0OSAxLjcxMzlMNC4wNjQwMSA3LjY3NzI0QzMuOTg1OSA3Ljc1NzU1IDMuODU3MDcgNy43NTgwNSAzLjc3ODM0IDcuNjc4MzRMMC4xMzg2NiAzLjk5MzMzQzAuMDYxNzc5OCAzLjkxNTQ5IDAuMDYxNzEwMiAzLjc5MDMyIDAuMTM4NTA0IDMuNzEyNEwxLjE2MjEzIDIuNjczNzJDMS4yNDAzOCAyLjU5NDMyIDEuMzY4NDMgMi41OTQyMiAxLjQ0NjggMi42NzM0OEwzLjkyMTc0IDUuMTc2NDdMOC41NTMyMyAwLjM5Njk3M1oiCiAgICBmaWxsPSIjOEU4RUE5IgogIC8+Cjwvc3ZnPg==) no-repeat no-repeat center center; + } + + .c10:disabled { + background-color: #dcdce4; + border: 1px solid #c0c0cf; + } + + .c10:indeterminate { + background-color: #4945ff; + border: 1px solid #4945ff; + } + + .c10:indeterminate:after { + content: ''; + display: block; + position: relative; + color: white; + height: 2px; + width: 10px; + background-color: #ffffff; + left: 50%; + top: 50%; + -webkit-transform: translateX(-50%) translateY(-50%); + -ms-transform: translateX(-50%) translateY(-50%); + transform: translateX(-50%) translateY(-50%); + } + + .c10:indeterminate:disabled { + background-color: #dcdce4; + border: 1px solid #c0c0cf; + } + + .c10:indeterminate:disabled:after { + background-color: #8e8ea9; + } + + .c15 { + 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; + } + + .c5 { + width: 100%; + white-space: nowrap; + } + + .c2 { + position: relative; + border-radius: 4px 4px 0 0; + } + + .c2:before { + background: linear-gradient(90deg,#000000 0%,rgba(0,0,0,0) 100%); + opacity: 0.2; + position: absolute; + height: 100%; + box-shadow: 0px 1px 4px rgba(33,33,52,0.1); + width: 8px; + left: 0; + } + + .c2:after { + background: linear-gradient(270deg,#000000 0%,rgba(0,0,0,0) 100%); + opacity: 0.2; + position: absolute; + height: 100%; + box-shadow: 0px 1px 4px rgba(33,33,52,0.1); + width: 8px; + right: 0; + top: 0; + } + + .c4 { + overflow-x: auto; + } + + .c6 { + border-bottom: 1px solid #eaeaef; + } + + .c7 { + border-bottom: 1px solid #eaeaef; + } + + .c7 td, + .c7 th { + padding: 16px; + } + + .c7 td:first-of-type, + .c7 th:first-of-type { + padding: 0 4px; + } + + .c8 { + vertical-align: middle; + text-align: left; + color: #666687; + outline-offset: -4px; + } + + .c8 input { + vertical-align: sub; + } + + .c11 svg { + height: 0.25rem; + } + +
+
+
+ + + + + + + + + + + + + + +
+
+ + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+
+ Actions +
+ +
+
+
+ +
+

+ You don't have any content yet... +

+
+
+
+
+
+
+ `); + + expect(getByText("You don't have any content yet...")).toBeInTheDocument(); + }); + + it('should show the empty state layout with the filter text when there is no content and some filters applied', () => { + useQueryParams.mockImplementationOnce(() => [ + { + query: { filters: { $and: [{ firstname: 'soup' }] } }, + }, + ]); + + const headers = [ + { + name: 'firstname', + key: 'firstname', + metadatas: { label: 'Name', sortable: true }, + }, + { + key: 'email', + name: 'email', + metadatas: { label: 'Email', sortable: true }, + }, + ]; + const app = makeApp({ headers }); + const { getByText } = render(app); + + expect(getByText('There are no Users with the applied filters...')).toBeInTheDocument(); + }); + + it('should show the data', () => { + const headers = [ + { + name: 'firstname', + key: 'firstname', + metadatas: { label: 'Name', sortable: true }, + }, + { + key: 'email', + name: 'email', + metadatas: { label: 'Email', sortable: true }, + }, + ]; + const rows = [ + { + id: 1, + firstname: 'soup', + }, + { + id: 2, + firstname: 'dummy', + email: 'dummy@strapi.io', + }, + ]; + const app = makeApp({ headers, rows }); + const { getByText } = render(app); + + expect(getByText('soup')).toBeInTheDocument(); + expect(getByText('-')).toBeInTheDocument(); + expect(getByText('dummy')).toBeInTheDocument(); + expect(getByText('dummy@strapi.io')).toBeInTheDocument(); + }); +}); diff --git a/packages/core/admin/admin/src/pages/Users/ListPage/index.js b/packages/core/admin/admin/src/pages/Users/ListPage/index.js index b4f6d59e73..6f9b6d33d9 100644 --- a/packages/core/admin/admin/src/pages/Users/ListPage/index.js +++ b/packages/core/admin/admin/src/pages/Users/ListPage/index.js @@ -17,7 +17,7 @@ import { useIntl } from 'react-intl'; import { useQuery } from 'react-query'; import get from 'lodash/get'; import adminPermissions from '../../../permissions'; -import Table from './Table'; +import DynamicTable from './DynamicTable'; import fetchData from './utils/api'; import tableHeaders from './utils/tableHeaders'; @@ -25,6 +25,7 @@ const ListPage = () => { const { allowedActions: { canCreate, canDelete, canRead, canUpdate }, } = useRBAC(adminPermissions.settings.users); + const toggleNotification = useNotification(); // const [isWarningDeleteAllOpened, setIsWarningDeleteAllOpened] = useState(false); @@ -232,7 +233,11 @@ const ListPage = () => { (status !== 'success' && status !== 'error') || (status === 'success' && isFetching); const createAction = canCreate ? ( -