Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: TestCases #55

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
@@ -0,0 +1,179 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
userEvent;
import '@testing-library/jest-dom';
import { useStore } from '@deriv/stores';
import { getCardLabels, isValidToSell, isValidToCancel, isMultiplierContract } from '@deriv/shared';
import ContractDetailsFooter from '../contract-details-footer';
import { getRemainingTime } from 'AppV2/Utils/helper';
import userEvent from '@testing-library/user-event';

jest.mock('@deriv/stores', () => ({
useStore: jest.fn(),
}));
jest.mock('@deriv/shared', () => ({
getCardLabels: jest.fn(),
isValidToSell: jest.fn(),
isValidToCancel: jest.fn(),
isMultiplierContract: jest.fn(),
}));
jest.mock('AppV2/Utils/helper', () => ({
getRemainingTime: jest.fn(),
}));

const mockContractInfo = {
bid_price: 100,
currency: 'USD',
contract_id: 1,
profit: 10,
contract_type: 'non-multiplier',
};

describe('ContractDetailsFooter', () => {
let mockStore: any;

beforeEach(() => {
mockStore = {
contract_replay: {
onClickCancel: jest.fn(),
onClickSell: jest.fn(),
is_sell_requested: false,
},
common: {
server_time: new Date(),
},
};

(useStore as jest.Mock).mockImplementation(() => mockStore);
(getCardLabels as jest.Mock).mockImplementation(() => ({
CLOSE: 'Close',
CANCEL: 'Cancel',
RESALE_NOT_OFFERED: 'Resale not offered',
}));
jest.clearAllMocks();
});

it('should render close button with bid price and currency for non-multiplier contracts', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => false);
(isValidToSell as jest.Mock).mockImplementation(() => true);

render(<ContractDetailsFooter contract_info={mockContractInfo} />);

const closeButton = screen.getByRole('button', { name: /close @ 100 usd/i });
expect(closeButton).toBeInTheDocument();
expect(closeButton).toBeEnabled();
});

it('should render resale not offered message for non-valid sell contracts', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => false);
(isValidToSell as jest.Mock).mockImplementation(() => false);

render(<ContractDetailsFooter contract_info={mockContractInfo} />);

const resaleMessage = screen.getByText(/resale not offered/i);
expect(resaleMessage).toBeInTheDocument();
});

it('should render close and cancel buttons for multiplier contracts', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => true);
(isValidToSell as jest.Mock).mockImplementation(() => true);
(isValidToCancel as jest.Mock).mockImplementation(() => true);
(getRemainingTime as jest.Mock).mockImplementation(() => '10:00');

render(
<ContractDetailsFooter
contract_info={{
...mockContractInfo,
contract_type: 'multiplier',
cancellation: { date_expiry: new Date() },
}}
/>
);

const closeButton = screen.getByRole('button', { name: /close/i });
const cancelButton = screen.getByRole('button', { name: /cancel 10:00/i });

expect(closeButton).toBeInTheDocument();
expect(cancelButton).toBeInTheDocument();
});

it('should call onClickSell when close button is clicked', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => false);
(isValidToSell as jest.Mock).mockImplementation(() => true);

render(<ContractDetailsFooter contract_info={mockContractInfo} />);

const closeButton = screen.getByRole('button', { name: /close @ 100 usd/i });

userEvent.click(closeButton);

expect(mockStore.contract_replay.onClickSell).toHaveBeenCalledWith(1);
});

it('should disable close button for multiplier contract when profit is negative and valid to cancel', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => true);
(isValidToSell as jest.Mock).mockImplementation(() => true);
(isValidToCancel as jest.Mock).mockImplementation(() => true);

render(
<ContractDetailsFooter contract_info={{ ...mockContractInfo, contract_type: 'multiplier', profit: -10 }} />
);

const closeButton = screen.getByRole('button', { name: /close/i });
expect(closeButton).toBeDisabled();
});

it('should disable cancel button when profit is non-negative', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => true);
(isValidToCancel as jest.Mock).mockImplementation(() => true);
(getRemainingTime as jest.Mock).mockImplementation(() => '10:00');

