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 @@ -3,6 +3,7 @@ import { Text, Button } from '@deriv/ui';
import styles from '../api-token.form.module.scss';
import useApiToken from '@site/src/hooks/useApiToken';
import { FieldErrorsImpl, UseFormRegisterReturn } from 'react-hook-form';
import TokenCreationDialogSuccess from '../../Dialogs/TokenCreationDialogSuccess';

type TCreateTokenField = {
register: UseFormRegisterReturn;
Expand All @@ -18,13 +19,17 @@ type TCreateTokenField = {
>;
form_is_cleared: boolean;
setFormIsCleared: Dispatch<SetStateAction<boolean>>;
is_toggle: boolean;
setToggleModal: Dispatch<SetStateAction<boolean>>;
};

const CreateTokenField = ({
errors,
register,
form_is_cleared,
setFormIsCleared,
is_toggle,
setToggleModal,
}: TCreateTokenField) => {
const { tokens } = useApiToken();
const [input_value, setInputValue] = useState('');
Expand Down Expand Up @@ -72,6 +77,7 @@ const CreateTokenField = ({
<Button disabled={disable_button} type='submit'>
Create
</Button>
{is_toggle && <TokenCreationDialogSuccess setToggleModal={setToggleModal} />}
</div>
{errors && errors.name && (
<Text as='span' type='paragraph-1' className='error-message'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ const scopes = [
label: 'Admin',
},
];
const preventDefault = jest.fn();

describe('Home Page', () => {
beforeEach(() => {
Expand Down Expand Up @@ -147,4 +148,29 @@ describe('Home Page', () => {

expect(mockCreateToken).not.toHaveBeenCalled();
});

it('Should open success dialog when token is created ', async () => {
const nameInput = screen.getByRole('textbox');

await userEvent.type(nameInput, 'test create token');

const submitButton = screen.getByRole('button', { name: /Create/i });
await userEvent.click(submitButton);

const modal = await screen.getByText('Your API token is ready to be used.');
expect(modal).toBeVisible();
});

it('Should have create button disabled in case of empty input or error message', async () => {
const submitButton = screen.getByRole('button', { name: /Create/i });
expect(submitButton).toBeDisabled();

const nameInput = screen.getByRole('textbox');

await userEvent.type(nameInput, 'token-text');
expect(submitButton).toBeDisabled();

await userEvent.clear(nameInput);
expect(submitButton).toBeDisabled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const scopes: TScope[] = [
const ApiTokenForm = (props: HTMLAttributes<HTMLFormElement>) => {
const { createToken, isCreatingToken } = useCreateToken();
const [form_is_cleared, setFormIsCleared] = useState(false);
const [is_toggle, setToggleModal] = useState(false);

const {
handleSubmit,
Expand All @@ -105,6 +106,7 @@ const ApiTokenForm = (props: HTMLAttributes<HTMLFormElement>) => {
});
createToken(name, selectedTokenScope);
setFormIsCleared(true);
setToggleModal((prev) => !prev);
reset();
},
[createToken, reset],
Expand Down Expand Up @@ -157,6 +159,8 @@ const ApiTokenForm = (props: HTMLAttributes<HTMLFormElement>) => {
errors={errors}
form_is_cleared={form_is_cleared}
setFormIsCleared={setFormIsCleared}
is_toggle={is_toggle}
setToggleModal={setToggleModal}
/>
<div className={styles.step_title}>
<div className={`${styles.third_step} ${styles.step}`}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import TokenCreationDialogSuccess from '..';
import { screen, render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

describe('Token Creation Dialog', () => {
it('Should display correct title on the modal', () => {
render(<TokenCreationDialogSuccess setToggleModal={jest.fn()} />);

const title = screen.getByText(/Token created successfully/i);
expect(title).toHaveTextContent('Token created successfully');
});

it('Should display correct content on the modal', () => {
render(<TokenCreationDialogSuccess setToggleModal={jest.fn()} />);

const textContent = screen.getByText(/Your API token is ready to be used./i);
expect(textContent).toHaveTextContent('Your API token is ready to be used.');
});

it('Should close the modal on OK button click', async () => {
const mockOnClose = jest.fn();

render(<TokenCreationDialogSuccess setToggleModal={mockOnClose} />);

const okButton = screen.getByRole('button', { name: /OK/i });
expect(okButton).toBeInTheDocument();

await userEvent.click(okButton);

expect(mockOnClose).toHaveBeenCalledTimes(1);
});

it('Should close the modal on cross button click', async () => {
const mockOnClose = jest.fn();

render(<TokenCreationDialogSuccess setToggleModal={mockOnClose} />);
const modal = screen.getByText('Your API token is ready to be used.');

const crossButton = screen.getByTestId('close-button');
await userEvent.click(crossButton);

expect(modal).not.toBeInTheDocument();
expect(mockOnClose).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { useCallback } from 'react';
import { Button, Modal } from '@deriv/ui';
import styles from './token-creation-dialog-sucess.module.scss';

type ITokenCreationDialogSuccessProps = {
setToggleModal: React.Dispatch<React.SetStateAction<boolean>>;
};

export const TokenCreationDialogSuccess = ({
setToggleModal,
}: ITokenCreationDialogSuccessProps) => {
const onOpenChange = useCallback(
(open: boolean) => {
if (!open) {
setToggleModal(false);
}
},
[setToggleModal],
);
const handleToggle = () => {
setToggleModal(false);
};

return (
<Modal defaultOpen onOpenChange={onOpenChange}>
<Modal.Portal>
<div className='modal-overlay'>
<Modal.Overlay />
<Modal.PageContent
title={'Token created successfully'}
has_close_button
className={styles.wrapper}
>
<div className={styles.modal}>
<p>Your API token is ready to be used.</p>
</div>

<div className={styles.buttonWrapper}>
<Button color='primary' onClick={handleToggle} className={styles.btn}>
OK
</Button>
</div>
</Modal.PageContent>
</div>
</Modal.Portal>
</Modal>
);
};

export default TokenCreationDialogSuccess;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
@use 'src/styles/utility' as *;

.wrapper {
width: rem(44);
}

.modal {
display: flex;
flex-direction: column;
gap: 8px;
padding: rem(0.8) rem(2.4) 0;
font-size: rem(1.4);
line-height: rem(2);
@media (max-width: 992px) {
padding: 0 0 0 rem(1.6);
}
}

.buttonWrapper {
display: flex;
justify-content: flex-end;
padding: rem(2.4);
gap: rem(0.8);

.btn {
padding: rem(1) rem(1.6);
border-radius: rem(1.5);
}
}