Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 12 additions & 7 deletions ts/features/messages/saga/handleThirdPartyMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as E from "fp-ts/lib/Either";
import { call, put, select } from "typed-redux-saga/macro";
import { ActionType } from "typesafe-actions";
import { loadThirdPartyMessage } from "../store/actions";
import { toSENDMessage } from "../../pn/store/types/transformers";
import {
trackPNNotificationLoadError,
trackPNNotificationLoadSuccess
Expand All @@ -29,6 +28,7 @@ import { apiUrlPrefix } from "../../../config";
import { sessionTokenSelector } from "../../authentication/common/store/selectors";
import { isTestEnv } from "../../../utils/environment";
import { getKeyInfo } from "../../lollipop/saga";
import { ThirdPartyMessage } from "../../../../definitions/pn/ThirdPartyMessage";

export function* handleThirdPartyMessage(
action: ActionType<typeof loadThirdPartyMessage.request>
Expand Down Expand Up @@ -113,15 +113,20 @@ const trackSuccess = (
tag
);
if (tag === TagEnum.PN) {
const sendMessageOrUndefined = toSENDMessage(messageFromApi);
const sendThirdPartyMessageEither = ThirdPartyMessage.decode(
messageFromApi.third_party_message
);
if (
E.isRight(sendThirdPartyMessageEither) &&
sendThirdPartyMessageEither.right.details != null
) {
const { attachments, details } = sendThirdPartyMessageEither.right;
const hasAttachments = attachments != null && attachments.length > 0;
const timeline = details.notificationStatusHistory;

if (sendMessageOrUndefined != null) {
const hasAttachments =
sendMessageOrUndefined.attachments != null &&
sendMessageOrUndefined.attachments.length > 0;
const timeline = sendMessageOrUndefined.notificationStatusHistory;
const status =
timeline.length > 0 ? timeline[timeline.length - 1].status : undefined;

trackPNNotificationLoadSuccess(
hasAttachments,
status,
Expand Down
68 changes: 56 additions & 12 deletions ts/features/pn/aar/store/selectors/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
} from "..";
import { GlobalState } from "../../../../../../store/reducers/types";
import { thirdPartyFromIdSelector } from "../../../../../messages/store/reducers/thirdPartyById";
import { toSENDMessage } from "../../../../store/types/transformers";
import {
AARFlowState,
maybeIunFromAarFlowState,
Expand All @@ -30,20 +29,27 @@ const mockIoMessageId = "test-id";
jest.mock("../../../../../messages/store/reducers/thirdPartyById", () => ({
thirdPartyFromIdSelector: jest.fn()
}));
jest.mock("../../../../store/types/transformers", () => ({
toSENDMessage: jest.fn()
}));

describe("thirdPartySenderDenominationSelector", () => {
beforeEach(() => {
jest.clearAllMocks();
});

it("should return senderDenomination when all data is present", () => {
(thirdPartyFromIdSelector as jest.Mock).mockReturnValue(pot.some({}));
(toSENDMessage as jest.Mock).mockReturnValue({
senderDenomination: "Denomination"
const thirdPartyMessagePot = pot.some({
third_party_message: {
details: {
iun: "",
notificationStatusHistory: [],
recipients: [],
senderDenomination: "Denomination",
subject: ""
}
}
});
(thirdPartyFromIdSelector as jest.Mock).mockReturnValue(
thirdPartyMessagePot
);

const result = thirdPartySenderDenominationSelector(
mockState,
Expand All @@ -62,9 +68,36 @@ describe("thirdPartySenderDenominationSelector", () => {
expect(result).toBeUndefined();
});

it("should return undefined if toPNMessage returns undefined", () => {
(thirdPartyFromIdSelector as jest.Mock).mockReturnValue(pot.some({}));
(toSENDMessage as jest.Mock).mockReturnValue(undefined);
it("should return undefined if data structure is not a ThirdPartyMessage", () => {
const thirdPartyMessagePot = pot.some({
third_party_message: {
details: {
notificationStatusHistory: [],
recipients: [],
subject: ""
}
}
});
(thirdPartyFromIdSelector as jest.Mock).mockReturnValue(
pot.some(thirdPartyMessagePot)
);

const result = thirdPartySenderDenominationSelector(
mockState,
mockIoMessageId
);
expect(result).toBeUndefined();
});

it("should return undefined if there are no details", () => {
const thirdPartyMessagePot = pot.some({
third_party_message: {
attachments: []
}
});
(thirdPartyFromIdSelector as jest.Mock).mockReturnValue(
pot.some(thirdPartyMessagePot)
);

const result = thirdPartySenderDenominationSelector(
mockState,
Expand All @@ -74,8 +107,19 @@ describe("thirdPartySenderDenominationSelector", () => {
});

it("should return undefined if senderDenomination is missing", () => {
(thirdPartyFromIdSelector as jest.Mock).mockReturnValue(pot.some({}));
(toSENDMessage as jest.Mock).mockReturnValue({});
const thirdPartyMessagePot = pot.some({
third_party_message: {
details: {
iun: "",
notificationStatusHistory: [],
recipients: [],
subject: ""
}
}
});
(thirdPartyFromIdSelector as jest.Mock).mockReturnValue(
thirdPartyMessagePot
);

const result = thirdPartySenderDenominationSelector(
mockState,
Expand Down
12 changes: 9 additions & 3 deletions ts/features/pn/aar/store/selectors/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as pot from "@pagopa/ts-commons/lib/pot";
import { createSelector } from "reselect";
import { isLeft } from "fp-ts/lib/Either";
import { GlobalState } from "../../../../../store/reducers/types";
import { thirdPartyFromIdSelector } from "../../../../messages/store/reducers/thirdPartyById";
import { toSENDMessage } from "../../../store/types/transformers";
import { ThirdPartyMessage } from "../../../../../../definitions/pn/ThirdPartyMessage";
import {
AARFlowState,
maybeIunFromAarFlowState,
Expand All @@ -18,8 +19,13 @@ export const thirdPartySenderDenominationSelector = (
if (thirdPartyMessage == null) {
return undefined;
}
const sendMessage = toSENDMessage(thirdPartyMessage);
return sendMessage?.senderDenomination;
const sendThirdPartyMessageEither = ThirdPartyMessage.decode(
thirdPartyMessage.third_party_message
);
if (isLeft(sendThirdPartyMessageEither)) {
return undefined;
}
return sendThirdPartyMessageEither.right?.details?.senderDenomination;
};

export const aarAdresseeDenominationSelector = (
Expand Down
31 changes: 13 additions & 18 deletions ts/features/pn/components/MessageDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import {
useFooterActionsMeasurements,
useIOTheme
} from "@pagopa/io-app-design-system";
import * as O from "fp-ts/lib/Option";
import * as RA from "fp-ts/lib/ReadonlyArray";
import * as SEP from "fp-ts/lib/Separated";
import { pipe } from "fp-ts/lib/function";
import I18n from "i18next";
import { useRef } from "react";
import { ScrollView } from "react-native";
Expand All @@ -19,7 +15,6 @@ import { NotificationPaymentInfo } from "../../../../definitions/pn/Notification
import { MessageDetailsAttachments } from "../../messages/components/MessageDetail/MessageDetailsAttachments";
import { MessageDetailsHeader } from "../../messages/components/MessageDetail/MessageDetailsHeader";
import { ATTACHMENT_CATEGORY } from "../../messages/types/attachmentCategory";
import { PNMessage } from "../store/types/types";
import {
maxVisiblePaymentCount,
openingSourceIsAarMessage,
Expand All @@ -29,6 +24,7 @@ import {
SendOpeningSource,
SendUserType
} from "../../pushNotifications/analytics";
import { IOReceivedNotification } from "../../../../definitions/pn/IOReceivedNotification";
import { BannerAttachments } from "./BannerAttachments";
import { F24Section } from "./F24Section";
import { MessageBottomMenu } from "./MessageBottomMenu";
Expand All @@ -39,7 +35,9 @@ import { MessagePaymentBottomSheet } from "./MessagePaymentBottomSheet";
import { MessagePayments } from "./MessagePayments";

export type MessageDetailsProps = {
message: PNMessage;
attachments: ReadonlyArray<ThirdPartyAttachment> | undefined;
createdAt: Date | undefined;
message: IOReceivedNotification;
messageId: string;
serviceId: ServiceId;
payments?: ReadonlyArray<NotificationPaymentInfo>;
Expand All @@ -48,6 +46,8 @@ export type MessageDetailsProps = {
};

export const MessageDetails = ({
attachments,
createdAt,
message,
messageId,
payments,
Expand All @@ -56,27 +56,22 @@ export const MessageDetails = ({
sendUserType
}: MessageDetailsProps) => {
const presentPaymentsBottomSheetRef = useRef<() => void>(undefined);
const partitionedAttachments = pipe(
message.attachments,
O.fromNullable,
O.getOrElse<ReadonlyArray<ThirdPartyAttachment>>(() => []),
RA.partition(attachment => attachment.category === ATTACHMENT_CATEGORY.F24)
);

const theme = useIOTheme();

const { footerActionsMeasurements, handleFooterActionsMeasurements } =
useFooterActionsMeasurements();

const attachmentList = SEP.left(partitionedAttachments);

const hasStandardAttachments = attachments?.some(
attachment =>
attachment.category != null &&
attachment.category !== ATTACHMENT_CATEGORY.F24
);
const isCancelled = message.isCancelled ?? false;
const completedPaymentNoticeCodes = isCancelled
? message.completedPayments
: undefined;

const isAarMessage = openingSourceIsAarMessage(sendOpeningSource);
const maybeMessageDate = isAarMessage ? undefined : message.created_at;
const maybeMessageDate = isAarMessage ? undefined : createdAt;
return (
<>
<ScrollView
Expand All @@ -97,7 +92,7 @@ export const MessageDetails = ({
text={I18n.t("features.pn.details.badge.legalValue")}
variant="legalMessage"
/>
{attachmentList.length > 0 && (
{hasStandardAttachments && (
<Icon
color={theme["icon-default"]}
name="attachment"
Expand Down
4 changes: 2 additions & 2 deletions ts/features/pn/components/MessageDetailsContent.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { BodySmall } from "@pagopa/io-app-design-system";
import I18n from "i18next";
import { useIOSelector } from "../../../store/hooks";
import { PNMessage } from "../store/types/types";
import { aarAdresseeDenominationSelector } from "../aar/store/selectors";
import { sendShowAbstractSelector } from "../../../store/reducers/backendStatus/remoteConfig";
import { isTestEnv } from "../../../utils/environment";
import { SendUserType } from "../../pushNotifications/analytics";
import { IOReceivedNotification } from "../../../../definitions/pn/IOReceivedNotification";

export type MessageDetailsContentProps = {
message: PNMessage;
message: IOReceivedNotification;
sendUserType: SendUserType;
};
export const MessageDetailsContent = ({
Expand Down
8 changes: 5 additions & 3 deletions ts/features/pn/components/__mocks__/MessageDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { View } from "react-native";
import { MessageDetailsProps } from "../MessageDetails";

export const MessageDetails = ({
attachments,
createdAt,
message,
messageId,
serviceId,
Expand All @@ -12,8 +14,8 @@ export const MessageDetails = ({
<View>
<View>Mock MessageDetails</View>
{message.abstract && <View>{message.abstract}</View>}
{message.attachments &&
message.attachments.map((attachment, index) => (
{attachments &&
attachments.map((attachment, index) => (
<View key={`a_${index}`}>
{attachment.category && <View>{attachment.category}</View>}
{attachment.content_type && <View>{attachment.content_type}</View>}
Expand All @@ -26,7 +28,7 @@ export const MessageDetails = ({
message.completedPayments.map((completedPayment, index) => (
<View key={`cp_${index}`}>{completedPayment}</View>
))}
<View>{`${message.created_at}`}</View>
<View>{`Created at: ${createdAt}`}</View>
{message.isCancelled && <View>{`${message.isCancelled}`}</View>}
<View>{message.iun}</View>
{message.notificationStatusHistory.map(
Expand Down
Loading
Loading