Skip to content

Commit

Permalink
chore: [IOBP-1122] Remove PSP preselection logic based on the onUs fi…
Browse files Browse the repository at this point in the history
…eld (#6612)

## Short description
This PR removes the logic to preselect a PSP if there is the `onUs`
field;

## List of changes proposed in this pull request
- Removed the `onUs` check to preselect the PSP when in the PSP list
choosing screen;
- Edited the featured label;
- Added the onUs as first element in the sorting algorithm;
- Added unit tests;

## How to test
- Update the dev-server;
- Run the dev-server and start a new payment;
- After choosing a payment method, check that when the PSP list
presents, there is any element preselected but there must be the
featured text `Sei già cliente`


https://github.com/user-attachments/assets/34c69c71-2287-4db5-bc27-fc816fe8de30
  • Loading branch information
Hantex9 authored Jan 17, 2025
1 parent 93bd0a8 commit 2d7127a
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 6 deletions.
2 changes: 1 addition & 1 deletion locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1894,7 +1894,7 @@ wallet:
defaultName: Gestore
pspTitle: Gestore
pspSortButton: Ordina
featuredReason: Perché sei già cliente
featuredReason: Sei già cliente
continueButton: Continua
sortBottomSheet:
default: Default
Expand Down
2 changes: 1 addition & 1 deletion locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1894,7 +1894,7 @@ wallet:
defaultName: Gestore
pspTitle: Gestore
pspSortButton: Ordina
featuredReason: Perché sei già cliente
featuredReason: Sei già cliente
continueButton: Continua
sortBottomSheet:
default: Default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ const WalletPaymentPickPspScreen = () => {
() => ({
type: "buttonLink",
componentProps: {
testID: "wallet-payment-pick-psp-sort-button",
label: I18n.t("wallet.payment.psp.pspSortButton"),
accessibilityLabel: I18n.t("wallet.payment.psp.pspSortButton"),
onPress: present
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { View } from "react-native";
import React from "react";
import { fireEvent } from "@testing-library/react-native";
import { createStore } from "redux";
import configureMockStore from "redux-mock-store";
import { appReducer } from "../../../../../store/reducers";
import { applicationChangeState } from "../../../../../store/actions/application";
import { GlobalState } from "../../../../../store/reducers/types";
import { RptId } from "../../../../../../definitions/pagopa/ecommerce/RptId";
import { renderScreenWithNavigationStoreContext } from "../../../../../utils/testWrapper";
import { PaymentsCheckoutRoutes } from "../../navigation/routes";
import { paymentsCalculatePaymentFeesAction } from "../../store/actions/networking";
import { useIOBottomSheetAutoresizableModal } from "../../../../../utils/hooks/bottomSheet";
import { WalletPaymentPickPspScreen } from "../WalletPaymentPickPspScreen";
import { Bundle } from "../../../../../../definitions/pagopa/ecommerce/Bundle";
import { PaymentMethodStatusEnum } from "../../../../../../definitions/pagopa/ecommerce/PaymentMethodStatus";
import I18n from "../../../../../i18n";

jest.mock("../../analytics");
jest.mock("../../../../../utils/hooks/bottomSheet");

const mockNavigation = {
navigate: jest.fn(),
setOptions: jest.fn()
};

jest.mock("@react-navigation/native", () => ({
...jest.requireActual("@react-navigation/native"),
useNavigation: () => mockNavigation,
useRoute: () => ({
params: { rptId: "1234567890" as RptId }
})
}));

const CHEAPER_VALUE = 123;
const MIDDLE_VALUE = 456;
const EXPENSIVE_VALUE = 789;
const MOCKED_PSP_LIST: ReadonlyArray<Bundle> = [
{
idPsp: "1",
abi: "01010",
pspBusinessName: "BANCO di NAPOLI",
taxPayerFee: CHEAPER_VALUE,
primaryCiIncurredFee: CHEAPER_VALUE,
idBundle: "A"
},
{
idPsp: "2",
abi: "01015",
pspBusinessName: "Banco di Sardegna",
taxPayerFee: MIDDLE_VALUE,
primaryCiIncurredFee: MIDDLE_VALUE,
idBundle: "B",
onUs: true
},
{
idPsp: "3",
abi: "03015",
pspBusinessName: "FINECO",
taxPayerFee: EXPENSIVE_VALUE,
primaryCiIncurredFee: EXPENSIVE_VALUE,
idBundle: "C"
}
];

const globalState = appReducer(undefined, applicationChangeState("active"));
const mockStore = configureMockStore<GlobalState>();
const mockModal = {
present: jest.fn(),
dismiss: jest.fn(),
bottomSheet: <View testID="modal-view-test" />
};
const mockedUseIOBottomSheetAutoresizableModal =
useIOBottomSheetAutoresizableModal as jest.Mock;
mockedUseIOBottomSheetAutoresizableModal.mockReturnValue(mockModal);

describe("WalletPaymentPickPspScreen", () => {
const renderComponent = () => {
const state = mockStore(globalState);
const store = createStore(appReducer, state as any);
return {
...renderScreenWithNavigationStoreContext<GlobalState>(
WalletPaymentPickPspScreen,
PaymentsCheckoutRoutes.PAYMENT_CHECKOUT_MAKE,
{},
store
),
store
};
};

it("renders the main content with the list content if psp list is available", () => {
const { getAllByText, store } = renderComponent();

store.dispatch(
paymentsCalculatePaymentFeesAction.success({
bundles: MOCKED_PSP_LIST,
asset: "MOCK",
paymentMethodDescription: "MOCK",
paymentMethodName: "MOCK",
paymentMethodStatus: PaymentMethodStatusEnum.ENABLED
})
);

expect(getAllByText("BANCO di NAPOLI")).toBeTruthy();
});

it("shows the featured reason if there is a psp with the onUs flag", () => {
const { getByText, store } = renderComponent();
store.dispatch(
paymentsCalculatePaymentFeesAction.success({
bundles: MOCKED_PSP_LIST,
asset: "MOCK",
paymentMethodDescription: "MOCK",
paymentMethodName: "MOCK",
paymentMethodStatus: PaymentMethodStatusEnum.ENABLED
})
);
expect(getByText(I18n.t("wallet.payment.psp.featuredReason"))).toBeTruthy();
});

it("doesn't show the featured reason if there is not a psp with the onUs flag", () => {
const { queryByText, store } = renderComponent();
store.dispatch(
paymentsCalculatePaymentFeesAction.success({
bundles: MOCKED_PSP_LIST.map(psp => {
const { onUs, ...rest } = psp;
return rest;
}),
asset: "MOCK",
paymentMethodDescription: "MOCK",
paymentMethodName: "MOCK",
paymentMethodStatus: PaymentMethodStatusEnum.ENABLED
})
);
expect(queryByText(I18n.t("wallet.payment.psp.featuredReason"))).toBeNull();
});

it("presents bottom sheet press the sort button", () => {
const { getByTestId, store } = renderComponent();
store.dispatch(
paymentsCalculatePaymentFeesAction.success({
bundles: MOCKED_PSP_LIST,
asset: "MOCK",
paymentMethodDescription: "MOCK",
paymentMethodName: "MOCK",
paymentMethodStatus: PaymentMethodStatusEnum.ENABLED
})
);
const sortButton = getByTestId("wallet-payment-pick-psp-sort-button");
fireEvent.press(sortButton);
expect(mockModal.present).toHaveBeenCalled();
});
});
4 changes: 2 additions & 2 deletions ts/features/payments/checkout/store/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ const reducer = (
// Bundles are stored sorted by default sort rule
const sortedBundles = getSortedPspList(bundles, "default");

// Automatically select PSP if only 1 received or with `onUs` property
// Automatically select PSP if only 1 received
const preselectedPsp =
sortedBundles.length === 1 || sortedBundles[0]?.onUs
sortedBundles.length === 1
? O.some(sortedBundles[0])
: state.selectedPsp;

Expand Down
64 changes: 63 additions & 1 deletion ts/features/payments/common/utils/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { format } from "date-fns";
import { isPaymentMethodExpired } from "..";
import { getSortedPspList, isPaymentMethodExpired } from "..";
import { Bundle } from "../../../../../../definitions/pagopa/ecommerce/Bundle";

describe("isPaymentMethodExpired", () => {
it("should return true if payment method is expired", () => {
Expand All @@ -23,3 +24,64 @@ describe("isPaymentMethodExpired", () => {
expect(result).toBeFalsy();
});
});

describe("getSortedPspList", () => {
const CHEAPER_VALUE = 123;
const MIDDLE_VALUE = 456;
const EXPENSIVE_VALUE = 789;
const MOCKED_PSP_LIST: ReadonlyArray<Bundle> = [
{
idPsp: "1",
abi: "01010",
pspBusinessName: "BANCO di NAPOLI",
taxPayerFee: CHEAPER_VALUE,
primaryCiIncurredFee: CHEAPER_VALUE,
idBundle: "A"
},
{
idPsp: "2",
abi: "01015",
pspBusinessName: "Banco di Sardegna",
taxPayerFee: MIDDLE_VALUE,
primaryCiIncurredFee: MIDDLE_VALUE,
idBundle: "B",
onUs: true
},
{
idPsp: "3",
abi: "03015",
pspBusinessName: "FINECO",
taxPayerFee: EXPENSIVE_VALUE,
primaryCiIncurredFee: EXPENSIVE_VALUE,
idBundle: "C"
}
];

it("should return as first element the element with onUs flag if default sorting", () => {
const result = getSortedPspList(MOCKED_PSP_LIST, "default");
expect(result[0].onUs).toBe(true);
});

it("should return the list by amount from the cheaper to the more expensive if amount sorting", () => {
const result = getSortedPspList(MOCKED_PSP_LIST, "amount");
expect(result[0].taxPayerFee).toBe(CHEAPER_VALUE);
expect(result[1].taxPayerFee).toBe(MIDDLE_VALUE);
expect(result[2].taxPayerFee).toBe(EXPENSIVE_VALUE);
});

it("should return the list sorted by name if name sorting", () => {
const result = getSortedPspList(MOCKED_PSP_LIST, "name");
expect(result[0].pspBusinessName).toBe("BANCO di NAPOLI");
expect(result[1].pspBusinessName).toBe("Banco di Sardegna");
expect(result[2].pspBusinessName).toBe("FINECO");
});

it("should return the exact same list if default sorting and not present the onUs flag", () => {
const MOCKED_PSP_LIST_WITHOUT_ONUS = MOCKED_PSP_LIST.map(psp => {
const { onUs, ...rest } = psp;
return rest;
});
const result = getSortedPspList(MOCKED_PSP_LIST_WITHOUT_ONUS, "default");
expect(result).toEqual(MOCKED_PSP_LIST_WITHOUT_ONUS);
});
});
2 changes: 1 addition & 1 deletion ts/features/payments/common/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export const getSortedPspList = (
return _.orderBy(
pspList,
["onUs", "taxPayerFee", "pspBusinessName"],
["desc", "asc", "asc"]
["asc", "asc", "asc"]
);
}
};
Expand Down

0 comments on commit 2d7127a

Please sign in to comment.