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

FarhanNurzi/P2PS-1329/Advertisers ads are duplicating in other advertiser profile after manual refresh #9569

Merged

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React from 'react';
import { render } from '@testing-library/react';
import { useModalManagerContext } from 'Components/modal-manager/modal-manager-context';
import { useStores } from 'Stores/index';
import AdvertiserPage from '../advertiser-page';

const mock_modal_manager = {
showModal: jest.fn(),
hideModal: jest.fn(),
useRegisterModalProps: jest.fn(),
is_modal_open: true,
};

jest.mock('Components/modal-manager/modal-manager-context');
const mocked_useModalManagerContext = useModalManagerContext as jest.MockedFunction<
() => Partial<ReturnType<typeof useModalManagerContext>>
>;

mocked_useModalManagerContext.mockImplementation(() => mock_modal_manager);

const mock_store: DeepPartial<ReturnType<typeof useStores>> = {
advertiser_page_store: {
advertiser_details_id: 'id1',
advertiser_details_name: 'test name',
counterparty_advertiser_info: {
name: 'name',
is_online: 1,
},
is_counterparty_advertiser_blocked: false,
onAdvertiserIdUpdate: jest.fn(),
onMount: jest.fn(),
onTabChange: jest.fn(),
setIsDropdownMenuVisible: jest.fn(),
onUnmount: jest.fn(),
onCancel: jest.fn(),
is_loading: false,
info: {
name: 'name',
},
},
general_store: {
advertiser_id: 'id2',
advertiser_info: {
name: 'my name',
is_online: 1,
},
block_unblock_user_error: '',
error_code: '',
active_index: 0,
setBlockUnblockUserError: jest.fn(),
setActiveIndex: jest.fn(),
path: {
my_profile: 3,
},
is_block_unblock_user_loading: false,
setCounterpartyAdvertiserId: jest.fn(),
},
buy_sell_store: {
show_advertiser_page: true,
hideAdvertiserPage: jest.fn(),
setShowAdvertiserPage: jest.fn(),
},
my_profile_store: {
setActiveTab: jest.fn(),
},
};

jest.mock('Pages/advertiser-page/advertiser-page-adverts', () => jest.fn(() => <div>adverts</div>));
jest.mock('Pages/advertiser-page/advertiser-page-stats', () => jest.fn(() => <div>stats</div>));
jest.mock('@deriv/components', () => ({
...jest.requireActual('@deriv/components'),
Loading: jest.fn(() => <div> loading...</div>),
}));

jest.mock('Stores', () => ({
...jest.requireActual('Stores'),
useStores: jest.fn(() => mock_store),
}));

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useLocation: jest.fn(() => ({
hash: '',
key: '0',
pathname: '/cashier/p2p/advertiser',
search: '?id=39',
})),
}));

describe('<Advertiserpage />', () => {
it('should render advertiser page', () => {
render(<AdvertiserPage />);
expect(mock_store.advertiser_page_store.onMount).toHaveBeenCalledTimes(1);
expect(mock_store.buy_sell_store.setShowAdvertiserPage).toHaveBeenCalledWith(true);
});
it('should handle unmount of advertiser page', () => {
const { unmount } = render(<AdvertiserPage />);
unmount();
expect(mock_store.advertiser_page_store.onUnmount).toHaveBeenCalled();
expect(mock_store.buy_sell_store.setShowAdvertiserPage).toHaveBeenCalledWith(false);
});

it('should call setCounterpartyAdvertiserId when component mounted', () => {
render(<AdvertiserPage />);
expect(mock_store.general_store.setCounterpartyAdvertiserId).toHaveBeenCalled();
});
});
16 changes: 11 additions & 5 deletions packages/p2p/src/pages/advertiser-page/advertiser-page.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import React from 'react';
import { useHistory } from 'react-router-dom';
import { useHistory, useLocation } from 'react-router-dom';
import classNames from 'classnames';
import { reaction } from 'mobx';
import { observer } from 'mobx-react-lite';

import { DesktopWrapper, Loading, MobileWrapper, Text } from '@deriv/components';
import { daysSince, isMobile } from '@deriv/shared';