render(
<ContractDetailsFooter
contract_info={{
...mockContractInfo,
contract_type: 'multiplier',
profit: 0,
cancellation: { date_expiry: new Date() },
}}
/>
);

const cancelButton = screen.getByRole('button', { name: /cancel 10:00/i });
expect(cancelButton).toBeDisabled();
});

it('should not render cancel button if not valid to cancel', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => true);
(isValidToCancel as jest.Mock).mockImplementation(() => false);

render(<ContractDetailsFooter contract_info={{ ...mockContractInfo, contract_type: 'multiplier' }} />);

const cancelButton = screen.queryByRole('button', { name: /cancel/i });
expect(cancelButton).not.toBeInTheDocument();
});

it('should not call onClickSell if not valid to sell', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => false);
(isValidToSell as jest.Mock).mockImplementation(() => false);

render(<ContractDetailsFooter contract_info={mockContractInfo} />);

const closeButton = screen.queryByRole('button', { name: /close @ 100 usd/i });
if (closeButton) {
userEvent.click(closeButton);
}

expect(mockStore.contract_replay.onClickSell).not.toHaveBeenCalled();
});

it('should render correct button label for non-multiplier contract when not valid to sell', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => false);
(isValidToSell as jest.Mock).mockImplementation(() => false);

render(<ContractDetailsFooter contract_info={mockContractInfo} />);

const resaleMessage = screen.getByRole('button', { name: /resale not offered/i });
expect(resaleMessage).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Text, CaptionText } from '@deriv-com/quill-ui';
import CardWrapper from '../CardWrapper';
import React from 'react';
import React, { useMemo } from 'react';
import { TContractInfo, addComma, getEndTime } from '@deriv/shared';

const getDateTimeFromEpoch = (epoch: number) => {
Expand All @@ -13,78 +13,49 @@ const getDateTimeFromEpoch = (epoch: number) => {
};
};

const DateTimeRow = ({ label, value, date, time }: { label: string; value?: string; date: string; time: string }) => (
<div className='entry-exit-details__table-row'>
<div className='entry-exit-details__table-cell'>
<Text size='sm' color='quill-typography__color--subtle'>
{label}
</Text>
</div>
<div className='entry-exit-details__table-cell'>
<Text size='sm'>{value}</Text>
<Text size='sm' color='quill-typography__color--subtle'>
{date}
</Text>
<CaptionText color='quill-typography__color--subtle'>{time}</CaptionText>
</div>
</div>
);

