Skip to content

Commit

Permalink
chore: [IOPID-991] Integration of email validation logic in the onboa…
Browse files Browse the repository at this point in the history
…rding flow and profile preferences flow (#5206)

## Short description
In this PR, I integrated business logic that allows the validation of
the email within both the onboarding and profile editing screens.

## List of changes proposed in this pull request
- business logic on the modify email in preferences
`NewEmailInsertScreen.tsx`
- added business logic on `NewOnboardingEmailInsertScreen.tsx`
- integration of logic described in solution 2 of this
[RFC](https://pagopa.atlassian.net/wiki/spaces/IAEI/pages/792166441/RFC+-+2013+Gestione+Errore+GET+e+POST+della+chiamata+API+profile+nell+UI+dell+app+IO)
`ProfileErrorType.ts`
- integration of the new openapi [in this PR
](pagopa/io-backend#1068)
- fix accessibilityLabel on `NewOptInScreen.tsx `

## Onboarding Flow


https://github.com/pagopa/io-app/assets/83651704/4bfeab28-b01e-4ffb-af23-dd861f9f26e8

## How to test
1. in [this
line](https://github.com/pagopa/io-app/blob/8d955e2a92223c0dd1baee255df383ee84ca1545/.env.local#L101)
change the value to YES
2. make sure [this
branch](pagopa/io-dev-api-server#317) and[ this
branch](pagopa/io-dev-api-server#321) are merged
into master in
[io-dev-api-server](https://github.com/pagopa/io-dev-api-server)
3. in io-dev-api-server [in this
line](https://github.com/pagopa/io-dev-api-server/blob/284edc21086fe0cfae39462958c8e8114d762f04/src/config.ts#L67C4-L67C28)
set `firstOnboarding: true`
4. in io-dev-api-server [at this
line](https://github.com/pagopa/io-dev-api-server/blob/284edc21086fe0cfae39462958c8e8114d762f04/src/payloads/profile.ts#L49)
and [at this
line](https://github.com/pagopa/io-dev-api-server/blob/284edc21086fe0cfae39462958c8e8114d762f04/src/payloads/profile.ts#L74)
set `is_email_validated: true`.
5. in io-dev-api-server, in the same file as the last point, set
`is_email_already_taken: true` if you need to display the alert on the
screen NewEmailInsertScreen.
6. run the application on io-dev-api-server 
7. To check for error 412 you can enter the e-mail
`mario.error@prova.com`.
8. when you get to the [verification
screen](https://www.figma.com/file/oLJMcWd0SbRHDtj7WRvu7N/Univocit%C3%A0-indirizzi-email?type=design&node-id=7-10909&mode=design&t=f1xmwaHUSRRROj50-0),
navigate to the browser at: http://localhost:3000/ and in the "email
configuration" section press the "validate email" button
9. continue the flow.

## Change preferences flow


https://github.com/pagopa/io-app/assets/83651704/e7cbaede-9fa6-4e2b-87de-5e7d3a8edd59

## How to test
Once logged in, go to your profile and select 'your data'. From here you
can edit your email. The flow is almost the same as explained above
(from point 7)

---------

Co-authored-by: Alice Azzolini <93777761+AliceAzzolini@users.noreply.github.com>
Co-authored-by: Fabio Bombardi <16268789+shadowsheep1@users.noreply.github.com>
Co-authored-by: Sabino <114305019+sabontech@users.noreply.github.com>
Co-authored-by: Cristiano Tofani <cri.tofani@gmail.com>
Co-authored-by: Andrea Piai <andrea.piai@pagopa.it>
Co-authored-by: Federico Mastrini <federicomastrini93@gmail.com>
Co-authored-by: Alessandro Izzo <34343582+Hantex9@users.noreply.github.com>
  • Loading branch information
8 people authored Nov 28, 2023
1 parent ef78c16 commit 1aeee14
Show file tree
Hide file tree
Showing 17 changed files with 500 additions and 148 deletions.
3 changes: 3 additions & 0 deletions locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,9 @@ email:
help:
title: Email
content: !include email_insert_help.md
alertTitle: This email address is already in use
alertDescription: This may happen if you share the same email address with a family member
alertButton: Use another email address
newinsert:
header: "Configure IO"
title: "What is your email address?"
Expand Down
3 changes: 3 additions & 0 deletions locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,9 @@ email:
help:
title: Email
content: !include email_insert_help.md
alertTitle: Questa email è già in uso
alertDescription: Può succedere se condividi lo stesso indirizzo con un familiare
alertButton: Usa un’altra email
newinsert:
header: Configura IO
title: Qual è la tua email?
Expand Down
24 changes: 12 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
{
"name": "italia-app",
"version": "2.47.0-rc.0",
"io_backend_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/api_backend.yaml",
"io_public_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/api_public.yaml",
"io_backend_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/api_backend.yaml",
"io_public_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/api_public.yaml",
"io_content_specs": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.28/definitions.yml",
"io_bonus_vacanze_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/api_bonus.yaml",
"io_cgn_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/api_cgn.yaml",
"io_cgn_merchants_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/api_cgn_operator_search.yaml",
"io_bonus_vacanze_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/api_bonus.yaml",
"io_cgn_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/api_cgn.yaml",
"io_cgn_merchants_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/api_cgn_operator_search.yaml",
"io_bpd_citizen": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.28/bonus/specs/bpd/citizen.json",
"io_bpd_citizen_v2": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.28/bonus/specs/bpd/citizen_v2.json",
"io_bpd_payment": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.28/bonus/specs/bpd/payment.json",
"io_bpd_award_periods": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.28/bonus/specs/bpd/award.json",
"io_bpd_winning_transactions": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.28/bonus/specs/bpd/winning_transactions.json",
"io_bpd_winning_transactions_v2": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.28/bonus/specs/bpd/winning_transactions_v2.json",
"api_fci": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/api_io_sign.yaml",
"io_eu_covid_cert": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/api_eucovidcert.yaml",
"io_sicilia_vola_token": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/api_mit_voucher.yaml",
"io_pn_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/api_pn.yaml",
"io_consumed_pn_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/openapi/consumed/api-piattaforma-notifiche.yaml",
"api_fci": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/api_io_sign.yaml",
"io_eu_covid_cert": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/api_eucovidcert.yaml",
"io_sicilia_vola_token": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/api_mit_voucher.yaml",
"io_pn_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/api_pn.yaml",
"io_consumed_pn_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/openapi/consumed/api-piattaforma-notifiche.yaml",
"api_sicilia_vola": "assets/SiciliaVola.yml",
"api_cdc": "assets/CdcSwagger.yml",
"pagopa_api": "assets/paymentManager/spec.json",
"pagopa_api_walletv2": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.28/bonus/specs/bpd/pm/walletv2.json",
"pagopa_cobadge_configuration": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.28/pagopa/cobadge/abi_definitions.yml",
"pagopa_privative_configuration": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.28/pagopa/privative/definitions.yml",
"idpay_api": "https://raw.githubusercontent.com/pagopa/cstar-infrastructure/v5.8.0/src/domains/idpay-app/api/idpay_appio_full/openapi.appio.full.yml",
"lollipop_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/api_lollipop_first_consumer.yaml",
"fast_login_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.20.0-RELEASE/openapi/generated/api_fast_login.yaml",
"lollipop_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/api_lollipop_first_consumer.yaml",
"fast_login_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.22.0-RELEASE/openapi/generated/api_fast_login.yaml",
"pagopa_api_walletv3": "https://raw.githubusercontent.com/pagopa/pagopa-infra/5bd3f60aff52d2653111aa47a3975997295ae210/src/domains/wallet-app/api/payment-wallet/v1/_openapi.json.tpl",
"private": true,
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions ts/__mocks__/initializedProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const mockedProfile: InitializedProfile = {
is_email_validated: true,
is_inbox_enabled: true,
is_webhook_enabled: true,
is_email_already_taken: false,
name: "John",
spid_email: "test@example.com" as EmailString,
version: 1 as Version
Expand Down
37 changes: 24 additions & 13 deletions ts/components/NewRemindEmailValidationOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import I18n from "../i18n";

import {
acknowledgeOnEmailValidation,
profileLoadRequest,
startEmailValidation
} from "../store/actions/profile";
Expand All @@ -28,6 +29,7 @@ import {
} from "../store/reducers/profile";
import { useIODispatch, useIOSelector } from "../store/hooks";
import { emailValidationSelector } from "../store/reducers/emailValidation";
import { emailAcknowledged } from "../store/actions/onboarding";
import NavigationService from "../navigation/NavigationService";
import ROUTES from "../navigation/routes";
import { IOStyles } from "./core/variables/IOStyles";
Expand Down Expand Up @@ -70,11 +72,19 @@ const NewRemindEmailValidationOverlay = (props: Props) => {
() => dispatch(startEmailValidation.request()),
[dispatch]
);

const acknowledgeEmail = useCallback(
() => dispatch(emailAcknowledged()),
[dispatch]
);
const reloadProfile = useCallback(
() => dispatch(profileLoadRequest()),
[dispatch]
);
const dispatchAcknowledgeOnEmailValidation = useCallback(
(maybeAcknowledged: O.Option<boolean>) =>
dispatch(acknowledgeOnEmailValidation(maybeAcknowledged)),
[dispatch]
);

// function to localize the title of the button. If the email is validated and if it is not, whether the confirmation email was sent or not
const buttonTitle = () => {
Expand All @@ -100,7 +110,17 @@ const NewRemindEmailValidationOverlay = (props: Props) => {

const handleSendEmailValidationButton = () => {
if (isEmailValidated) {
hideModal();
if (isOnboarding) {
// if the user is in the onboarding flow and the email il correctly validated,
// the email validation flow is finished
acknowledgeEmail();
hideModal();
} else {
hideModal();
NavigationService.navigate(ROUTES.PROFILE_NAVIGATOR, {
screen: ROUTES.PROFILE_DATA
});
}
} else {
// send email validation only if it exists
pipe(
Expand All @@ -113,17 +133,8 @@ const NewRemindEmailValidationOverlay = (props: Props) => {
};

const navigateToInsertEmail = () => {
if (isOnboarding) {
hideModal();
NavigationService.navigate(ROUTES.ONBOARDING, {
screen: ROUTES.ONBOARDING_INSERT_EMAIL_SCREEN
});
} else {
hideModal();
NavigationService.navigate(ROUTES.PROFILE_NAVIGATOR, {
screen: ROUTES.INSERT_EMAIL_SCREEN
});
}
dispatchAcknowledgeOnEmailValidation(O.none);
hideModal();
};

const renderFooter = () => (
Expand Down
1 change: 1 addition & 0 deletions ts/components/messages/__tests__/PaymentButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const testPaymentButton = (
is_email_enabled: true,
is_webhook_enabled: true,
is_email_validated: true,
is_email_already_taken: false,
family_name: "Red",
fiscal_code: "FiscalCode" as FiscalCode,
has_profile: true,
Expand Down
13 changes: 2 additions & 11 deletions ts/hooks/useValidateEmailModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import { LightModalContext } from "../components/ui/LightModal";
import { useIOSelector } from "../store/hooks";
import { emailValidationSelector } from "../store/reducers/emailValidation";
import { isProfileEmailValidatedSelector } from "../store/reducers/profile";
import NewRemindEmailValidationOverlay from "../components/NewRemindEmailValidationOverlay";
import { isNewCduFlow } from "../config";

export const useValidatedEmailModal = (isOnboarding?: boolean) => {
const { showModal, hideModal } = useContext(LightModalContext);
Expand All @@ -32,17 +30,10 @@ export const useValidatedEmailModal = (isOnboarding?: boolean) => {

useFocusEffect(
React.useCallback(() => {
// AS-IS FLOW
if (!isNewCduFlow && !isEmailValidated) {
if (!isEmailValidated) {
showModal(<RemindEmailValidationOverlay isOnboarding={isOnboarding} />);
return () => hideModal();
// CDU FLOW
} else if (isNewCduFlow && !isEmailValidated) {
showModal(
<NewRemindEmailValidationOverlay isOnboarding={isOnboarding} />
);
}
return () => void 0;
return () => hideModal();
}, [hideModal, isEmailValidated, isOnboarding, showModal])
);
};
8 changes: 7 additions & 1 deletion ts/navigation/OnboardingNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import ServicePreferenceCompleteScreen from "../screens/onboarding/ServicePrefer
import { isGestureEnabled } from "../utils/navigation";
import MissingDevicePinScreen from "../screens/onboarding/biometric&securityChecks/MissingDevicePinScreen";
import MissingDeviceBiometricScreen from "../screens/onboarding/biometric&securityChecks/MissingDeviceBiometricScreen";
import NewOnboardingEmailInsertScreen from "../screens/onboarding/NewOnboardingEmailInsertScreen";
import { isNewCduFlow } from "../config";
import { OnboardingParamsList } from "./params/OnboardingParamsList";
import ROUTES from "./routes";

Expand Down Expand Up @@ -65,7 +67,11 @@ const navigator = () => (
/>
<Stack.Screen
name={ROUTES.ONBOARDING_READ_EMAIL_SCREEN}
component={OnboardingEmailReadScreen}
component={
isNewCduFlow
? NewOnboardingEmailInsertScreen
: OnboardingEmailReadScreen
}
/>
<Stack.Screen
name={ROUTES.ONBOARDING_COMPLETED}
Expand Down
5 changes: 3 additions & 2 deletions ts/navigation/ProfileNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createStackNavigator } from "@react-navigation/stack";
import * as React from "react";
import { HeaderSecondLevel } from "@pagopa/io-app-design-system";
import LogoutScreen from "../components/screens/LogoutScreen";
import { remindersOptInEnabled } from "../config";
import { isNewCduFlow, remindersOptInEnabled } from "../config";
import { DesignSystemNavigator } from "../features/design-system/navigation/navigator";
import LollipopPlayground from "../features/lollipop/playgrounds/LollipopPlayground";
import CalendarsPreferencesScreen from "../screens/profile/CalendarsPreferencesScreen";
Expand Down Expand Up @@ -34,6 +34,7 @@ import { ContextualHelpPropsMarkdown } from "../components/screens/BaseScreenCom
import I18n from "../i18n";
import { IdPayCodePlayGround } from "../screens/profile/playgrounds/IdPayCodePlayground";
import { useStartSupportRequest } from "../hooks/useStartSupportRequest";
import NewEmailInsertScreen from "../screens/profile/NewEmailInsertScreen";
import { ProfileParamsList } from "./params/ProfileParamsList";
import ROUTES from "./routes";

Expand Down Expand Up @@ -162,7 +163,7 @@ const ProfileStackNavigator = () => {
headerShown: false
}}
name={ROUTES.INSERT_EMAIL_SCREEN}
component={EmailInsertScreen}
component={isNewCduFlow ? NewEmailInsertScreen : EmailInsertScreen}
/>
<Stack.Screen
options={{
Expand Down
21 changes: 20 additions & 1 deletion ts/sagas/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ import {
} from "../utils/locale";
import { readablePrivacyReport } from "../utils/reporters";
import { withRefreshApiCall } from "../features/fastLogin/saga/utils";
import { ProfileError } from "../store/reducers/profileErrorType";
import { UpdateProfile412ErrorTypesEnum } from "../../definitions/backend/UpdateProfile412ErrorTypes";

// A saga to load the Profile.
export function* loadProfile(
Expand Down Expand Up @@ -135,6 +137,7 @@ function* createOrUpdateProfileSaga(
is_inbox_enabled: currentProfile.is_inbox_enabled,
is_webhook_enabled: currentProfile.is_webhook_enabled,
is_email_validated: currentProfile.is_email_validated || false,
is_email_already_taken: !!currentProfile.is_email_already_taken,
is_email_enabled: currentProfile.is_email_enabled,
version: currentProfile.version,
email: currentProfile.email,
Expand All @@ -157,6 +160,7 @@ function* createOrUpdateProfileSaga(
is_email_validated: action.payload.is_email_validated || false,
is_email_enabled: action.payload.is_email_enabled || false,
last_app_version: currentProfile.last_app_version ?? appVersion,
is_email_already_taken: !!currentProfile.is_email_already_taken,
...action.payload,
accepted_tos_version: tosVersion,
version: 0
Expand All @@ -180,7 +184,22 @@ function* createOrUpdateProfileSaga(
// app has a different version of profile compared to that one owned by the backend
// so we force profile reloading (see https://www.pivotaltracker.com/n/projects/2048617/stories/171994417)
yield* put(profileLoadRequest());
throw new Error(response.right.value.title);
throw new ProfileError(
response.right.value.title,
"PROFILE_EMAIL_VALIDATION_ERROR"
);
}
if (
response.right.status === 412 &&
response.right.value.type ===
UpdateProfile412ErrorTypesEnum[
"https://ioapp.it/problems/email-already-taken"
]
) {
throw new ProfileError(
response.right.value.title,
"PROFILE_EMAIL_IS_NOT_UNIQUE_ERROR"
);
}

if (response.right.status !== 200) {
Expand Down
4 changes: 2 additions & 2 deletions ts/screens/authentication/NewOptInScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ const NewOptInScreen = (props: Props) => {
testID="container-test"
primaryActionProps={{
label: I18n.t("authentication.opt-in.button-accept-lv"),
accessibilityLabel: "Click to continue with fast access",
accessibilityLabel: I18n.t("authentication.opt-in.button-accept-lv"),
onPress: () => navigateToIdpPage(true),
testID: "accept-button-test"
}}
secondaryActionProps={{
label: I18n.t("authentication.opt-in.button-decline-lv"),
accessibilityLabel: "Click to continue with classic access",
accessibilityLabel: I18n.t("authentication.opt-in.button-decline-lv"),
onPress: () => navigateToIdpPage(false),
testID: "decline-button-test"
}}
Expand Down
Loading

0 comments on commit 1aeee14

Please sign in to comment.