Skip to content
This repository was archived by the owner on May 13, 2024. It is now read-only.

Commit 043cdc8

Browse files
authored
Merge pull request #203 from sanjam-deriv/restrictions
2 parents b8d742c + e614d3f commit 043cdc8

File tree

7 files changed

+85
-3
lines changed

7 files changed

+85
-3
lines changed

src/features/dashboard/components/ApiTokenForm/CreateTokenField/index.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type TCreateTokenField = {
1919
>;
2020
form_is_cleared: boolean;
2121
setFormIsCleared: Dispatch<SetStateAction<boolean>>;
22+
setHideRestriction: Dispatch<SetStateAction<boolean>>;
2223
is_toggle: boolean;
2324
setToggleModal: Dispatch<SetStateAction<boolean>>;
2425
};
@@ -28,6 +29,7 @@ const CreateTokenField = ({
2829
register,
2930
form_is_cleared,
3031
setFormIsCleared,
32+
setHideRestriction,
3133
is_toggle,
3234
setToggleModal,
3335
}: TCreateTokenField) => {
@@ -54,6 +56,11 @@ const CreateTokenField = ({
5456
const disable_button = token_name_exists || Object.keys(errors).length > 0 || input_value === '';
5557
const error_border_active = token_name_exists || errors.name;
5658

59+
useEffect(() => {
60+
if (error_border_active) {
61+
setHideRestriction(true);
62+
}
63+
}, [error_border_active, setHideRestriction]);
5764
return (
5865
<React.Fragment>
5966
<div className={styles.step_title}>

src/features/dashboard/components/ApiTokenForm/__tests__/api-token.form.test.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import userEvent from '@testing-library/user-event';
44
import ApiTokenForm from '../api-token.form';
55
import useCreateToken from '../../../hooks/useCreateToken';
66
import useApiToken from '@site/src/hooks/useApiToken';
7+
import TokenNameRestrictions from '../../TokenNameRestrictions/TokenNameRestrictions';
78

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

@@ -139,6 +140,14 @@ describe('Home Page', () => {
139140
expect(error).toBeVisible;
140141
});
141142

143+
it('should hide restrictions if error is present', async () => {
144+
const nameInput = screen.getByRole('textbox');
145+
const restrictions = screen.getByRole('list');
146+
expect(restrictions).toBeVisible();
147+
await userEvent.type(nameInput, 'testtoken1');
148+
expect(restrictions).not.toBeVisible();
149+
});
150+
142151
it('Should not create token when name input is empty', async () => {
143152
const nameInput = screen.getByRole('textbox');
144153

src/features/dashboard/components/ApiTokenForm/api-token.form.module.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ form {
5555
display: flex;
5656
position: relative;
5757
box-sizing: border-box;
58-
margin: rem(1) 0;
5958
&:hover {
6059
border: 1px solid var(--colors-greyLight600);
6160
}

src/features/dashboard/components/ApiTokenForm/api-token.form.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { HTMLAttributes, useCallback, useState } from 'react';
1+
import React, { HTMLAttributes, useCallback, useEffect, useState } from 'react';
22
import { Text } from '@deriv/ui';
33
import { useForm } from 'react-hook-form';
44
import { Circles } from 'react-loader-spinner';
@@ -8,6 +8,7 @@ import ApiTokenCard from '../ApiTokenCard';
88
import useCreateToken from '@site/src/features/dashboard/hooks/useCreateToken';
99
import * as yup from 'yup';
1010
import styles from './api-token.form.module.scss';
11+
import TokenNameRestrictions from '../TokenNameRestrictions/TokenNameRestrictions';
1112
import CreateTokenField from './CreateTokenField';
1213

1314
const schema = yup
@@ -79,6 +80,7 @@ const scopes: TScope[] = [
7980

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

@@ -93,7 +95,6 @@ const ApiTokenForm = (props: HTMLAttributes<HTMLFormElement>) => {
9395
resolver: yupResolver(schema),
9496
mode: 'all',
9597
});
96-
9798
const onSubmit = useCallback(
9899
(data: TApiTokenForm) => {
99100
const { name } = data;
@@ -120,6 +121,10 @@ const ApiTokenForm = (props: HTMLAttributes<HTMLFormElement>) => {
120121
[getValues, setValue],
121122
);
122123

124+
useEffect(() => {
125+
errors.name?.message ? setHideRestrictions(true) : setHideRestrictions(false);
126+
}, [errors.name?.message]);
127+
123128
return (
124129
<form role={'form'} onSubmit={handleSubmit(onSubmit)} {...props}>
125130
<div className={styles.steps_line} />
@@ -159,9 +164,11 @@ const ApiTokenForm = (props: HTMLAttributes<HTMLFormElement>) => {
159164
errors={errors}
160165
form_is_cleared={form_is_cleared}
161166
setFormIsCleared={setFormIsCleared}
167+
setHideRestriction={setHideRestrictions}
162168
is_toggle={is_toggle}
163169
setToggleModal={setToggleModal}
164170
/>
171+
{!hiderestrictions && <TokenNameRestrictions />}
165172
<div className={styles.step_title}>
166173
<div className={`${styles.third_step} ${styles.step}`}>
167174
<Text as={'p'} type={'paragraph-1'} data-testid={'third-step-title'}>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@use 'src/styles/utility' as *;
2+
3+
.tokenrestrictions {
4+
font-size: rem(1.4);
5+
font-weight: 400;
6+
line-height: 18px;
7+
padding-left: rem(2.8);
8+
margin-top: rem(1);
9+
color: var(--colors-greyLight600);
10+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
import styles from './TokenNameRestrictions.module.scss';
3+
4+
const TokenNameRestrictions = () => {
5+
return (
6+
<ol className={styles.tokenrestrictions}>
7+
<li>Only alphanumeric characters with spaces and underscores are allowed.</li>
8+
<li>Only 2-32 characters are allowed</li>
9+
<li>No duplicate token names are allowed for the same account.</li>
10+
<li>
11+
{
12+
'No keywords "deriv" or "binary" or words that look similar, e.g. "_binary_" or "d3eriv" are allowed.'
13+
}
14+
</li>
15+
</ol>
16+
);
17+
};
18+
19+
export default TokenNameRestrictions;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React from 'react';
2+
import { render, screen } from '@site/src/test-utils';
3+
import TokenNameRestrictions from '../TokenNameRestrictions';
4+
5+
describe('Restrictions for App name', () => {
6+
beforeEach(() => {
7+
render(<TokenNameRestrictions />);
8+
});
9+
it('Should render the list', () => {
10+
const RestrictonList = screen.getByRole('list');
11+
expect(RestrictonList).toBeInTheDocument();
12+
});
13+
14+
it('Should display correct content inside list items', () => {
15+
const listItem1 = screen.getByText(
16+
'Only alphanumeric characters with spaces and underscores are allowed.',
17+
);
18+
const listItem2 = screen.getByText('Only 2-32 characters are allowed');
19+
const listItem3 = screen.getByText(
20+
'No duplicate token names are allowed for the same account.',
21+
);
22+
const listItem4 = screen.getByText(
23+
'No keywords "deriv" or "binary" or words that look similar, e.g. "_binary_" or "d3eriv" are allowed.',
24+
);
25+
26+
expect(listItem1).toBeInTheDocument();
27+
expect(listItem2).toBeInTheDocument();
28+
expect(listItem3).toBeInTheDocument();
29+
expect(listItem4).toBeInTheDocument();
30+
});
31+
});

0 commit comments

Comments
 (0)