const EntryExitDetails = ({ contract_info }: { contract_info: TContractInfo }) => {
const { entry_tick_time, entry_spot_display_value, exit_tick_time, date_start, exit_tick_display_value } =
contract_info;
const entryDisplayValue = entry_spot_display_value ? addComma(entry_spot_display_value) : null;
const entrySpotDateTime = entry_tick_time ? getDateTimeFromEpoch(entry_tick_time) : null;
const exitSpotDateTime = exit_tick_time ? getDateTimeFromEpoch(exit_tick_time) : null;
const startDateTime = date_start ? getDateTimeFromEpoch(date_start) : null;
const exitSpot = exit_tick_display_value ? addComma(exit_tick_display_value) : null;
const endTime = getEndTime(contract_info);
const exitDateTime = endTime ? getDateTimeFromEpoch(endTime) : null;

const dateTimes = useMemo(
() => ({
entry: entry_tick_time && getDateTimeFromEpoch(entry_tick_time),
exit: exit_tick_time && getDateTimeFromEpoch(exit_tick_time),
start: date_start && getDateTimeFromEpoch(date_start),
end: getEndTime(contract_info) && getDateTimeFromEpoch(getEndTime(contract_info)),
}),
[contract_info]
);

const entryValue = entry_spot_display_value ? addComma(entry_spot_display_value) : null;
const exitValue = exit_tick_display_value ? addComma(exit_tick_display_value) : null;

return (
<CardWrapper title='Entry & exit details' className='entry-exit-details'>
<div className='entry-exit-details__table'>
{startDateTime && (
<div className='entry-exit-details__table-row'>
<div className='entry-exit-details__table-cell'>
<Text size='sm' color='quill-typography__color--subtle'>
Start time
</Text>
</div>
<div className='entry-exit-details__table-cell'>
<Text size='sm'>{startDateTime.date}</Text>
<CaptionText color='quill-typography__color--subtle'>{startDateTime.time}</CaptionText>
</div>
</div>
)}
{entrySpotDateTime && entryDisplayValue && (
<div className='entry-exit-details__table-row'>
<div className='entry-exit-details__table-cell'>
<Text size='sm' color='quill-typography__color--subtle'>
Entry spot
</Text>
</div>
<div className='entry-exit-details__table-cell'>
<Text size='sm'>{entryDisplayValue}</Text>
<Text size='sm' color='quill-typography__color--subtle'>
{entrySpotDateTime.date}
</Text>
<CaptionText color='quill-typography__color--subtle'>{entrySpotDateTime.time}</CaptionText>
</div>
</div>
)}
{exitDateTime && (
<div className='entry-exit-details__table-row'>
<div className='entry-exit-details__table-cell'>
<Text size='sm' color='quill-typography__color--subtle'>
Exit time
</Text>
</div>
<div className='entry-exit-details__table-cell'>
<Text size='sm'>{exitDateTime.date}</Text>
<CaptionText color='quill-typography__color--subtle'>{exitDateTime.time}</CaptionText>
</div>
</div>
)}
{exitSpotDateTime && exitSpot && (
<div className='entry-exit-details__table-row'>
<div className='entry-exit-details__table-cell'>
<Text size='sm' color='quill-typography__color--subtle'>
Exit spot
</Text>
</div>
<div className='entry-exit-details__table-cell'>
<Text size='sm'>{exitSpot}</Text>
<Text size='sm' color='quill-typography__color--subtle'>
{exitSpotDateTime.date}
</Text>
<CaptionText color='quill-typography__color--subtle'>{exitSpotDateTime.time}</CaptionText>
</div>
</div>
{dateTimes.start && <DateTimeRow label='Start time' {...dateTimes.start} />}
{dateTimes.entry && entryValue && (
<DateTimeRow label='Entry spot' value={entryValue} {...dateTimes.entry} />
)}
{dateTimes.end && <DateTimeRow label='Exit time' {...dateTimes.end} />}
{dateTimes.exit && exitValue && <DateTimeRow label='Exit spot' value={exitValue} {...dateTimes.exit} />}
</div>
</CardWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import '@testing-library/jest-dom';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import PayoutInfoModal from '../payout-info-modal';

describe('PayoutInfoModal', () => {
const bodyContent = 'This is the body content of the modal.';

it('should render the button and modal content correctly', () => {
render(<PayoutInfoModal body_content={bodyContent} />);

const button = screen.getByRole('button');
expect(button).toBeInTheDocument();
expect(screen.getByText('How do I earn a payout?')).toBeInTheDocument();
expect(screen.queryByText(bodyContent)).not.toBeInTheDocument();
});

it('should toggle the modal visibility when the button is clicked', async () => {
render(<PayoutInfoModal body_content={bodyContent} />);

const button = screen.getByRole('button');
await userEvent.click(button);
expect(screen.getByText(bodyContent)).toBeInTheDocument();

await userEvent.click(button);

await waitFor(() => {
expect(screen.queryByText(bodyContent)).not.toBeInTheDocument();
});
});

it('should close the modal when the primary button is clicked', async () => {
render(<PayoutInfoModal body_content={bodyContent} />);

const button = screen.getByRole('button');
await userEvent.click(button);

expect(screen.getByText(bodyContent)).toBeInTheDocument();

const primaryButton = screen.getByText('Got it');
await userEvent.click(primaryButton);

await waitFor(() => {
expect(screen.queryByText(bodyContent)).not.toBeInTheDocument();
});
});
});
Loading
Loading