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: [IOBP-833] Sorting algorithms for PSP bundles #6382

Open
wants to merge 47 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
b935c2a
refactor: sorting algorithms for PSP bundles
LeleDallas Nov 7, 2024
e6fdc3a
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 7, 2024
f1b1de8
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 7, 2024
36b2c0f
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 7, 2024
a11cf23
refactor: update psp default sorting logic
LeleDallas Nov 7, 2024
2b3120a
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 7, 2024
cabf9d4
test: add missing test for common payments method
LeleDallas Nov 7, 2024
42fb9e8
Merge branch 'IOBP-833-GEC-sorting-logic' of https://github.com/pagop…
LeleDallas Nov 7, 2024
5c072b6
test: useSortPspBottomSheet test suite
LeleDallas Nov 7, 2024
c645ed7
refactor: update psp sorting logic
LeleDallas Nov 7, 2024
a394dfb
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 7, 2024
5932b27
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 7, 2024
6b74ff5
test: checkout reducer
LeleDallas Nov 8, 2024
6401beb
test: add screen suite test
LeleDallas Nov 8, 2024
c37f55a
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 8, 2024
d0b1d3c
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 11, 2024
fc66b39
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 11, 2024
9070102
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 12, 2024
2b22c7b
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 14, 2024
02bf633
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 15, 2024
7856245
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 18, 2024
fb51218
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 18, 2024
0455322
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 18, 2024
a5747e5
chore: update import from merge
LeleDallas Nov 20, 2024
f710d21
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 20, 2024
795f306
test: update expected value due function update
LeleDallas Nov 20, 2024
fc43089
Merge branch 'IOBP-833-GEC-sorting-logic' of https://github.com/pagop…
LeleDallas Nov 20, 2024
9ed080b
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 21, 2024
f08534f
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 25, 2024
61f57f1
test: adjust failed test on action failure
LeleDallas Nov 25, 2024
c05ae5f
test: select psp action
LeleDallas Nov 25, 2024
43c24a1
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 25, 2024
ed03c55
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Nov 26, 2024
201712d
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 2, 2024
454d589
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 3, 2024
27ec4de
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 5, 2024
f95cf53
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 5, 2024
f9f29aa
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 5, 2024
f9189e9
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 5, 2024
c792c99
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 5, 2024
21a9696
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 6, 2024
8335f8c
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 7, 2024
538d53f
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 11, 2024
7297446
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 13, 2024
ba9115f
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 16, 2024
e09e78b
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 16, 2024
c8a4ee3
Merge branch 'master' into IOBP-833-GEC-sorting-logic
LeleDallas Dec 18, 2024
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
Expand Up @@ -9,13 +9,13 @@ import { View } from "react-native";
import Placeholder from "rn-placeholder";

export const WalletPspListSkeleton = () => (
<>
<View testID="wallet-psp-list-skeleton">
<PspSkeleton showFeatured />
<Divider />
<PspSkeleton />
<Divider />
<PspSkeleton />
</>
</View>
);

type PspSkeletonProps = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { fireEvent, render } from "@testing-library/react-native";
import React from "react";
import { Button, Text } from "react-native";
import { WalletPaymentPspSortType } from "../../types";
import { useSortPspBottomSheet } from "../useSortPspBottomSheet";

// Mock bottom sheet hook
jest.mock("../../../../../utils/hooks/bottomSheet", () => ({
useIOBottomSheetAutoresizableModal: jest.fn().mockReturnValue({
isVisible: false,
show: jest.fn(),
hide: jest.fn()
})
}));

// Test component to render and use the hook
const ComponentWithPspBottomSheet = ({
onSortChange
}: {
onSortChange: (sortType: WalletPaymentPspSortType) => void;
}) => {
const { sortType, dismiss, present } = useSortPspBottomSheet({
onSortChange
});

return (
<>
<Text testID="current-sort-type">{sortType}</Text>
<Button title="Show" onPress={present} testID="show-button" />
<Button title="Hide" onPress={dismiss} testID="hide-button" />
<Button
title="Change to Name Sort"
onPress={() => onSortChange("name")}
testID="change-sort-button"
/>
</>
);
};

