Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into fix/pn-9848
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreaCimini90 committed Mar 22, 2024
2 parents 1b15425 + 0272469 commit d28a5ea
Show file tree
Hide file tree
Showing 167 changed files with 2,385 additions and 1,683 deletions.
4 changes: 2 additions & 2 deletions aws-cdn-templates/one-cdn.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ Resources:
ContentSecurityPolicy:
ContentSecurityPolicy:
"default-src 'self' https://pnpg.uat.selfcare.pagopa.it/ https://pnpg.selfcare.pagopa.it/ ; \
connect-src 'self' https://api-eu.mixpanel.com/track/ \
connect-src 'self' https://api-eu.mixpanel.com/ \
https://uat.selfcare.pagopa.it/assets/ \
https://selfcare.pagopa.it/assets/ \
https://pnpg.uat.selfcare.pagopa.it/assets/ \
Expand Down Expand Up @@ -534,7 +534,7 @@ Resources:
Fn::Join:
- " "
- - "default-src 'self'; object-src 'none';"
- !Sub " connect-src 'self' https://api-eu.mixpanel.com/track/ \
- !Sub " connect-src 'self' https://api-eu.mixpanel.com/ \
https://selfcare.pagopa.it/assets/ \
https://privacyportalde-cdn.onetrust.com/ \
${WebApiUrl}; \
Expand Down
14 changes: 7 additions & 7 deletions packages/pn-commons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@
"@babel/preset-env": "^7.23.2",
"@babel/preset-react": "^7.23.2",
"@babel/preset-typescript": "^7.23.2",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.5.1",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/css-mediaquery": "^0.1.1",
"@typescript-eslint/eslint-plugin": "^6.7.3",
"@typescript-eslint/parser": "^6.7.3",
"@vitejs/plugin-react": "~4.1.1",
"@vitest/coverage-v8": "0.34.6",
"@vitejs/plugin-react": "^4.2.1",
"@vitest/coverage-v8": "^1.3.1",
"css-mediaquery": "^0.1.2",
"eslint": "7.11.0",
"eslint-config-prettier": "^8.3.0",
Expand All @@ -74,11 +74,11 @@
"eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-sonarjs": "^0.10.0",
"jsdom": "^16.7.0",
"jsdom": "^24.0.0",
"prettier": "^2.4.1",
"sonarqube-scanner": "^3.3.0",
"vite": "^4.5.0",
"vitest": "0.34.6",
"vitest-sonar-reporter": "0.5.0"
"vite": "^5.1.4",
"vitest": "1.3.1",
"vitest-sonar-reporter": "^2.0.0"
}
}
24 changes: 16 additions & 8 deletions packages/pn-commons/src/components/AppMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,45 @@
import { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import { IAppMessage, MessageType } from '../models';
import { IAppMessage } from '../models';
import { AppResponseOutcome } from '../models/AppResponse';
import { appStateActions, appStateSelectors } from '../redux';
import SnackBar from './SnackBar/SnackBar';

type EnqueuedMessage = {
type: 'error' | 'success';
type: AppResponseOutcome;
message: IAppMessage;
};

const AppMessage = () => {
const dispatch = useDispatch();
const errors = useSelector(appStateSelectors.selectErrors);
const success = useSelector(appStateSelectors.selectSuccess);
const info = useSelector(appStateSelectors.selectInfo);
const [currentMessage, setCurrentMessage] = useState<EnqueuedMessage | null>(null);
const [queue, setQueue] = useState<Array<EnqueuedMessage>>([]);

const isMessageEnqueued = (message: IAppMessage): boolean =>
queue.findIndex((elem) => elem.message.id === message.id) >= 0 ? true : false;

const onCloseToast = (message: EnqueuedMessage) => {
if (message.type === MessageType.ERROR) {
if (message.type === AppResponseOutcome.ERROR) {
/**
* keep "alreadyShown" property on IAppMessage to ensure back-compatibility with ApiErrorWrapper Component
* this property can be removed and ApiErrorWrapper refactored to take advantage of the pub/sub mechanism
*/
// dispatch(appStateActions.removeError(id));
dispatch(appStateActions.setErrorAsAlreadyShown(message.message.id));
} else {
} else if (message.type === AppResponseOutcome.SUCCESS) {
dispatch(appStateActions.removeSuccess(message.message.id));
} else {
dispatch(appStateActions.removeInfo(message.message.id));
}

setCurrentMessage(null);
};

const enqueueMessages = (messages: Array<IAppMessage>, type: 'success' | 'error') => {
const enqueueMessages = (messages: Array<IAppMessage>, type: AppResponseOutcome) => {
const newQueue: Array<EnqueuedMessage> = messages
.filter(
(message: IAppMessage) =>
Expand Down Expand Up @@ -65,13 +69,17 @@ const AppMessage = () => {
}, [currentMessage, queue]);

useEffect(() => {
enqueueMessages(errors, 'error');
enqueueMessages(errors, AppResponseOutcome.ERROR);
}, [errors]);

useEffect(() => {
enqueueMessages(success, 'success');
enqueueMessages(success, AppResponseOutcome.SUCCESS);
}, [success]);

useEffect(() => {
enqueueMessages(info, AppResponseOutcome.INFO);
}, [info]);

return (
<>
{currentMessage && (
Expand All @@ -80,7 +88,7 @@ const AppMessage = () => {
title={currentMessage.message.title}
message={currentMessage.message.message}
open
type={currentMessage.type === MessageType.ERROR ? MessageType.ERROR : MessageType.SUCCESS}
type={currentMessage.type}
onClose={() => onCloseToast(currentMessage)}
closingDelay={5000}
/>
Expand Down
6 changes: 3 additions & 3 deletions packages/pn-commons/src/components/AppResponseMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ import { AppResponsePublisher } from '../utility/AppResponse';
* @returns {any}
*/
type Props = {
eventTrackingToastErrorMessages?: (error: AppResponseError, traceid?: string) => void;
eventTrackingToastErrorMessages?: (error: AppResponseError, response: AppResponse) => void;
};
const AppResponseMessage = ({ eventTrackingToastErrorMessages }: Props) => {
const dispatch = useDispatch();

const showErrorMessage = (response: AppResponse) => {
const { errors, action, traceId, status } = response;
const { errors, action, status } = response;

errors?.forEach((error) => {
if (eventTrackingToastErrorMessages) {
eventTrackingToastErrorMessages(error, traceId);
eventTrackingToastErrorMessages(error, response);
}
dispatch(
appStateActions.addError({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import { Box, Radio, Skeleton, Typography } from '@mui/material';
import { ButtonNaked, CopyToClipboardButton } from '@pagopa/mui-italia';

import { useIsMobile } from '../../hooks';
import { PagoPAPaymentFullDetails, PaymentInfoDetail, PaymentStatus } from '../../models';
import {
EventPaymentRecipientType,
PagoPAPaymentFullDetails,
PaymentInfoDetail,
PaymentStatus,
} from '../../models';
import { formatEurocentToCurrency } from '../../utility';
import { formatDate } from '../../utility/date.utility';
import { getLocalizedOrDefaultLabel } from '../../utility/localization.utility';
Expand All @@ -19,7 +24,7 @@ type Props = {
handleDeselectPayment: () => void;
isSinglePayment?: boolean;
isCancelled: boolean;
handleTrackEventDetailPaymentError?: () => void;
handleTrackEventDetailPaymentError?: (event: EventPaymentRecipientType, param?: object) => void;
};

const SkeletonCard: React.FC = () => {
Expand Down Expand Up @@ -197,8 +202,12 @@ const NotificationPaymentPagoPAItem: React.FC<Props> = ({
pagoPAItem.detail !== PaymentInfoDetail.PAYMENT_EXPIRED;

if (isError && handleTrackEventDetailPaymentError) {
handleTrackEventDetailPaymentError();
handleTrackEventDetailPaymentError(EventPaymentRecipientType.SEND_PAYMENT_DETAIL_ERROR, {
detail: pagoPAItem.detail,
errorCode: pagoPAItem.errorCode,
});
}

const getErrorMessage = () => {
switch (pagoPAItem.detail) {
case PaymentInfoDetail.GENERIC_ERROR:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,7 @@ const NotificationPaymentRecipient: React.FC<Props> = ({
handleDeselectPayment={handleDeselectPayment}
isSinglePayment={isSinglePayment}
isCancelled={isCancelled}
handleTrackEventDetailPaymentError={() =>
handleTrackEventFn(EventPaymentRecipientType.SEND_PAYMENT_DETAIL_ERROR)
}
handleTrackEventDetailPaymentError={handleTrackEventFn}
/>
</Box>
) : null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,7 @@ describe('NotificationPaymentF24Item Component', () => {
expect(window.location.href).toBe(downloadUrl);
});

// TO-FIX: il test fallisce perchè sembra che in jest 27, useFakeTimers non funzioni correttamente
it.skip('download the attachment after retryAfter', async () => {
it('download the attachment after retryAfter', async () => {
vi.useFakeTimers();
const item = { ...f24Item, attachmentIdx: 1 };
const { getByTestId } = render(
Expand All @@ -185,28 +184,27 @@ describe('NotificationPaymentF24Item Component', () => {
expect(downloadingMessage).toBeInTheDocument();
expect(downloadingMessage).toHaveTextContent('detail.payment.download-f24-in-progress');
// wait...
act(() => {
vi.advanceTimersByTime((retryAfterDelay - 1000) / 2 + 200);
await act(async () => {
vi.advanceTimersToNextTimerAsync();
});
expect(downloadingMessage).toHaveTextContent('detail.payment.download-f24-waiting');
// wait...
act(() => {
vi.advanceTimersByTime((retryAfterDelay - 1000) / 2);
await act(async () => {
vi.advanceTimersToNextTimerAsync();
});
expect(downloadingMessage).toHaveTextContent('detail.payment.download-f24-ongoing');
// download the file
act(() => {
vi.advanceTimersByTime(1000);
});
await waitFor(() => {
await vi.waitFor(() => {
expect(downloadingMessage).not.toBeInTheDocument();
});
expect(window.location.href).toBe(downloadUrl);
vi.useRealTimers();
});

// TO-FIX: il test fallisce perchè sembra che in jest 27, useFakeTimers non funzioni correttamente
it.skip('should show error when interval is finished', async () => {
it('should show error when interval is finished', async () => {
vi.useFakeTimers();
const item = { ...f24Item, attachmentIdx: 1 };
const { getByTestId } = render(
Expand All @@ -224,22 +222,24 @@ describe('NotificationPaymentF24Item Component', () => {
const downloadButton = getByTestId('download-f24-button');
fireEvent.click(downloadButton);
// show downloading message and after recall the api to download the file
const downloadingMessage = await waitFor(() => getByTestId('f24-download-message'));
const downloadingMessage = await vi.waitFor(() => getByTestId('f24-download-message'));
expect(downloadingMessage).toBeInTheDocument();
expect(downloadingMessage).toHaveTextContent('detail.payment.download-f24-in-progress');
// wait...
act(() => {
vi.advanceTimersByTime((retryAfterDelay - 1000) / 2);
await act(async () => {
vi.advanceTimersToNextTimerAsync();
});
expect(downloadingMessage).toHaveTextContent('detail.payment.download-f24-waiting');
// wait...
act(() => {
vi.advanceTimersByTime((retryAfterDelay - 1000) / 2);
await act(async () => {
vi.advanceTimersToNextTimerAsync();
});
expect(downloadingMessage).toHaveTextContent('detail.payment.download-f24-ongoing');
// show the error
vi.advanceTimersByTime(1000);
const error = await waitFor(() => getByTestId('f24-maxTime-error'));
await act(async () => {
vi.advanceTimersByTimeAsync(1000);
});
const error = await vi.waitFor(() => getByTestId('f24-maxTime-error'));
expect(error).toBeInTheDocument();
expect(error).toHaveTextContent('detail.payment.f24-download-error');
vi.useRealTimers();
Expand Down
16 changes: 8 additions & 8 deletions packages/pn-commons/src/components/SnackBar/SnackBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import CloseIcon from '@mui/icons-material/Close';
import { Alert, AlertTitle, IconButton, Snackbar } from '@mui/material';

import { useIsMobile } from '../../hooks/useIsMobile';
import { MessageType } from '../../models/MessageType';
import { AppResponseOutcome } from '../../models/AppResponse';

type Props = {
/** whether the sneakbar should be open or not */
open: boolean;
/** message type (error, success, info, warning) */
type: MessageType;
type: AppResponseOutcome;
/** title to be shown */
title?: React.ReactNode;
/** message to be shown */
Expand Down Expand Up @@ -55,11 +55,11 @@ const SnackBar: React.FC<Props> = ({
return;
}, []);

const getColor = new Map<MessageType, 'error' | 'warning' | 'success' | 'info'>([
[MessageType.ERROR, 'error'],
[MessageType.WARNING, 'warning'],
[MessageType.SUCCESS, 'success'],
[MessageType.INFO, 'info'],
const getColor = new Map<AppResponseOutcome, 'error' | 'warning' | 'success' | 'info'>([
[AppResponseOutcome.ERROR, 'error'],
[AppResponseOutcome.WARNING, 'warning'],
[AppResponseOutcome.SUCCESS, 'success'],
[AppResponseOutcome.INFO, 'info'],
]);

const action = (
Expand Down Expand Up @@ -90,7 +90,7 @@ const SnackBar: React.FC<Props> = ({
}}
variant={variant}
>
{title && <AlertTitle id={`alert-api-status}`}>{title}</AlertTitle>}
{title && <AlertTitle id="alert-api-status">{title}</AlertTitle>}
{message}
</Alert>
</Snackbar>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { vi } from 'vitest';

import { MessageType } from '../../../models';
import { AppResponseOutcome } from '../../../models/AppResponse';
import { fireEvent, render, waitFor, within } from '../../../test-utils';
import SnackBar from '../SnackBar';

const renderSnackBar = (open: boolean, type: MessageType, closingDelay?: number) =>
const renderSnackBar = (open: boolean, type: AppResponseOutcome, closingDelay?: number) =>
render(
<SnackBar
open={open}
Expand All @@ -16,20 +16,20 @@ const renderSnackBar = (open: boolean, type: MessageType, closingDelay?: number)

describe('SnackBar Component', () => {
it('renders snack bar (closed)', () => {
const { queryByTestId } = renderSnackBar(false, MessageType.INFO);
const { queryByTestId } = renderSnackBar(false, AppResponseOutcome.INFO);
const snackBarContainer = queryByTestId('snackBarContainer');
expect(snackBarContainer).not.toBeInTheDocument();
});

it('renders snack bar (opened)', () => {
const { getByTestId } = renderSnackBar(true, MessageType.INFO);
const { getByTestId } = renderSnackBar(true, AppResponseOutcome.INFO);
const snackBarContainer = getByTestId('snackBarContainer');
expect(snackBarContainer).toBeInTheDocument();
expect(snackBarContainer).toHaveTextContent('SnackBar mocked message');
});

it('closes snack bar by clicking close button', async () => {
const { getByTestId } = renderSnackBar(true, MessageType.INFO);
const { getByTestId } = renderSnackBar(true, AppResponseOutcome.INFO);
const snackBarContainer = getByTestId('snackBarContainer');
expect(snackBarContainer).toBeInTheDocument();
const closeButton = within(snackBarContainer!).getByRole('button');
Expand All @@ -39,22 +39,14 @@ describe('SnackBar Component', () => {
expect(snackBarContainer).not.toBeInTheDocument();
});

// TO-FIX
// This test fails, probably due of the combination of useFakeTimers with a waitFor block.
// I skip it to go forward with the migration jest -> vitest.
// To analyze jointly with the skipped tests in src/components/NotificationDetail/__test__/NotificationPaymentF24Item.test.tsx
// and src/hooks/__test__/useProcess.test.tsx
// ---------------------------------
// Carlos Lombardi, 2023-11-10
// ---------------------------------
it.skip('closes snack bar after delay', async () => {
it('closes snack bar after delay', async () => {
vi.useFakeTimers();
const { getByTestId } = renderSnackBar(true, MessageType.INFO, 400);
const { getByTestId } = renderSnackBar(true, AppResponseOutcome.INFO, 400);
const snackBarContainer = getByTestId('snackBarContainer');
expect(snackBarContainer).toBeInTheDocument();
// wait...
vi.advanceTimersByTime(500);
await waitFor(() => {
await vi.waitFor(() => {
expect(snackBarContainer).not.toBeInTheDocument();
});
vi.useRealTimers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ interface TimedMessageProps {
/** Message to show */
children?: React.ReactNode;
}

/**
* Show timed message
* @deprecated since PN-8718
*/
const TimedMessage: React.FC<TimedMessageProps> = ({ timeout = 0, callback, children }) => {
const [showMessage, setShowMessage] = useState(false);

Expand Down
Loading

0 comments on commit d28a5ea

Please sign in to comment.