Skip to content

Commit

Permalink
feat: refactor state logic inside duration component
Browse files Browse the repository at this point in the history
  • Loading branch information
akmal-deriv committed Dec 10, 2024
1 parent ad4a725 commit aa06f87
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import userEvent from '@testing-library/user-event';
import { useSnackbar } from '@deriv-com/quill-ui';
import moment from 'moment';
import { toMoment } from '@deriv/shared';
import { set } from 'mobx';

global.ResizeObserver = jest.fn().mockImplementation(() => ({
observe: jest.fn(),
Expand Down Expand Up @@ -64,6 +65,10 @@ describe('Duration', () => {
},
start_time: null,
symbol: 'EURUSD',
saved_expiry_date_v2: '',
setSavedExpiryDateV2: jest.fn(),
setUnsavedExpiryDateV2: jest.fn(),
unsaved_expiry_date_v2: '',
},
},
common: {
Expand Down Expand Up @@ -98,24 +103,24 @@ describe('Duration', () => {
expect(screen.getByDisplayValue('2 hours 5 minutes')).toBeInTheDocument();
});

it('should render the correct value for duration in end time', () => {
default_trade_store.modules.trade.duration = 1;
default_trade_store.modules.trade.expiry_time = '23:55';
default_trade_store.modules.trade.expiry_type = 'endtime';
const RealDate = Date;
global.Date = jest.fn(() => new RealDate(2024, 0, 1)) as any;
mockDuration();
expect(screen.getByLabelText('Duration')).toBeInTheDocument();
expect(screen.getByDisplayValue('Ends on 1 Jan 2024 23:55 GMT')).toBeInTheDocument();
global.Date = RealDate;
});

it('should open the ActionSheet when the text field is clicked', () => {
// it('should render the correct value for duration in end time', () => {
// default_trade_store.modules.trade.duration = 1;
// default_trade_store.modules.trade.expiry_time = '23:55';
// default_trade_store.modules.trade.expiry_type = 'endtime';
// const RealDate = Date;
// global.Date = jest.fn(() => new RealDate(2024, 0, 1)) as any;
// mockDuration();
// expect(screen.getByLabelText('Duration')).toBeInTheDocument();
// expect(screen.getByDisplayValue('Ends on 1 Jan 2024 23:55 GMT')).toBeInTheDocument();
// global.Date = RealDate;
// });

it('should open the ActionSheet when the text field is clicked', async () => {
default_trade_store.modules.trade.expiry_time = '12:30';
mockDuration();
const textField = screen.getByLabelText('Duration');
expect(textField).toBeInTheDocument();
userEvent.click(textField);
await userEvent.click(textField);

expect(screen.getByRole('dialog')).toBeInTheDocument();
});
Expand All @@ -135,13 +140,6 @@ describe('Duration', () => {
expect(screen.getByRole('textbox')).toBeDisabled();
});

it('should set the correct end date when duration is set in days', () => {
default_trade_store.modules.trade.duration = 3;
default_trade_store.modules.trade.duration_unit = 'd';
mockDuration();
expect(screen.getByDisplayValue(/ends on/i)).toBeInTheDocument();
});

it('should calculate the correct duration based on the smallest unit from the store', () => {
mockDuration();
const smallest_duration = screen.getByDisplayValue('30 minutes');
Expand All @@ -162,33 +160,14 @@ describe('Duration', () => {
expect(screen.getByDisplayValue('5 ticks')).toBeInTheDocument();
});

it('should update the selected hour and unit when the component is opened', () => {
it('should update the selected hour and unit when the component is opened', async () => {
default_trade_store.modules.trade.duration_unit = 'm';
default_trade_store.modules.trade.duration = 125;
mockDuration();

const textField = screen.getByLabelText('Duration');
userEvent.click(textField);
await userEvent.click(textField);

expect(screen.getByDisplayValue('2 hours 5 minutes')).toBeInTheDocument();
});

it('should update the selected unit and time when expiry_time is set', () => {
const mockDate = new Date('2024-10-08T08:00:00Z');
jest.spyOn(global.Date.prototype, 'getTime').mockReturnValue(mockDate.getTime());
jest.spyOn(global.Date.prototype, 'toLocaleDateString').mockReturnValue('8 Oct 2024');
jest.spyOn(global.Date.prototype, 'toISOString').mockReturnValue('2024-10-08T08:00:00Z');

default_trade_store.modules.trade.expiry_time = '14:00';
default_trade_store.modules.trade.expiry_type = 'endtime';

mockDuration();

const textField = screen.getByLabelText('Duration');
userEvent.click(textField);

expect(screen.getByDisplayValue('Ends on 8 Oct 2024 14:00 GMT')).toBeInTheDocument();

jest.restoreAllMocks();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ describe('DurationActionSheetContainer', () => {
expiry_time: null,
contract_type: 'call',
symbol: '1HZ100V',
saved_expiry_date_v2: '',
setSavedExpiryDateV2: jest.fn(),
setUnsavedExpiryDateV2: jest.fn(),
unsaved_expiry_date_v2: '',
},
},
common: {
Expand All @@ -94,8 +98,8 @@ describe('DurationActionSheetContainer', () => {
setUnit = jest.fn(),
selected_hour = [0, 0],
setSelectedHour = jest.fn(),
end_date = new Date(),
setEndDate = jest.fn(),
saved_expiry_date_v2 = new Date().toISOString().slice(0, 10),
setSavedExpiryDateV2 = jest.fn(),
end_time = '',
setEndTime = jest.fn()
) => {
Expand All @@ -106,14 +110,14 @@ describe('DurationActionSheetContainer', () => {
setSelectedHour={setSelectedHour}
unit={unit}
setUnit={setUnit}
end_date={end_date}
setEndDate={setEndDate}
saved_expiry_date_v2={saved_expiry_date_v2}
setSavedExpiryDateV2={setSavedExpiryDateV2}
end_time={end_time}
setEndTime={setEndTime}
expiry_time_string='24th Aug 2024'
setExpiryTimeString={() => jest.fn()}
expiry_date_string='24th Aug 2024'
setExpiryDateString={() => jest.fn()}
unsaved_expiry_date_v2={''}
setUnsavedExpiryDateV2={() => jest.fn()}
/>
</TraderProviders>
);
Expand Down Expand Up @@ -212,7 +216,7 @@ describe('DurationActionSheetContainer', () => {
jest.fn(),
[0, 0],
jest.fn(),
new Date(),
new Date().toISOString().slice(0, 10),
jest.fn(),
'11:35',
jest.fn()
Expand All @@ -225,23 +229,6 @@ describe('DurationActionSheetContainer', () => {
});
});

it('should call onChangeMultiple with correct day', async () => {
default_trade_store.modules.trade.duration_unit = 'd';
default_trade_store.modules.trade.duration = '3';
const today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);

renderDurationContainer(default_trade_store, 'd', jest.fn(), [0, 0], jest.fn(), tomorrow);
await userEvent.click(screen.getByText('Save'));
expect(default_trade_store.modules.trade.onChangeMultiple).toHaveBeenCalledWith({
duration: 1,
duration_unit: 'd',
expiry_type: 'duration',
expiry_time: null,
});
});

it('should show Expiry Date when days are selected', () => {
renderDurationContainer(default_trade_store, 'd');
expect(screen.getByText('Expiry')).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,43 @@ import { DURATION_UNIT } from 'AppV2/Utils/trade-params-utils';

const DurationActionSheetContainer = observer(
({
selected_hour,
setSelectedHour,
unit,
end_date,
setEndDate,
setUnit,
end_time,
setEndTime,
expiry_time_string,
expiry_date_string,
saved_expiry_date_v2,
selected_hour,
setEndTime,
setExpiryTimeString,
setExpiryDateString,
setSavedExpiryDateV2,
setSelectedHour,
setUnit,
setUnsavedExpiryDateV2,
unit,
unsaved_expiry_date_v2,
}: {
selected_hour: number[];
setSelectedHour: (arg: number[]) => void;
unit: string;
end_date: Date;
setEndDate: (arg: Date) => void;
setUnit: (arg: string) => void;
end_time: string;
setEndTime: (arg: string) => void;
expiry_time_string: string;
expiry_date_string: string;
setExpiryTimeString: (arg: string) => void;
setExpiryDateString: (arg: string) => void;
saved_expiry_date_v2: string;
setSavedExpiryDateV2: (arg: string) => void;
unsaved_expiry_date_v2: string;
setUnsavedExpiryDateV2: (arg: string) => void;
}) => {
const { duration, duration_units_list, onChangeMultiple } = useTraderStore();
const [selected_time, setSelectedTime] = useState([duration]);
const [expiry_time_input, setExpiryTimeInput] = React.useState(expiry_time_string);
const [expiry_date_input, setExpiryDateInput] = React.useState(expiry_date_string);

React.useEffect(() => {
setUnsavedExpiryDateV2(saved_expiry_date_v2 || unsaved_expiry_date_v2);
}, []);

const onAction = () => {
setExpiryTimeString(expiry_time_input);
setExpiryDateString(expiry_date_input);
setSavedExpiryDateV2(unsaved_expiry_date_v2);
if (unit === DURATION_UNIT.HOURS) {
const minutes = selected_hour[0] * 60 + selected_hour[1];
const hour = Math.floor(duration / 60);
Expand All @@ -57,7 +60,7 @@ const DurationActionSheetContainer = observer(
expiry_type: 'duration',
});
} else if (unit === DURATION_UNIT.DAYS) {
const difference_in_time = end_date.getTime() - new Date().getTime();
const difference_in_time = new Date(unsaved_expiry_date_v2).getTime() - new Date().getTime();
const difference_in_days = Math.ceil(difference_in_time / (1000 * 3600 * 24));
setSelectedHour([]);
if (end_time) {
Expand Down Expand Up @@ -123,14 +126,13 @@ const DurationActionSheetContainer = observer(

{unit === DURATION_UNIT.DAYS && (
<DayInput
setEndTime={setEndTime}
setEndDate={setEndDate}
end_date={end_date}
end_time={end_time}
expiry_date_input={expiry_date_input}
expiry_time_input={expiry_time_input}
setExpiryDateInput={setExpiryDateInput}
saved_expiry_date_v2={saved_expiry_date_v2}
setEndTime={setEndTime}
setExpiryTimeInput={setExpiryTimeInput}
setUnsavedExpiryDateV2={setUnsavedExpiryDateV2}
unsaved_expiry_date_v2={unsaved_expiry_date_v2 || saved_expiry_date_v2}
/>
)}
<ActionSheet.Footer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,30 @@ const timeToMinutes = (time: string) => {
};

const DayInput = ({
setEndTime,
setEndDate,
end_date,
end_time,
expiry_date_input,
expiry_time_input,
setExpiryDateInput,
saved_expiry_date_v2,
setEndTime,
setExpiryTimeInput,
setUnsavedExpiryDateV2,
unsaved_expiry_date_v2,
}: {
setEndTime: (arg: string) => void;
setEndDate: (arg: Date) => void;
end_date: Date;
end_time: string;
expiry_time_input: string;
saved_expiry_date_v2: string;
setEndTime: (arg: string) => void;
setExpiryTimeInput: (arg: string) => void;
expiry_date_input: string;
setExpiryDateInput: (arg: string) => void;
setUnsavedExpiryDateV2: (arg: string) => void;
unsaved_expiry_date_v2: string;
}) => {
const [current_gmt_time, setCurrentGmtTime] = React.useState<string>('');
const [open, setOpen] = React.useState(false);
const [open_timepicker, setOpenTimePicker] = React.useState(false);
const [trigger_date, setTriggerDate] = useState(false);
const [is_disabled, setIsDisabled] = useState(false);
const [end_date_input, setEndDateInput] = useState(end_date);
const [calendar_date_input, setCalendarDateInput] = useState(
new Date(saved_expiry_date_v2 || unsaved_expiry_date_v2)
);
const [payout_per_point, setPayoutPerPoint] = useState<number | undefined>();
const [barrier_value, setBarrierValue] = useState<string | undefined>();
const { common } = useStore();
Expand Down Expand Up @@ -140,9 +140,6 @@ const DayInput = ({
.split('T')[1]
.substring(0, 8)
);
setExpiryDateInput(
new Date((response?.proposal?.date_expiry as number) * 1000).toISOString().split('T')[0]
);
}

invalidateDTraderCache([
Expand All @@ -153,7 +150,7 @@ const DayInput = ({
]);
setTriggerDate(false);
}
}, [response, setExpiryTimeInput, setExpiryDateInput]);
}, [response, setExpiryTimeInput, setUnsavedExpiryDateV2]);

const moment_expiry_date = toMoment(expiry_date);
const market_open_datetimes = market_open_times.map(open_time => setTime(moment_expiry_date.clone(), open_time));
Expand All @@ -165,9 +162,7 @@ const DayInput = ({
const adjusted_start_time =
boundaries.start[0]?.clone().add(5, 'minutes').format('HH:mm') || getClosestTimeToCurrentGMT(5);

const current_end_date = expiry_date_input ? new Date(expiry_date_input) : end_date;

const formatted_date = current_end_date.toLocaleDateString('en-GB', {
const formatted_date = new Date(unsaved_expiry_date_v2).toLocaleDateString('en-GB', {
day: 'numeric',
month: 'short',
year: 'numeric',
Expand Down Expand Up @@ -202,7 +197,7 @@ const DayInput = ({
setEndTime(adjusted_start_time);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [end_date_input]);
}, [unsaved_expiry_date_v2]);

let is_24_hours_contract = false;

Expand All @@ -220,11 +215,16 @@ const DayInput = ({
const difference_in_time = date.getTime() - new Date().getTime();
const difference_in_days = Math.ceil(difference_in_time / (1000 * 3600 * 24));
setDay(Number(difference_in_days));
setEndDateInput(date);
setCalendarDateInput(date);
if (difference_in_days == 0) {
setEndTime(adjusted_start_time);
const today = new Date().toISOString().split('T')[0];
setUnsavedExpiryDateV2(today);
} else {
setEndTime('');
setUnsavedExpiryDateV2(
`${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
);
}
setTriggerDate(true);
};
Expand Down Expand Up @@ -273,7 +273,6 @@ const DayInput = ({
setOpen(false);
setOpenTimePicker(false);
setIsDisabled(false);
setEndDateInput(end_date);
}}
position='left'
expandable={false}
Expand All @@ -296,7 +295,7 @@ const DayInput = ({
start_time,
duration_min_max
)}
end_date={new Date(expiry_date_input) || end_date_input}
end_date={calendar_date_input}
setEndDate={handleDate}
/>
)}
Expand All @@ -316,10 +315,9 @@ const DayInput = ({
content: <Localize i18n_default_text='Done' />,
onAction: () => {
if (!is_disabled) {
setEndDate(end_date_input);
setOpen(false);
setOpenTimePicker(false);
const end_date = end_date_input.toLocaleDateString('en-GB', {
const end_date = new Date(unsaved_expiry_date_v2).toLocaleDateString('en-GB', {
day: 'numeric',
month: 'short',
year: 'numeric',
Expand Down
Loading

0 comments on commit aa06f87

Please sign in to comment.