diff --git a/src/__mocks__/mock-data.ts b/src/__mocks__/mock-data.ts index 6f7345a5..357a3a1f 100644 --- a/src/__mocks__/mock-data.ts +++ b/src/__mocks__/mock-data.ts @@ -125,3 +125,152 @@ export const mockAdvertiserPaymentMethods = [ used_by_orders: null, }, ]; + +export const mockCountryList = { + af: { + country_name: 'Afghanistan', + cross_border_ads_enabled: 1, + fixed_rate_adverts: 'enabled', + float_rate_adverts: 'disabled', + float_rate_offset_limit: 10, + local_currency: 'AFN', + payment_methods: { + alipay: { + display_name: 'Alipay', + fields: { + account: { + display_name: 'Alipay ID', + required: 1, + type: 'text', + }, + instructions: { + display_name: 'Instructions', + required: 0, + type: 'memo', + }, + }, + type: 'ewallet', + }, + }, + }, +}; + +export const mockPaymentMethods = [ + { + display_name: 'Bank Transfer', + fields: { + account: { + display_name: 'Account Number', + required: 1, + type: 'text', + value: 'Account Number', + }, + bank_name: { display_name: 'Bank Transfer', required: 1, type: 'text', value: 'Bank Name' }, + }, + id: 'test1', + is_enabled: 0, + method: '', + type: 'bank', + used_by_adverts: null, + used_by_orders: null, + }, + { + display_name: 'Ali pay', + fields: { + account: { + display_name: 'Account Number', + required: 1, + type: 'text', + value: 'Account Number', + }, + bank_name: { display_name: 'Ali pay', required: 1, type: 'text', value: 'Bank Name' }, + }, + id: 'test2', + is_enabled: 0, + method: '', + type: 'wallet', + used_by_adverts: null, + used_by_orders: null, + }, + { + display_name: 'Skrill', + fields: { + account: { + display_name: 'Account Number', + required: 1, + type: 'text', + value: 'Account Number', + }, + bank_name: { display_name: 'Skrill', required: 1, type: 'text', value: 'Bank Name' }, + }, + id: 'test3', + is_enabled: 0, + method: '', + type: 'wallet', + used_by_adverts: null, + used_by_orders: null, + }, +]; + +export const mockAdvertiserAdvertValues = { + account_currency: 'USD', + active_orders: 0, + advertiser_details: { + completed_orders_count: 0, + has_not_been_recommended: false, + id: '34', + is_blocked: false, + is_favourite: false, + is_online: true, + is_recommended: false, + last_online_time: 1688480346, + name: 'client CR90000212', + rating_average: null, + rating_count: 0, + recommended_average: null, + recommended_count: null, + total_completion_rate: null, + }, + amount: 22, + amount_display: '22.00', + block_trade: false, + contact_info: '', + counterparty_type: 'sell' as const, + country: 'id', + created_time: new Date(1688460999), + currentRateType: 'fixed' as const, + days_until_archive: 1, + description: '', + effective_rate: 22, + effective_rate_display: '22.00', + eligible_countries: ['ID'], + id: '138', + is_active: true, + is_floating: false, + is_visible: true, + local_currency: 'IDR', + max_order_amount: 22, + max_order_amount_display: '22.00', + max_order_amount_limit: 22, + max_order_amount_limit_display: '22.00', + min_completion_rate: 22, + min_join_days: 4, + min_order_amount: 22, + min_order_amount_display: '22.00', + min_order_amount_limit: 22, + min_order_amount_limit_display: '22.00', + min_rating: 4, + order_expiry_period: 900, + payment_info: '', + payment_method: null, + payment_method_names: ['Bank Transfer'], + price: 22, + price_display: '22.00', + rate: 22, + rate_display: '22.00', + rate_type: 'fixed' as const, + remaining_amount: 22, + remaining_amount_display: '22.00', + type: 'buy' as const, + visibility_status: [], +}; diff --git a/src/components/CopyAdForm/CopyAdForm.scss b/src/components/CopyAdForm/CopyAdForm.scss index 4bb13a93..cb02d7b0 100644 --- a/src/components/CopyAdForm/CopyAdForm.scss +++ b/src/components/CopyAdForm/CopyAdForm.scss @@ -9,7 +9,7 @@ position: absolute; top: -6rem; z-index: 2; - height: calc(100vh - 9rem); + height: calc(100vh - 12rem); & .mobile-wrapper__body { margin-top: 1.6rem; diff --git a/src/components/CopyAdForm/CopyAdForm.tsx b/src/components/CopyAdForm/CopyAdForm.tsx index cf4d1d64..9b59951d 100644 --- a/src/components/CopyAdForm/CopyAdForm.tsx +++ b/src/components/CopyAdForm/CopyAdForm.tsx @@ -57,14 +57,15 @@ const CopyAdForm = ({ type, } = rest; const { floatRateOffsetLimitString, rateType } = useFloatingRate(); + const methods = useForm({ defaultValues: { - amount: amount ?? formValues.amount, + amount: formValues.amount || (amount ?? 0), 'float-rate-offset-limit': floatRateOffsetLimitString, 'max-order': formValues.maxOrder, 'min-order': formValues.minOrder, 'rate-type-string': rateType, - 'rate-value': formValues.rateValue ?? rateType === RATE_TYPE.FLOAT ? '-0.01' : rateDisplay, + 'rate-value': formValues.rateValue || (rateType === RATE_TYPE.FLOAT ? '-0.01' : rateDisplay), }, mode: 'all', }); diff --git a/src/components/CopyAdForm/CopyAdFormFooter.tsx b/src/components/CopyAdForm/CopyAdFormFooter.tsx index 3aa4a711..031512a3 100644 --- a/src/components/CopyAdForm/CopyAdFormFooter.tsx +++ b/src/components/CopyAdForm/CopyAdFormFooter.tsx @@ -16,6 +16,7 @@ const CopyAdFormFooter = ({ isValid, onClickCancel, onSubmit }: TCopyAdFormFoote onClick={onClickCancel} size='lg' textSize={isMobile ? 'md' : 'sm'} + type='button' variant='outlined' > diff --git a/src/components/CopyAdForm/__tests__/CopyAdForm.spec.tsx b/src/components/CopyAdForm/__tests__/CopyAdForm.spec.tsx new file mode 100644 index 00000000..5200afd2 --- /dev/null +++ b/src/components/CopyAdForm/__tests__/CopyAdForm.spec.tsx @@ -0,0 +1,72 @@ +// import { ReactNode } from 'react'; +import { mockAdvertiserAdvertValues, mockCountryList } from '@/__mocks__/mock-data'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import CopyAdForm from '../CopyAdForm'; + +const mockProps = { + ...mockAdvertiserAdvertValues, + formValues: { + amount: 22, + maxOrder: '22', + minOrder: '22', + rateValue: '22', + }, + isModalOpen: true, + isValid: true, + onClickCancel: jest.fn(), + onFormSubmit: jest.fn(), + onRequestClose: jest.fn(), +}; + +jest.mock('@deriv-com/ui', () => ({ + ...jest.requireActual('@deriv-com/ui'), + useDevice: () => ({ isMobile: false }), +})); + +jest.mock('@/pages/my-ads/components/AdFormInput', () => ({ + AdFormInput: () =>
AdFormInput
, +})); + +jest.mock('@/pages/my-ads/components/AdFormTextArea', () => ({ + AdFormTextArea: () =>
AdFormTextArea
, +})); + +jest.mock('@/hooks/custom-hooks', () => { + return { + ...jest.requireActual('@/hooks'), + useFloatingRate: () => ({ floatRateOffsetLimitString: '22', rateType: 'fixed' }), + }; +}); + +jest.mock('@/hooks', () => ({ + ...jest.requireActual('@/hooks'), + api: { + countryList: { + useGet: jest.fn(() => ({ data: mockCountryList })), + }, + }, +})); + +describe('CopyAdForm', () => { + it('should render the form', () => { + render(); + expect(screen.getByText('Ad type')).toBeInTheDocument(); + expect(screen.getByText('Instructions')).toBeInTheDocument(); + expect( + screen.getByText('Review your settings and create a new ad. Every ad must have unique limits and rates.') + ).toBeInTheDocument(); + }); + it('should handle cancel', async () => { + render(); + const button = screen.getByRole('button', { name: 'Cancel' }); + await userEvent.click(button); + expect(mockProps.onClickCancel).toHaveBeenCalled(); + }); + it('should handle submit', async () => { + render(); + const button = screen.getByRole('button', { name: 'Create ad' }); + await userEvent.click(button); + expect(mockProps.onFormSubmit).toHaveBeenCalled(); + }); +}); diff --git a/src/components/CopyAdForm/__tests__/CopyAdFormDisplayWrapper.spec.tsx b/src/components/CopyAdForm/__tests__/CopyAdFormDisplayWrapper.spec.tsx new file mode 100644 index 00000000..a72ad0cf --- /dev/null +++ b/src/components/CopyAdForm/__tests__/CopyAdFormDisplayWrapper.spec.tsx @@ -0,0 +1,29 @@ +import { useDevice } from '@deriv-com/ui'; +import { render, screen } from '@testing-library/react'; +import CopyAdFormDisplayWrapper from '../CopyAdFormDisplayWrapper'; + +const mockProps = { + isModalOpen: true, + isValid: true, + onClickCancel: jest.fn(), + onRequestClose: jest.fn(), + onSubmit: jest.fn(), +}; + +jest.mock('@deriv-com/ui', () => ({ + ...jest.requireActual('@deriv-com/ui'), + useDevice: jest.fn(() => ({ isMobile: false })), +})); + +describe('CopyAdFormDisplayWrapper', () => { + it('should render the modal with header for desktop view', () => { + render(); + expect(screen.getByText('Create a similar ad')).toBeInTheDocument(); + }); + it('should render the full page mobile wrapper for mobile view', () => { + (useDevice as jest.Mock).mockReturnValue({ isMobile: true }); + render(); + expect(screen.getByTestId('dt_full_page_mobile_wrapper')).toBeInTheDocument(); + expect(screen.queryByText('Create a similar ad')).not.toBeInTheDocument(); + }); +}); diff --git a/src/components/Modals/AdCancelCreateEditModal/AdCancelCreateEditModal.tsx b/src/components/Modals/AdCancelCreateEditModal/AdCancelCreateEditModal.tsx index a0a34500..93154635 100644 --- a/src/components/Modals/AdCancelCreateEditModal/AdCancelCreateEditModal.tsx +++ b/src/components/Modals/AdCancelCreateEditModal/AdCancelCreateEditModal.tsx @@ -8,9 +8,10 @@ import './AdCancelCreateEditModal.scss'; type TAdCancelCreateEditModalProps = { isModalOpen: boolean; onRequestClose: () => void; + resetValues?: () => void; }; -const AdCancelCreateEditModal = ({ isModalOpen, onRequestClose }: TAdCancelCreateEditModalProps) => { +const AdCancelCreateEditModal = ({ isModalOpen, onRequestClose, resetValues }: TAdCancelCreateEditModalProps) => { const { isMobile } = useDevice(); const history = useHistory(); const { queryString } = useQueryString(); @@ -46,7 +47,10 @@ const AdCancelCreateEditModal = ({ isModalOpen, onRequestClose }: TAdCancelCreat