Skip to content

Commit

Permalink
Merge branch 'master' into IOBP-1047-add-store-review-when-payment-co…
Browse files Browse the repository at this point in the history
…mpleted
  • Loading branch information
Hantex9 authored Dec 4, 2024
2 parents 1857811 + 2767743 commit e1636a4
Show file tree
Hide file tree
Showing 15 changed files with 578 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ export const PaymentsBizEventsTransactionCartList = ({
};

const SkeletonTransactionDetailsList = () => (
<View style={[IOStyles.flex, IOStyles.rowSpaceBetween, IOStyles.alignCenter]}>
<View
style={[IOStyles.flex, IOStyles.rowSpaceBetween, IOStyles.alignCenter]}
testID="skeleton-transaction-details-list"
>
<View style={[IOStyles.flex, { paddingVertical: 12 }]}>
<Placeholder.Box height={16} width="90%" radius={4} />
<VSpacer size={8} />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Body, IOStyles, VSpacer } from "@pagopa/io-app-design-system";
import React from "react";
import { View } from "react-native";
import Placeholder from "rn-placeholder";
import I18n from "../../../../i18n";
import { InfoNotice } from "../../../../../definitions/pagopa/biz-events/InfoNotice";
import { formatAmountText, isValidPspName } from "../utils";

type Props = {
loading: boolean;
transactionInfo?: InfoNotice;
};

const PaymentsBizEventsTransactionFeeAmountSection = (props: Props) => {
const { loading, transactionInfo } = props;

if (loading) {
return (
<View style={IOStyles.flex} testID="loading-placeholder">
<VSpacer size={4} />
<Placeholder.Line width="100%" animate="fade" />
<VSpacer size={8} />
<Placeholder.Line width="50%" animate="fade" />
</View>
);
}

const pspName = transactionInfo?.pspName;

if (transactionInfo?.fee !== undefined) {
const formattedFee = formatAmountText(transactionInfo.fee);
return (
<Body>
{I18n.t("transaction.details.totalFee")}{" "}
<Body weight="Semibold">{formattedFee}</Body>{" "}
{isValidPspName(pspName)
? // we want to make sure no empty string is passed either
I18n.t("transaction.details.totalFeePsp", {
pspName
})
: I18n.t("transaction.details.totalFeeNoPsp")}
</Body>
);
}

return (
<Body>
{isValidPspName(pspName)
? I18n.t("features.payments.transactions.details.totalFeeUnknown", {
pspName
})
: I18n.t("features.payments.transactions.details.totalFeeUnknownPsp")}
</Body>
);
};

export default PaymentsBizEventsTransactionFeeAmountSection;
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
import _ from "lodash";
import {
Body,
IOColors,
IOStyles,
useIOTheme,
VSpacer,
VStack
} from "@pagopa/io-app-design-system";
import { useNavigation } from "@react-navigation/native";
import React from "react";
import { View } from "react-native";
import Placeholder from "rn-placeholder";
import { CartItem } from "../../../../../definitions/pagopa/biz-events/CartItem";
import I18n from "../../../../i18n";
import { NoticeDetailResponse } from "../../../../../definitions/pagopa/biz-events/NoticeDetailResponse";
import { Psp } from "../../../../types/pagopa";
import { calculateTotalAmount, formatAmountText } from "../utils";
import { PaymentsTransactionBizEventsStackNavigation } from "../navigation/navigator";
import { PaymentsTransactionBizEventsRoutes } from "../navigation/routes";
import { NoticeDetailResponse } from "../../../../../definitions/pagopa/biz-events/NoticeDetailResponse";
import { calculateTotalAmount } from "../utils";
import { PaymentsBizEventsTransactionCartList } from "./PaymentsBizEventsTransactionCartList";
import PaymentsBizEventsTransactionFeeAmountSection from "./PaymentsBizEventsTransactionFeeAmountSection";
import { PaymentsBizEventsTransactionTotalAmount } from "./PaymentsBizEventsTransactionTotalAmount";

type Props = {
Expand Down Expand Up @@ -50,44 +46,6 @@ export const PaymentsBizEventsTransactionHeadingSection = ({
}
};

const FeeAmountSection = () => {
if (isLoading) {
return (
<View style={IOStyles.flex}>
<VSpacer size={4} />
<Placeholder.Line width="100%" animate="fade" />
<VSpacer size={8} />
<Placeholder.Line width="50%" animate="fade" />
</View>
);
}
const pspName = transactionInfo?.pspName;
if (transactionInfo?.fee !== undefined) {
const formattedFee = formatAmountText(transactionInfo.fee);
return (
<Body>
{I18n.t("transaction.details.totalFee")}{" "}
<Body weight="Semibold">{formattedFee}</Body>{" "}
{pspName
? // we want to make sure no empty string is passed either
I18n.t("transaction.details.totalFeePsp", {
pspName
})
: I18n.t("transaction.details.totalFeeNoPsp")}
</Body>
);
}
return (
<Body>
{pspName
? I18n.t("features.payments.transactions.details.totalFeeUnknown", {
pspName
})
: I18n.t("features.payments.transactions.details.totalFeeUnknownPsp")}
</Body>
);
};

const totalAmount = calculateTotalAmount(transactionInfo);

return (
Expand All @@ -104,7 +62,10 @@ export const PaymentsBizEventsTransactionHeadingSection = ({
totalAmount={totalAmount}
/>
)}
<FeeAmountSection />
<PaymentsBizEventsTransactionFeeAmountSection
loading={isLoading}
transactionInfo={transactionInfo}
/>
</VStack>
</View>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { clipboardSetStringWithFeedback } from "../../../../utils/clipboard";
import { format } from "../../../../utils/dates";
import { capitalizeTextName } from "../../../../utils/strings";
import { WalletTransactionReceiptDivider } from "../../transaction/components/WalletTransactionReceiptDivider";
import { getPayerInfoLabel, removeAsterisks } from "../utils";
import { getPayerInfoLabel, isValidPspName, removeAsterisks } from "../utils";

type PaymentsBizEventsTransactionInfoSectionProps = {
transaction?: NoticeDetailResponse;
Expand Down Expand Up @@ -83,6 +83,7 @@ const PaymentsBizEventsTransactionInfoSection = ({
{transactionInfo.payer && (
<>
<ListItemInfo
testID="payer-info"
label={I18n.t("transaction.details.info.executedBy")}
value={getPayerInfoLabel(transactionInfo.payer)}
/>
Expand Down Expand Up @@ -110,15 +111,16 @@ const PaymentsBizEventsTransactionInfoSection = ({
<Divider />
</>
)}
{transactionInfo.pspName && (
<>
<ListItemInfo
label={I18n.t("transaction.details.info.pspName")}
value={transactionInfo.pspName}
/>
<Divider />
</>
)}
{transactionInfo.pspName &&
isValidPspName(transactionInfo.pspName) && (
<>
<ListItemInfo
label={I18n.t("transaction.details.info.pspName")}
value={transactionInfo.pspName}
/>
<Divider />
</>
)}
{transactionInfo.noticeDate && (
<>
<ListItemInfo
Expand Down Expand Up @@ -223,7 +225,7 @@ const renderPaymentMethod = (walletInfo: WalletInfo) => {
};

const SkeletonItem = () => (
<View style={[IOStyles.flex, { paddingVertical: 12 }]}>
<View style={[IOStyles.flex, { paddingVertical: 12 }]} testID="skeleton-item">
<Placeholder.Box height={16} width="80%" radius={4} />
<VSpacer size={8} />
<Placeholder.Box height={16} width="25%" radius={4} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ListItemTransaction, VSpacer } from "@pagopa/io-app-design-system";
import * as React from "react";
import { View } from "react-native";
import Placeholder from "rn-placeholder";
import { PaymentsBizEventsFadeInOutAnimationView } from "./PaymentsBizEventsFadeInOutAnimationView";

Expand All @@ -12,11 +13,11 @@ export const PaymentsBizEventsTransactionLoadingList = ({
}: PaymentsBizEventsTransactionLoadingListProps) => (
<>
{showSectionTitleSkeleton && (
<>
<View testID="section-title-skeleton">
<VSpacer size={16} />
<Placeholder.Box animate="fade" radius={8} width={62} height={16} />
<VSpacer size={16} />
</>
</View>
)}

{Array.from({ length: 5 }).map((_, index) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ export const PaymentsBizEventsTransactionTotalAmount = ({
{I18n.t("transaction.details.totalAmount")}
</H6>
{loading && (
<View>
<View testID="loader">
<Placeholder.Box width={72} height={34} animate="fade" radius={8} />
</View>
)}
{!loading && totalAmount && <H3>{formatAmountText(totalAmount)}</H3>}
{!loading && totalAmount && (
<H3 testID="total-amount">{formatAmountText(totalAmount)}</H3>
)}
</View>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { fireEvent, render } from "@testing-library/react-native";
import React from "react";
import {
PaymentBizEventsCategoryFilter,
paymentsBizEventsCategoryFilters
} from "../../types";
import { PaymentsBizEventsFilterTabs } from "../PaymentsBizEventsFilterTabs";

describe("PaymentsBizEventsFilterTabs", () => {
const mockOnCategorySelected = jest.fn();

const renderComponent = (selectedCategory: PaymentBizEventsCategoryFilter) =>
render(
<PaymentsBizEventsFilterTabs
selectedCategory={selectedCategory}
onCategorySelected={mockOnCategorySelected}
/>
);

beforeEach(() => {
mockOnCategorySelected.mockClear();
});

it("should render all category tabs", () => {
const { getByTestId } = renderComponent(
paymentsBizEventsCategoryFilters[0]
);

paymentsBizEventsCategoryFilters.forEach(category => {
expect(getByTestId(`CategoryTabTestID-${category}`)).toBeTruthy();
});
});

it("should call onCategorySelected with the correct category when a tab is pressed", () => {
const { getByTestId } = renderComponent(
paymentsBizEventsCategoryFilters[0]
);

const newCategory = paymentsBizEventsCategoryFilters[1];
fireEvent.press(getByTestId(`CategoryTabTestID-${newCategory}`));

expect(mockOnCategorySelected).toHaveBeenCalledWith(newCategory);
});

it("should not call onCategorySelected if the selected tab is pressed again", () => {
const selectedCategory = paymentsBizEventsCategoryFilters[0];
const { getByTestId } = renderComponent(selectedCategory);

fireEvent.press(getByTestId(`CategoryTabTestID-${selectedCategory}`));

expect(mockOnCategorySelected).not.toHaveBeenCalled();
});

it("should highlight the selected category tab", () => {
const selectedCategory = paymentsBizEventsCategoryFilters[1];
const { getByTestId } = renderComponent(selectedCategory);

const selectedTab = getByTestId(`CategoryTabTestID-${selectedCategory}`);
expect(selectedTab.props.accessibilityState.selected).toBe(true);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from "react";
import { render, fireEvent } from "@testing-library/react-native";
import { PaymentsBizEventsTransactionCartList } from "../PaymentsBizEventsTransactionCartList";
import { CartItem } from "../../../../../../definitions/pagopa/biz-events/CartItem";

describe("PaymentsBizEventsTransactionCartList", () => {
const mockOnPress = jest.fn();
const cartItems: ReadonlyArray<CartItem> = [
{
refNumberValue: "123",
subject: "Test Subject 1",
refNumberType: "Test Ref Number Type 1",
debtor: { name: "Test Debtor 1", taxCode: "Test Tax Code 1" },
amount: "1000"
},
{
refNumberValue: "456",
subject: "Test Subject 2",
refNumberType: "Test Ref Number Type 2",
debtor: { name: "Test Debtor 2", taxCode: "Test Tax Code 2" },
amount: "2000"
}
];

it("should render loading state", () => {
const { getByTestId } = render(
<PaymentsBizEventsTransactionCartList
loading={true}
onPress={mockOnPress}
/>
);
expect(getByTestId("skeleton-transaction-details-list")).toBeTruthy();
});

it("should render cart items", () => {
const { getByText } = render(
<PaymentsBizEventsTransactionCartList
carts={cartItems}
loading={false}
onPress={mockOnPress}
/>
);

expect(getByText("Test Subject 1")).toBeTruthy();
expect(getByText("Test Subject 2")).toBeTruthy();
});

it("should call onPress when a cart item is pressed", () => {
const { getByText } = render(
<PaymentsBizEventsTransactionCartList
carts={cartItems}
loading={false}
onPress={mockOnPress}
/>
);

fireEvent.press(getByText("Test Subject 1"));
expect(mockOnPress).toHaveBeenCalledWith(cartItems[0]);

fireEvent.press(getByText("Test Subject 2"));
expect(mockOnPress).toHaveBeenCalledWith(cartItems[1]);
});

it("should render null when carts are not provided", () => {
const { queryByText } = render(
<PaymentsBizEventsTransactionCartList
loading={false}
onPress={mockOnPress}
/>
);

expect(queryByText("Test Subject 1")).toBeNull();
expect(queryByText("Test Subject 2")).toBeNull();
});
});
Loading

0 comments on commit e1636a4

Please sign in to comment.