import { Localize, localize } from 'Components/i18next';
import { useModalManagerContext } from 'Components/modal-manager/modal-manager-context';
import { OnlineStatusIcon, OnlineStatusLabel } from 'Components/online-status';
Expand All @@ -28,12 +26,14 @@ const AdvertiserPage = () => {
const { advertiser_page_store, buy_sell_store, general_store, my_profile_store } = useStores();
const { hideModal, showModal, useRegisterModalProps } = useModalManagerContext();
const { advertiser_details_name, advertiser_details_id, counterparty_advertiser_info } = advertiser_page_store;
const { advertiser_id, advertiser_info, counterparty_advertiser_id } = general_store;

const is_my_advert = advertiser_details_id === general_store.advertiser_id;
const is_my_advert = advertiser_details_id === advertiser_id;
// Use general_store.advertiser_info since resubscribing to the same id from advertiser page returns error
const info = is_my_advert ? general_store.advertiser_info : counterparty_advertiser_info;
const info = is_my_advert ? advertiser_info : counterparty_advertiser_info;

const history = useHistory();
const location = useLocation();

const {
basic_verification,
Expand Down Expand Up @@ -68,6 +68,11 @@ const AdvertiserPage = () => {
};

React.useEffect(() => {
if (location.search || counterparty_advertiser_id) {
const url_params = new URLSearchParams(location.search);
general_store.setCounterpartyAdvertiserId(url_params.get('id'));
}

buy_sell_store.setShowAdvertiserPage(true);
advertiser_page_store.onMount();
advertiser_page_store.setIsDropdownMenuVisible(false);
Expand Down Expand Up @@ -130,6 +135,7 @@ const AdvertiserPage = () => {

return () => {
disposeBlockUnblockUserErrorReaction();
advertiser_page_store.onUnmount();
};
}, [advertiser_details_name, counterparty_advertiser_info]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import PropTypes from 'prop-types';

const BlockUserOverlay = ({ children, is_visible, onClickUnblock }) => {
const { advertiser_page_store } = useStores();
const { advertiser_details_name, counterparty_advertiser_info } = advertiser_page_store;

if (is_visible) {
return (
Expand All @@ -16,7 +17,7 @@ const BlockUserOverlay = ({ children, is_visible, onClickUnblock }) => {
<Text className='block-user-overlay__wrapper-text' weight='bold'>
<Localize
i18n_default_text='You have blocked {{advertiser_name}}.'
values={{ advertiser_name: advertiser_page_store.advertiser_details_name }}
values={{ advertiser_name: advertiser_details_name ?? counterparty_advertiser_info?.name }}
/>
</Text>
<Button className='block-user-overlay__wrapper-button' large onClick={onClickUnblock} secondary>
Expand Down
1 change: 0 additions & 1 deletion packages/p2p/src/pages/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ const App = () => {
} else if (/\/advertiser$/.test(location.pathname)) {
if (location.search || general_store.counterparty_advertiser_id) {
const url_params = new URLSearchParams(location.search);
general_store.setCounterpartyAdvertiserId(url_params.get('id'));

// DO NOT REMOVE. This will prevent the page from redirecting to buy sell on reload from advertiser page
// as it resets the URL search params
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { render } from '@testing-library/react';
import { useStores } from 'Stores/index';
import PaymentMethods from '../payment-methods';
import { APIProvider } from '@deriv/api';
import { StoreProvider, mockStore } from '@deriv/stores';

let mock_store: DeepPartial<ReturnType<typeof useStores>>;

jest.mock('Stores', () => ({
...jest.requireActual('Stores'),
useStores: jest.fn(() => mock_store),
}));

jest.mock('Pages/my-profile/payment-methods/add-payment-method', () => jest.fn(() => <div>AddPaymentMethod</div>));
jest.mock('Pages/my-profile/payment-methods/payment-methods-list/edit-payment-method-form', () =>
jest.fn(() => <div>EditPaymentMethodForm</div>)
);
jest.mock('Pages/my-profile/payment-methods/payment-methods-empty', () =>
jest.fn(() => <div>PaymentMethodsEmpty</div>)
);
jest.mock('Pages/my-profile/payment-methods/payment-methods-list', () => jest.fn(() => <div>PaymentMethodsList</div>));

describe('<PaymentMethods />', () => {
beforeEach(() => {
mock_store = {
general_store: {
active_index: 3,
setFormikRef: jest.fn(),
},
my_profile_store: {
advertiser_has_payment_methods: true,
hideAddPaymentMethodForm: jest.fn(),
is_loading: false,
getAdvertiserPaymentMethods: jest.fn(),
getPaymentMethodsList: jest.fn(),
setAddPaymentMethodErrorMessage: jest.fn(),
setIsLoading: jest.fn(),
setShouldShowAddPaymentMethodForm: jest.fn(),
setShouldShowEditPaymentMethodForm: jest.fn(),
should_show_add_payment_method_form: false,
},
};
});

it('should call getPaymentMethodsList when component mounted', () => {
render(
<APIProvider>
<StoreProvider store={mockStore({})}>
<PaymentMethods />
</StoreProvider>
</APIProvider>
);
expect(mock_store.my_profile_store.getPaymentMethodsList).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const PaymentMethods = ({ formik_ref }) => {
React.useEffect(() => {
my_profile_store.setIsLoading(true);
my_profile_store.getAdvertiserPaymentMethods();
my_profile_store.getPaymentMethodsList();
my_profile_store.setShouldShowAddPaymentMethodForm(false);
my_profile_store.setShouldShowEditPaymentMethodForm(false);
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down
10 changes: 5 additions & 5 deletions packages/p2p/src/stores/advertiser-page-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ export default class AdvertiserPageStore extends BaseStore {
? { local_currency: buy_sell_store.selected_local_currency }
: {}),
}).then(response => {
if (response.error) {
if (response?.error) {
this.setErrorMessage(response.error);
} else {
const { list } = response.p2p_advert_list;
const { list } = response?.p2p_advert_list ?? {};

this.setAdverts(list);
this.setHasMoreAdvertsToLoad(list.length >= general_store.list_item_limit);
this.setHasMoreAdvertsToLoad(list?.length >= general_store.list_item_limit);
}
this.setIsLoadingAdverts(false);
resolve();
Expand Down Expand Up @@ -192,7 +192,7 @@ export default class AdvertiserPageStore extends BaseStore {
p2p_advertiser_info: 1,
id: general_store.counterparty_advertiser_id,
}).then(response => {
if (response.error) {
if (response?.error) {
this.setErrorMessage(response.error);
} else {
this.setAdvertiserInfo(response);
Expand All @@ -206,7 +206,7 @@ export default class AdvertiserPageStore extends BaseStore {
onSubmit() {
const current_advertiser_id = this.advertiser_details_id ?? this.counterparty_advertiser_info?.id;
this.root_store.general_store.blockUnblockUser(!this.is_counterparty_advertiser_blocked, current_advertiser_id);
if (this.is_counterparty_advertiser_blocked) this.getCounterpartyAdvertiserList(this.advertiser_details_id);
if (this.is_counterparty_advertiser_blocked) this.getCounterpartyAdvertiserList(current_advertiser_id);
this.setIsDropdownMenuVisible(false);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/p2p/src/stores/my-profile-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ export default class MyProfileStore extends BaseStore {
requestWS({
p2p_advertiser_payment_methods: 1,
}).then(response => {
if (response.error) {
if (response?.error) {
this.setAdvertiserPaymentMethodsError(response.error.message);
} else {
this.setAdvertiserPaymentMethods(response?.p2p_advertiser_payment_methods);
Expand Down Expand Up @@ -538,7 +538,7 @@ export default class MyProfileStore extends BaseStore {
p2p_advertiser_update: 1,
show_name: this.root_store?.general_store?.should_show_real_name ? 1 : 0,
}).then(response => {
if (response.error) {
if (response?.error) {
this.setFormError(response.error.message);
this.root_store.general_store.setShouldShowRealName(
!this.root_store?.general_store?.should_show_real_name
Expand Down Expand Up @@ -638,7 +638,7 @@ export default class MyProfileStore extends BaseStore {
},
},
}).then(response => {
if (response.error) {
if (response?.error) {
this.setAddPaymentMethodErrorMessage(response.error.message);
this.root_store.general_store.showModal({
key: 'AddPaymentMethodErrorModal',
Expand Down
Loading