describe("useSortPspBottomSheet", () => {
it("should initialize sortType to 'default'", () => {
const onSortChangeMock = jest.fn();
const { getByTestId } = render(
<ComponentWithPspBottomSheet onSortChange={onSortChangeMock} />
);

expect(getByTestId("current-sort-type").children[0]).toBe("default");
});

it("should update sortType and call onSortChange when handleChangeSort is called", () => {
const onSortChangeMock = jest.fn();
const { getByTestId } = render(
<ComponentWithPspBottomSheet onSortChange={onSortChangeMock} />
);

// Trigger the sort change
fireEvent.press(getByTestId("change-sort-button"));
expect(onSortChangeMock).toHaveBeenCalledWith("name");
});

it("should call show and hide methods for the bottom sheet modal", () => {
const onSortChangeMock = jest.fn();
const { getByTestId } = render(
<ComponentWithPspBottomSheet onSortChange={onSortChangeMock} />
);

const showButton = getByTestId("show-button");
const hideButton = getByTestId("hide-button");

// Trigger show and hide methods
fireEvent.press(showButton);
fireEvent.press(hideButton);

expect(showButton).toBeTruthy();
expect(hideButton).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ const useSortPspBottomSheet = ({
const [sortType, setSortType] =
React.useState<WalletPaymentPspSortType>("default");

const handleChangeSort = (sortType: WalletPaymentPspSortType) => {
setSortType(sortType);
onSortChange(sortType);
const handleChangeSort = (currentSortCriteria: WalletPaymentPspSortType) => {
setSortType(currentSortCriteria);
onSortChange(currentSortCriteria);
};

const getModalContent = () => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,11 @@ const WalletPaymentPickPspScreen = () => {

return (
<GradientScrollView
testID="wallet-payment-pick-psp-screen"
primaryActionProps={
canContinue
? {
testID: "wallet-payment-pick-psp-continue-button",
label: I18n.t("wallet.payment.psp.continueButton"),
accessibilityLabel: I18n.t("wallet.payment.psp.continueButton"),
onPress: handleContinue,
Expand All @@ -202,15 +204,16 @@ const WalletPaymentPickPspScreen = () => {
}
>
<SelectPspHeadingContent />
{!isLoading && (
{isLoading ? (
<WalletPspListSkeleton />
) : (
<RadioGroup<string>
onPress={handlePspSelection}
type="radioListItemWithAmount"
selectedItem={pspSelected?.idBundle}
items={getRadioItemsFromPspList(sortedPspList, showFeaturedPsp)}
/>
)}
{isLoading && <WalletPspListSkeleton />}
{sortPspBottomSheet}
</GradientScrollView>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import * as pot from "@pagopa/ts-commons/lib/pot";
import { fireEvent } from "@testing-library/react-native";
import * as O from "fp-ts/lib/Option";
import React from "react";
import { Store } from "redux";
import configureMockStore from "redux-mock-store";
import I18n from "../../../../../i18n";
import { applicationChangeState } from "../../../../../store/actions/application";
import { appReducer } from "../../../../../store/reducers";
import { GlobalState } from "../../../../../store/reducers/types";
import { renderScreenWithNavigationStoreContext } from "../../../../../utils/testWrapper";
import { PaymentsCheckoutRoutes } from "../../navigation/routes";
import { selectPaymentPspAction } from "../../store/actions/orchestration";
import { PaymentsCheckoutState } from "../../store/reducers";
import { WalletPaymentStepEnum } from "../../types";
import { WalletPaymentPickPspScreen } from "../WalletPaymentPickPspScreen";

describe("WalletPaymentPickPspScreen", () => {
const mockStore = configureMockStore<GlobalState>();

const checkout: PaymentsCheckoutState = {
currentStep: WalletPaymentStepEnum.PICK_PSP,
pspList: pot.someLoading([
{
id: "test"
}
]),
paymentDetails: pot.none,
userWallets: pot.none,
recentUsedPaymentMethod: pot.none,
allPaymentMethods: pot.none,
selectedWallet: O.none,
selectedPaymentMethod: O.none,
selectedPsp: O.none,
transaction: pot.none,
authorizationUrl: pot.none
};

const globalState = appReducer(undefined, applicationChangeState("active"));
const state = {
...globalState,
features: {
...globalState.features,
payments: {
...globalState.features.payments,
checkout
}
}
};

const renderPspScreen = (store: Store<GlobalState>) =>
renderScreenWithNavigationStoreContext<GlobalState>(
() => <WalletPaymentPickPspScreen />,
PaymentsCheckoutRoutes.PAYMENT_CHECKOUT_MAKE,
{},
store
);

it("should render the screen", () => {
const store: ReturnType<typeof mockStore> = mockStore(state);
const { getByTestId } = renderPspScreen(store);
expect(getByTestId("wallet-payment-pick-psp-screen")).toBeDefined();
});

it("should render with skeleton", () => {
const store: ReturnType<typeof mockStore> = mockStore({
...state,
features: {
...state.features,
payments: {
...state.features.payments,
checkout: {
...checkout,
pspList: pot.someLoading([])
}
}
}
});
const { getByTestId } = renderPspScreen(store);
expect(getByTestId("wallet-psp-list-skeleton")).toBeDefined();
});

it("should render the screen with the continue button disabled", () => {
const store: ReturnType<typeof mockStore> = mockStore(state);
const { getByTestId, queryByText } = renderPspScreen(store);
expect(getByTestId("wallet-payment-pick-psp-screen")).toBeDefined();
expect(queryByText("wallet-payment-pick-psp-continue-button")).toBeNull();
});

it("should render the screen with the continue button enabled", () => {
const store: ReturnType<typeof mockStore> = mockStore({
...state,
features: {
...state.features,
payments: {
...state.features.payments,
checkout: {
...checkout,
selectedPsp: O.some({
id: "test"
})
}
}
}
});
const { getByTestId } = renderPspScreen(store);
expect(getByTestId("wallet-payment-pick-psp-screen")).toBeDefined();
expect(
getByTestId("wallet-payment-pick-psp-continue-button")
).toBeDefined();
});

it("should show bottom sheet", () => {
const store: ReturnType<typeof mockStore> = mockStore(state);
const { getByText } = renderPspScreen(store);
fireEvent.press(getByText(I18n.t("wallet.payment.psp.pspTitle")));
expect(
getByText(I18n.t("wallet.payment.psp.sortBottomSheet.default"))
).toBeDefined();
});

it("should sort by amount", () => {
const store: ReturnType<typeof mockStore> = mockStore(state);
const { getByText } = renderPspScreen(store);
fireEvent.press(getByText(I18n.t("wallet.payment.psp.pspTitle")));
fireEvent.press(
getByText(I18n.t("wallet.payment.psp.sortBottomSheet.amount"))
);
expect(
getByText(I18n.t("wallet.payment.psp.sortBottomSheet.amount"))
).toBeDefined();
});

it("should sort by name", () => {
const store: ReturnType<typeof mockStore> = mockStore(state);
const { getByText } = renderPspScreen(store);
fireEvent.press(getByText(I18n.t("wallet.payment.psp.pspTitle")));
fireEvent.press(
getByText(I18n.t("wallet.payment.psp.sortBottomSheet.name"))
);
expect(
getByText(I18n.t("wallet.payment.psp.sortBottomSheet.name"))
).toBeDefined();
});

it("should select a PSP", () => {
const store: ReturnType<typeof mockStore> = mockStore({
...state,
features: {
...state.features,
payments: {
...state.features.payments,
checkout: {
...checkout,
pspList: pot.some([
{
idBundle: "test",
pspBusinessName: "Test PSP",
taxPayerFee: 100
}
])
}
}
}
});
const { getByText } = renderPspScreen(store);
fireEvent.press(getByText("Test PSP"));
expect(store.getActions()).toContainEqual(
selectPaymentPspAction({
idBundle: "test",
pspBusinessName: "Test PSP",
taxPayerFee: 100
})
);
});
});
Loading
Loading