From 08202bbed4ba328e58244d5e4e0299dc5841048e Mon Sep 17 00:00:00 2001 From: Liana Date: Tue, 15 Oct 2024 17:30:13 +0300 Subject: [PATCH] coomit before rebase --- .../DatasetUploader/DatasetUploader.tsx | 1 - .../FileStats/ModeButton/ModeButton.tsx | 2 +- .../client/src/components/Icon/Icon.test.tsx | 4 +- web-app/client/src/components/Icon/Icon.tsx | 2 +- .../Inputs/MultiSelect/MultiSelect.test.tsx | 77 +++++++++-------- .../Inputs/MultiSelect/MultiSelect.tsx | 7 +- .../Inputs/Password/Password.module.scss | 6 ++ .../Inputs/Password/Password.test.tsx | 52 +++++++++++ .../components/Inputs/Password/Password.tsx | 86 +++++++++++++++++++ .../Inputs/Password/TestPassword.tsx | 49 +++++++++++ .../src/components/Inputs/Password/index.ts | 1 + .../components/Inputs/Select/Select.test.tsx | 64 +++++++------- .../src/components/Inputs/Select/Select.tsx | 8 +- .../LogInModal/LogInModal.module.scss | 7 -- .../src/components/LogInModal/LogInModal.tsx | 4 +- .../src/components/LogInModal/steps/LogIn.tsx | 12 +-- .../LogInModal/steps/Password.test.tsx | 64 -------------- .../{Password.tsx => RestorePassword.tsx} | 24 ++---- .../LogInModal/steps/TestPassword.tsx | 59 ------------- .../ModalContainer/ModalContainer.test.tsx | 21 +++-- .../ModalContainer/ModalContainer.tsx | 2 +- .../components/SignUpModal/SignUpModal.tsx | 2 +- .../components/SignUpModal/steps/CoreInfo.tsx | 32 ++----- .../src/components/Tooltip/Tooltip.test.tsx | 12 ++- .../client/src/components/Tooltip/Tooltip.tsx | 1 - .../client/src/pages/reports/dependencies.tsx | 7 +- .../src/pages/reports/metric-dependencies.tsx | 3 +- .../tabs/AccountSettings/AccountSettings.tsx | 5 +- .../ChangePasswordModal.tsx | 49 +++++------ 29 files changed, 347 insertions(+), 316 deletions(-) create mode 100644 web-app/client/src/components/Inputs/Password/Password.module.scss create mode 100644 web-app/client/src/components/Inputs/Password/Password.test.tsx create mode 100644 web-app/client/src/components/Inputs/Password/Password.tsx create mode 100644 web-app/client/src/components/Inputs/Password/TestPassword.tsx create mode 100644 web-app/client/src/components/Inputs/Password/index.ts delete mode 100644 web-app/client/src/components/LogInModal/steps/Password.test.tsx rename web-app/client/src/components/LogInModal/steps/{Password.tsx => RestorePassword.tsx} (73%) delete mode 100644 web-app/client/src/components/LogInModal/steps/TestPassword.tsx diff --git a/web-app/client/src/components/DatasetUploader/DatasetUploader.tsx b/web-app/client/src/components/DatasetUploader/DatasetUploader.tsx index 656c54cdc..0f389c786 100644 --- a/web-app/client/src/components/DatasetUploader/DatasetUploader.tsx +++ b/web-app/client/src/components/DatasetUploader/DatasetUploader.tsx @@ -23,7 +23,6 @@ type Props = { const DatasetUploader: FC = ({ onUpload, isOpen, setIsOpen }) => { const inputFile = useRef(null); - //const [isOpen, setIsOpen] = useState(false); const [filesState, setFiles] = useState(null); const [isFileDragged, setIsFileDragged] = useState(false); const [isDraggedInside, setIsDraggedInside] = useState(false); diff --git a/web-app/client/src/components/FileStats/ModeButton/ModeButton.tsx b/web-app/client/src/components/FileStats/ModeButton/ModeButton.tsx index 5de5f9d75..7fe40c324 100644 --- a/web-app/client/src/components/FileStats/ModeButton/ModeButton.tsx +++ b/web-app/client/src/components/FileStats/ModeButton/ModeButton.tsx @@ -15,7 +15,7 @@ export const ModeButton: FC = ({ }: ModeButtonProps) => ( + + + ); +}; diff --git a/web-app/client/src/components/Inputs/Password/index.ts b/web-app/client/src/components/Inputs/Password/index.ts new file mode 100644 index 000000000..da970e76d --- /dev/null +++ b/web-app/client/src/components/Inputs/Password/index.ts @@ -0,0 +1 @@ +export { default } from './Password'; diff --git a/web-app/client/src/components/Inputs/Select/Select.test.tsx b/web-app/client/src/components/Inputs/Select/Select.test.tsx index a2849e9b4..86ee57cd8 100644 --- a/web-app/client/src/components/Inputs/Select/Select.test.tsx +++ b/web-app/client/src/components/Inputs/Select/Select.test.tsx @@ -1,46 +1,46 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import Select from './Select'; -import { countries } from 'countries-list'; const user = userEvent.setup(); +const options = [ + { label: 'aaa', value: 1 }, + { label: 'bbb', value: 2 }, + { label: 'ccc', value: 3 }, +]; -describe('Testing select dropdown', () => { +const renderAndOpen = async () => { + render( + <> + ({ - label: `${emoji} ${native}`, - value: name, - }))} - /> -
Outside
- , - ); - const trigger = screen.getByText('Germany'); - await user.click(trigger); - const andorra = () => screen.getByText('🇦🇩 Andorra'); - const anguilla = screen.getByText('🇦🇮 Anguilla'); - const anguillaQuery = () => screen.queryByText('🇦🇮 Anguilla'); - expect(andorra()); - expect(anguilla); + test('Should open dropdown', async () => { + await renderAndOpen(); + expect(screen.getByText('aaa')); + }); - await user.click(andorra()); - expect(andorra()); - expect(anguillaQuery()).toBeNull(); + test('Should select option', async () => { + await renderAndOpen(); + await user.click(screen.getByText('aaa')); + expect(screen.queryByText('aaa')).toBeTruthy(); + expect(screen.queryByText('bbb')).toBeNull(); + }); - await user.click(andorra()); - expect(anguillaQuery()).not.toBeNull(); - await user.click(screen.getByText('Outside')); - expect(anguillaQuery()).toBeNull(); + test('Should close by click outside', async () => { + await renderAndOpen(); + const outside = screen.getByText('Outside'); + await user.click(outside); + expect(screen.queryByText('aaa')).toBeNull(); }); }); diff --git a/web-app/client/src/components/Inputs/Select/Select.tsx b/web-app/client/src/components/Inputs/Select/Select.tsx index 65f4caa14..6ed7b64d9 100644 --- a/web-app/client/src/components/Inputs/Select/Select.tsx +++ b/web-app/client/src/components/Inputs/Select/Select.tsx @@ -43,17 +43,13 @@ const Select: ForwardRefRenderFunction = ( {tooltip && {tooltip}} { - return { ...base }; - }, - }} menuPortalTarget={portalRoot} - menuPosition='fixed' + menuPosition="fixed" components={{ ...customComponents, ...components }} /> {error &&

{error}

} diff --git a/web-app/client/src/components/LogInModal/LogInModal.module.scss b/web-app/client/src/components/LogInModal/LogInModal.module.scss index 4fe8fb31b..7cb183d12 100644 --- a/web-app/client/src/components/LogInModal/LogInModal.module.scss +++ b/web-app/client/src/components/LogInModal/LogInModal.module.scss @@ -24,10 +24,3 @@ gap: 16px; } } - -.tooltip { - ul { - list-style: disc; - margin-left: 24px; - } -} diff --git a/web-app/client/src/components/LogInModal/LogInModal.tsx b/web-app/client/src/components/LogInModal/LogInModal.tsx index 30c546556..323e5ce75 100644 --- a/web-app/client/src/components/LogInModal/LogInModal.tsx +++ b/web-app/client/src/components/LogInModal/LogInModal.tsx @@ -4,7 +4,7 @@ import ModalContainer, { ModalProps } from '../ModalContainer'; import Code from './steps/Code'; import Email from './steps/Email'; import LogIn from './steps/LogIn'; -import Password from './steps/Password'; +import RestorePassword from './steps/RestorePassword'; const LogInModal: FC = ({ isOpen, onClose }) => { const [stage, setStage] = useState(1); @@ -29,7 +29,7 @@ const LogInModal: FC = ({ isOpen, onClose }) => { )} {stage === 3 && } - {stage === 4 && } + {stage === 4 && } = ({ onSuccess, onRecovery }) => { const { applyTokens } = useAuthContext(); const { + control, register, handleSubmit, formState: { errors, isSubmitting }, @@ -73,14 +75,12 @@ const LogIn: FC = ({ onSuccess, onRecovery }) => { })} error={errors.email?.message} /> - diff --git a/web-app/client/src/components/LogInModal/steps/Password.test.tsx b/web-app/client/src/components/LogInModal/steps/Password.test.tsx deleted file mode 100644 index bf5236c3d..000000000 --- a/web-app/client/src/components/LogInModal/steps/Password.test.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { fireEvent, render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; - -import { TestPassword } from './TestPassword'; - -const user = userEvent.setup(); - -describe('Testing variants for password', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - -const prepare = () => { - render(); - const input = screen.getByPlaceholderText('admin1234'); - const trigger = screen.getByRole('submit'); - const errorQuery = () => - screen.queryByText('The password does not match the pattern (see tooltip)'); - return { input, trigger, errorQuery }; -}; - -test('Too shot password', async () => { - const { input, trigger, errorQuery } = prepare(); - fireEvent.change(input, { target: { value: 'Aa23.0' } }); - await user.click(trigger); - expect(errorQuery()).not.toBeNull(); -}); - -test('Password without digit', async () => { - const { input, trigger, errorQuery } = prepare(); - fireEvent.change(input, { target: { value: 'Aaaaaa.a' } }); - await user.click(trigger); - expect(errorQuery()).not.toBeNull(); -}); - -test('Password without special symbol', async () => { - const { input, trigger, errorQuery } = prepare(); - fireEvent.change(input, { target: { value: 'Aaaa2312' } }); - await user.click(trigger); - expect(errorQuery()).not.toBeNull(); -}); - -test('Password without uppercase letter', async () => { - const { input, trigger, errorQuery } = prepare(); - fireEvent.change(input, { target: { value: 'aaaa23.0' } }); - await user.click(trigger); - expect(errorQuery()).not.toBeNull(); -}); - -test('Password without lowercase letter', async () => { - const { input, trigger, errorQuery } = prepare(); - fireEvent.change(input, { target: { value: 'AAAA23.0' } }); - await user.click(trigger); - expect(errorQuery()).not.toBeNull(); -}); - -test('Good password', async () => { - const { input, trigger, errorQuery } = prepare(); - fireEvent.change(input, { target: { value: 'Aaaa23.0' } }); - await user.click(trigger); - expect(errorQuery()).toBeNull(); -}); -}); - diff --git a/web-app/client/src/components/LogInModal/steps/Password.tsx b/web-app/client/src/components/LogInModal/steps/RestorePassword.tsx similarity index 73% rename from web-app/client/src/components/LogInModal/steps/Password.tsx rename to web-app/client/src/components/LogInModal/steps/RestorePassword.tsx index b33d89727..6eeded3f5 100644 --- a/web-app/client/src/components/LogInModal/steps/Password.tsx +++ b/web-app/client/src/components/LogInModal/steps/RestorePassword.tsx @@ -1,10 +1,7 @@ import { useMutation } from '@apollo/client'; import { FC } from 'react'; import { useForm } from 'react-hook-form'; -import isStrongPassword from 'validator/lib/isStrongPassword'; import Button from '@components/Button'; -import { Text } from '@components/Inputs'; -import { passwordTooltip } from '@components/SignUpModal/steps/CoreInfo'; import { changePassword, changePasswordVariables, @@ -13,6 +10,7 @@ import { CHANGE_PASSWORD } from '@graphql/operations/mutations/changePassword'; import { useAuthContext } from '@hooks/useAuthContext'; import hashPassword from '@utils/hashPassword'; import styles from '../LogInModal.module.scss'; +import Password from '@components/Inputs/Password'; type Inputs = { password: string; @@ -27,14 +25,14 @@ interface Props { onSuccess: () => void; } -const Password: FC = ({ onSuccess, email }) => { +const RestorePassword: FC = ({ onSuccess, email }) => { const { applyTokens } = useAuthContext(); const [changePassword] = useMutation( CHANGE_PASSWORD, ); const { - register, + control, handleSubmit, formState: { errors, isSubmitting }, } = useForm({ @@ -60,18 +58,12 @@ const Password: FC = ({ onSuccess, email }) => {

Recovery

- - isStrongPassword(value) || - 'The password does not match the pattern (see tooltip)', - })} - error={errors.password?.message} + rules={{ required: 'Required' }} />
@@ -85,4 +77,4 @@ const Password: FC = ({ onSuccess, email }) => { ); }; -export default Password; +export default RestorePassword; diff --git a/web-app/client/src/components/LogInModal/steps/TestPassword.tsx b/web-app/client/src/components/LogInModal/steps/TestPassword.tsx deleted file mode 100644 index f9bef3834..000000000 --- a/web-app/client/src/components/LogInModal/steps/TestPassword.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { FC } from 'react'; -import { useForm } from 'react-hook-form'; -import isStrongPassword from 'validator/lib/isStrongPassword'; -import Button from '@components/Button'; -import { Text } from '@components/Inputs'; -import { passwordTooltip } from '@components/SignUpModal/steps/CoreInfo'; -import styles from '../LogInModal.module.scss'; - -type Inputs = { - password: string; -}; - -const defaultValues: Inputs = { - password: '', -}; - -export const TestPassword: FC = () => { - - const { - register, - handleSubmit, - formState: { errors, isSubmitting }, - } = useForm({ - defaultValues, - }); - - const onSubmit = handleSubmit(async (values) => { - console.log('submit') - }); - - return ( - <> -

Recovery

- -
- - isStrongPassword(value) || - 'The password does not match the pattern (see tooltip)', - })} - error={errors.password?.message} - /> -
- -
- -
- - - ); -}; diff --git a/web-app/client/src/components/ModalContainer/ModalContainer.test.tsx b/web-app/client/src/components/ModalContainer/ModalContainer.test.tsx index 516d72fc6..a8dbbbcdf 100644 --- a/web-app/client/src/components/ModalContainer/ModalContainer.test.tsx +++ b/web-app/client/src/components/ModalContainer/ModalContainer.test.tsx @@ -4,24 +4,31 @@ import { TestModal } from './TestModal'; const user = userEvent.setup(); -describe('Testing Modal Container as Test Modal window', () => { +describe('Modal Container as Test Modal window', () => { beforeEach(() => { jest.clearAllMocks(); }); +const renderAndOpen = async () => { + render(); + const triggerOpen = screen.getByText('Test Button'); + await user.click(triggerOpen); +}; - test('Should open, close by button and click outside', async () => { - render(); - - const triggerOpen = screen.getByText('Test Button'); - await user.click(triggerOpen); + test('Should open', async () => { + await renderAndOpen(); expect(screen.getByText('Test Modal')); + }); + test('Should close by button', async () => { + await renderAndOpen(); const triggerClose = screen.getByRole('close'); await user.click(triggerClose); expect(screen.queryByText('Test Modal')).toBeNull(); + }); - await user.click(triggerOpen); + test('Should close by click outside', async () => { + await renderAndOpen(); await user.click(screen.getByText('Outside')); expect(screen.queryByText('Test Modal')).toBeNull(); }); diff --git a/web-app/client/src/components/ModalContainer/ModalContainer.tsx b/web-app/client/src/components/ModalContainer/ModalContainer.tsx index e0981c90c..f424a932e 100644 --- a/web-app/client/src/components/ModalContainer/ModalContainer.tsx +++ b/web-app/client/src/components/ModalContainer/ModalContainer.tsx @@ -17,7 +17,7 @@ import styles from './ModalContainer.module.scss'; export interface ModalProps { onClose: () => void; className?: string; - isOpen: boolean; + isOpen?: boolean; } const ModalContainer: FCWithChildren = ({ diff --git a/web-app/client/src/components/SignUpModal/SignUpModal.tsx b/web-app/client/src/components/SignUpModal/SignUpModal.tsx index 77ce1bd8e..26fbed571 100644 --- a/web-app/client/src/components/SignUpModal/SignUpModal.tsx +++ b/web-app/client/src/components/SignUpModal/SignUpModal.tsx @@ -26,7 +26,7 @@ const SignUpModal: FC = ({ isOpen, onClose }) => { onCloseSuccessVerified} + onClose={onCloseSuccessVerified} /> ); diff --git a/web-app/client/src/components/SignUpModal/steps/CoreInfo.tsx b/web-app/client/src/components/SignUpModal/steps/CoreInfo.tsx index 73bad9513..8c2475da1 100644 --- a/web-app/client/src/components/SignUpModal/steps/CoreInfo.tsx +++ b/web-app/client/src/components/SignUpModal/steps/CoreInfo.tsx @@ -15,22 +15,10 @@ import { CREATE_USER } from '@graphql/operations/mutations/createUser'; import { useAuthContext } from '@hooks/useAuthContext'; import hashPassword from '@utils/hashPassword'; import styles from '../../LogInModal/LogInModal.module.scss'; +import Password from '@components/Inputs/Password'; const countryNames = Object.entries(countries).map(([, country]) => country); -export const passwordTooltip = ( -
- The password must contain -
    -
  • at least 8 characters
  • -
  • at least 1 uppercase letter
  • -
  • at least 1 lowercase letter
  • -
  • at least 1 digit
  • -
  • at least 1 special character
  • -
-
-); - type Inputs = { fullName: string; email: string; @@ -89,7 +77,6 @@ const CoreInfo: FC = ({ onSuccess }) => { } } catch (e) {} }); - return ( <>

Sign Up

@@ -121,21 +108,12 @@ const CoreInfo: FC = ({ onSuccess }) => { })} error={errors.email?.message} /> - { - return ( - isStrongPassword(value) || - 'The password does not match the pattern (see tooltip)' - ); - }, - })} - error={errors.password?.message} + rules={{ required: 'Required' }} /> { +describe('Tooltip', () => { beforeEach(() => { jest.clearAllMocks(); }); - test('Should open with text by hover and close by unhover', async () => { + const renderAndOpen = async () => { render(Test Tooltip); const trigger = screen.getByRole('img'); await user.hover(trigger); + return trigger + } + + test('Should open with text by hover', async () => { + await renderAndOpen() expect(screen.getByText(/test tooltip/i)); + }); + test('Should close by unhover', async () => { + const trigger = await renderAndOpen(); await user.unhover(trigger); expect(screen.queryByText(/test tooltip/i)).toBeNull(); }); diff --git a/web-app/client/src/components/Tooltip/Tooltip.tsx b/web-app/client/src/components/Tooltip/Tooltip.tsx index a85a4abd0..69d130625 100644 --- a/web-app/client/src/components/Tooltip/Tooltip.tsx +++ b/web-app/client/src/components/Tooltip/Tooltip.tsx @@ -49,7 +49,6 @@ const Tooltip: FCWithChildren = ({ position = 'top', children }) => { size={16} color={colors.primary[100]} className={styles.icon} - role='img' /> diff --git a/web-app/client/src/pages/reports/dependencies.tsx b/web-app/client/src/pages/reports/dependencies.tsx index 63db2cd46..fadb62c95 100644 --- a/web-app/client/src/pages/reports/dependencies.tsx +++ b/web-app/client/src/pages/reports/dependencies.tsx @@ -53,10 +53,9 @@ const ReportsDependencies: NextPageWithLayout = ({ defaultData }) => { taskInfo?.taskInfo.data.baseConfig.type; const algorithm: Algorithms = taskInfo?.taskInfo.data.baseConfig .algorithmName as Algorithms; - const title = - algorithm in approximateAlgorithms - ? 'Discovered approximate dependencies verified' - : 'Discovered functional dependencies'; + const title = approximateAlgorithms.includes(algorithm) + ? 'Discovered approximate dependencies verified' + : 'Discovered functional dependencies'; const methods = useFilters(primitive || PrimitiveType.FD); const { watch, register, setValue: setFilterParam } = methods; const { search, page, ordering, direction, showKeys } = watch(); diff --git a/web-app/client/src/pages/reports/metric-dependencies.tsx b/web-app/client/src/pages/reports/metric-dependencies.tsx index 003257812..47306fb6a 100644 --- a/web-app/client/src/pages/reports/metric-dependencies.tsx +++ b/web-app/client/src/pages/reports/metric-dependencies.tsx @@ -62,7 +62,6 @@ const ReportsMFD: NextPageWithLayout = () => { parameter, orderDirection, ); - const isHoldsTitile = !data.clustersTotalCount ? 'holds' : 'not holds'; useEffect(() => { if (!loading && !error && data) { @@ -155,7 +154,7 @@ const ReportsMFD: NextPageWithLayout = () => { return ( <> - + {isOrderingShown && ( { {isModalOpen && ( - setIsModalOpen(false)} /> + setIsModalOpen(false)} + /> )} ); diff --git a/web-app/client/src/routes/UserCabinet/tabs/AccountSettings/components/ChangePasswordModal/ChangePasswordModal.tsx b/web-app/client/src/routes/UserCabinet/tabs/AccountSettings/components/ChangePasswordModal/ChangePasswordModal.tsx index 853a1ed77..920f94fa0 100644 --- a/web-app/client/src/routes/UserCabinet/tabs/AccountSettings/components/ChangePasswordModal/ChangePasswordModal.tsx +++ b/web-app/client/src/routes/UserCabinet/tabs/AccountSettings/components/ChangePasswordModal/ChangePasswordModal.tsx @@ -1,9 +1,7 @@ import { useMutation } from '@apollo/client'; import { FC, useId } from 'react'; import { useForm } from 'react-hook-form'; -import isStrongPassword from 'validator/lib/isStrongPassword'; import Button from '@components/Button'; -import { Text } from '@components/Inputs'; import ModalContainer, { ModalProps } from '@components/ModalContainer'; import { changePassword, @@ -12,6 +10,7 @@ import { import { CHANGE_PASSWORD } from '@graphql/operations/mutations/changePassword'; import hashPassword from '@utils/hashPassword'; import styles from './ChangePasswordModal.module.scss'; +import Password from '@components/Inputs/Password'; type Inputs = { oldPassword: string; @@ -19,10 +18,9 @@ type Inputs = { repeatPassword: string; }; -const ChangePasswordModal: FC = ({ onClose }) => { +const ChangePasswordModal: FC = ({ isOpen, onClose }) => { const { - register, - formState: { errors }, + control, handleSubmit, } = useForm(); const formId = useId(); @@ -43,41 +41,34 @@ const ChangePasswordModal: FC = ({ onClose }) => { }); return ( - +

Change password

- - isStrongPassword(value) || 'Weak password', - })} - error={errors.newPassword?.message} + rules={{ required: 'Required' }} /> - isStrongPassword(value) || 'Weak password', - isSame: (value, { newPassword }) => - value === newPassword || 'Passwords do not match', - }, - })} - error={errors.repeatPassword?.message} + validate: (value, { newPassword }) => + value === newPassword || 'Passwords do not match', + }} />