Skip to content
This repository was archived by the owner on May 13, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type TCreateTokenField = {
>;
form_is_cleared: boolean;
setFormIsCleared: Dispatch<SetStateAction<boolean>>;
setHideRestriction: Dispatch<SetStateAction<boolean>>;
is_toggle: boolean;
setToggleModal: Dispatch<SetStateAction<boolean>>;
};
Expand All @@ -28,6 +29,7 @@ const CreateTokenField = ({
register,
form_is_cleared,
setFormIsCleared,
setHideRestriction,
is_toggle,
setToggleModal,
}: TCreateTokenField) => {
Expand All @@ -54,6 +56,11 @@ const CreateTokenField = ({
const disable_button = token_name_exists || Object.keys(errors).length > 0 || input_value === '';
const error_border_active = token_name_exists || errors.name;

useEffect(() => {
if (error_border_active) {
setHideRestriction(true);
}
}, [error_border_active, setHideRestriction]);
return (
<React.Fragment>
<div className={styles.step_title}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import userEvent from '@testing-library/user-event';
import ApiTokenForm from '../api-token.form';
import useCreateToken from '../../../hooks/useCreateToken';
import useApiToken from '@site/src/hooks/useApiToken';
import TokenNameRestrictions from '../../TokenNameRestrictions/TokenNameRestrictions';

jest.mock('@site/src/hooks/useApiToken');

Expand Down Expand Up @@ -139,6 +140,14 @@ describe('Home Page', () => {
expect(error).toBeVisible;
});

it('should hide restrictions if error is present', async () => {
const nameInput = screen.getByRole('textbox');
const restrictions = screen.getByRole('list');
expect(restrictions).toBeVisible();
await userEvent.type(nameInput, 'testtoken1');
expect(restrictions).not.toBeVisible();
});

it('Should not create token when name input is empty', async () => {
const nameInput = screen.getByRole('textbox');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ form {
display: flex;
position: relative;
box-sizing: border-box;
margin: rem(1) 0;
&:hover {
border: 1px solid var(--colors-greyLight600);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { HTMLAttributes, useCallback, useState } from 'react';
import React, { HTMLAttributes, useCallback, useEffect, useState } from 'react';
import { Text } from '@deriv/ui';
import { useForm } from 'react-hook-form';
import { Circles } from 'react-loader-spinner';
Expand All @@ -8,6 +8,7 @@ import ApiTokenCard from '../ApiTokenCard';
import useCreateToken from '@site/src/features/dashboard/hooks/useCreateToken';
import * as yup from 'yup';
import styles from './api-token.form.module.scss';
import TokenNameRestrictions from '../TokenNameRestrictions/TokenNameRestrictions';
import CreateTokenField from './CreateTokenField';

const schema = yup
Expand Down Expand Up @@ -79,6 +80,7 @@ const scopes: TScope[] = [

const ApiTokenForm = (props: HTMLAttributes<HTMLFormElement>) => {
const { createToken, isCreatingToken } = useCreateToken();
const [hiderestrictions, setHideRestrictions] = useState(false);
const [form_is_cleared, setFormIsCleared] = useState(false);
const [is_toggle, setToggleModal] = useState(false);

Expand All @@ -93,7 +95,6 @@ const ApiTokenForm = (props: HTMLAttributes<HTMLFormElement>) => {
resolver: yupResolver(schema),
mode: 'all',
});

const onSubmit = useCallback(
(data: TApiTokenForm) => {
const { name } = data;
Expand All @@ -120,6 +121,10 @@ const ApiTokenForm = (props: HTMLAttributes<HTMLFormElement>) => {
[getValues, setValue],
);

useEffect(() => {
errors.name?.message ? setHideRestrictions(true) : setHideRestrictions(false);
}, [errors.name?.message]);

return (
<form role={'form'} onSubmit={handleSubmit(onSubmit)} {...props}>
<div className={styles.steps_line} />
Expand Down Expand Up @@ -159,9 +164,11 @@ const ApiTokenForm = (props: HTMLAttributes<HTMLFormElement>) => {
errors={errors}
form_is_cleared={form_is_cleared}
setFormIsCleared={setFormIsCleared}
setHideRestriction={setHideRestrictions}
is_toggle={is_toggle}
setToggleModal={setToggleModal}
/>
{!hiderestrictions && <TokenNameRestrictions />}
<div className={styles.step_title}>
<div className={`${styles.third_step} ${styles.step}`}>
<Text as={'p'} type={'paragraph-1'} data-testid={'third-step-title'}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@use 'src/styles/utility' as *;

.tokenrestrictions {
font-size: rem(1.4);
font-weight: 400;
line-height: 18px;
padding-left: rem(2.8);
margin-top: rem(1);
color: var(--colors-greyLight600);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import styles from './TokenNameRestrictions.module.scss';

const TokenNameRestrictions = () => {
return (
<ol className={styles.tokenrestrictions}>
<li>Only alphanumeric characters with spaces and underscores are allowed.</li>
<li>Only 2-32 characters are allowed</li>
<li>No duplicate token names are allowed for the same account.</li>
<li>
{
'No keywords "deriv" or "binary" or words that look similar, e.g. "_binary_" or "d3eriv" are allowed.'
}
</li>
</ol>
);
};

export default TokenNameRestrictions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import { render, screen } from '@site/src/test-utils';
import TokenNameRestrictions from '../TokenNameRestrictions';

describe('Restrictions for App name', () => {
beforeEach(() => {
render(<TokenNameRestrictions />);
});
it('Should render the list', () => {
const RestrictonList = screen.getByRole('list');
expect(RestrictonList).toBeInTheDocument();
});

it('Should display correct content inside list items', () => {
const listItem1 = screen.getByText(
'Only alphanumeric characters with spaces and underscores are allowed.',
);
const listItem2 = screen.getByText('Only 2-32 characters are allowed');
const listItem3 = screen.getByText(
'No duplicate token names are allowed for the same account.',
);
const listItem4 = screen.getByText(
'No keywords "deriv" or "binary" or words that look similar, e.g. "_binary_" or "d3eriv" are allowed.',
);

expect(listItem1).toBeInTheDocument();
expect(listItem2).toBeInTheDocument();
expect(listItem3).toBeInTheDocument();
expect(listItem4).toBeInTheDocument();
});
});