Skip to content

Commit

Permalink
fix(IT Wallet): [SIW-699] Credential image disappearing from wallet (#…
Browse files Browse the repository at this point in the history
…5250)

## Short description
This PR resolves a bug which causes the disappearance of the credential
image between usage sessions. The issue is caused by the persistence of
mock display data, in particular by the `require` result for the asset
which is not constant between usage session. This inconsistency leads to
the disappearance of the credential image when restarting the app.

## List of changes proposed in this pull request
- Instead of including the required assets in the display data which is
then persisted, use the credential type to get the assets at runtime
with the `getImageFromCredentialType` helper function.
Note that the `CredentialType` enum serves the purpose of avoiding the
use of arbitrary strings to represent the credential type. Despite this,
the credential type is still represented as a string to align with the
library's typing requirements and due to the fact that it remains mocked
and subject to potential changes.
Therefore, although it is not strictly type checked at the moment, it is
used in place of string constants in the mock declaration but not in the
underlying Redux state.

## How to test
Obtain a PID and a credential. Check if the background image is properly
shown in the preview, home and details screen. Then restart the app
(kill it from the background apps list) and test it again.

---------

Co-authored-by: Mario Perrotta <mario.perrotta@pagopa.it>
  • Loading branch information
LazyAfternoons and hevelius committed Nov 24, 2023
1 parent 0fe3716 commit 0488086
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 18 deletions.
11 changes: 8 additions & 3 deletions ts/features/it-wallet/components/ItwClaimsWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import React from "react";
import { ImageBackground, StyleSheet, View } from "react-native";
import { H6, IOColors } from "@pagopa/io-app-design-system";
import { CredentialCatalogDisplay } from "../utils/mocks";
import {
CredentialCatalogDisplay,
getImageFromCredentialType
} from "../utils/mocks";

/**
* Props of the component.
* @param displayData - the display data of the credential.
* @param children - the children of the component.
* @param type - the credential type.
*/
type Props = {
displayData: CredentialCatalogDisplay;
children: React.ReactNode;
type: string;
};

/**
Expand All @@ -21,11 +26,11 @@ const BORDER_RADIUS = 16;
/**
* Renders a wrapper for the claims of a credential which shows an header with background image and title.
*/
const ItwClaimsWrapper = ({ displayData, children }: Props) => (
const ItwClaimsWrapper = ({ displayData, children, type }: Props) => (
<>
<View style={styles.body}>
<ImageBackground
source={displayData.image}
source={getImageFromCredentialType(type)}
style={styles.backgroundImage}
>
<View style={styles.header}>
Expand Down
11 changes: 9 additions & 2 deletions ts/features/it-wallet/components/ItwCredentialCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ import { View, Dimensions, Image, StyleSheet } from "react-native";
import { Body, H6, IOColors, Label } from "@pagopa/io-app-design-system";
import { PidWithToken } from "@pagopa/io-react-native-wallet/lib/typescript/pid/sd-jwt";
import customVariables from "../../../theme/variables";
import { CredentialCatalogDisplay } from "../utils/mocks";
import {
CredentialCatalogDisplay,
getImageFromCredentialType
} from "../utils/mocks";

/**
* Common props for the component.
* @param display - the display configuration for the credential.
* @param type - the type of the credential.
*/
type CommonProps = {
display: CredentialCatalogDisplay;
type: string;
};

/**
Expand Down Expand Up @@ -89,7 +94,9 @@ const ItwCredentialCard = (props: CredentialCardProps) => {

const { firstLine, secondLine } = getLines();

const { image, textColor, title } = props.display;
const { textColor, title } = props.display;

const image = getImageFromCredentialType(props.type);

return (
<View>
Expand Down
5 changes: 4 additions & 1 deletion ts/features/it-wallet/screens/ItwHomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { itwCredentialsSelector } from "../store/reducers/itwCredentialsReducer"
import { itwDecodedPidValueSelector } from "../store/reducers/itwPidDecodeReducer";
import { useItwResetFlow } from "../hooks/useItwResetFlow";
import ItwCredentialCard from "../components/ItwCredentialCard";
import { getPidDisplayData } from "../utils/mocks";
import { CredentialType, getPidDisplayData } from "../utils/mocks";

const contextualHelpMarkdown: ContextualHelpPropsMarkdown = {
title: "wallet.contextualHelpTitle",
Expand Down Expand Up @@ -60,6 +60,7 @@ const ItwHomeScreen = () => {
I18n.t("features.itWallet.homeScreen.categories.bonus")
];
const pidDisplayData = getPidDisplayData();
const pidType = CredentialType.PID;

/**
* Condionally navigate to the credentials catalog screen if the experimental feature flag is true.
Expand Down Expand Up @@ -100,6 +101,7 @@ const ItwHomeScreen = () => {
<ItwCredentialCard
pidClaims={decodedPid.pid.claims}
display={pidDisplayData}
type={pidType}
/>
<VSpacer />
</Pressable>
Expand All @@ -122,6 +124,7 @@ const ItwHomeScreen = () => {
<ItwCredentialCard
parsedCredential={credential.parsedCredential}
display={credential.displayData}
type={credential.credentialType}
/>
<VSpacer />
</Pressable>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const ItwCredentialPreviewScreen = () => {
<ItwCredentialCard
parsedCredential={data.parsedCredential}
display={data.displayData}
type={data.credentialType}
/>
<VSpacer />
<ItwCredentialClaimsList data={data} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { useOnFirstRender } from "../../../../../../utils/hooks/useOnFirstRender
import { itwDecodePid } from "../../../../store/actions/itwCredentialsActions";
import { itwPidValueSelector } from "../../../../store/reducers/itwPidReducer";
import ItwCredentialCard from "../../../../components/ItwCredentialCard";
import { getPidDisplayData } from "../../../../utils/mocks";
import { CredentialType, getPidDisplayData } from "../../../../utils/mocks";

type ContentViewProps = {
decodedPid: PidWithToken;
Expand All @@ -48,6 +48,7 @@ const ItwPidPreviewScreen = () => {
const pid = useIOSelector(itwPidValueSelector);
const decodedPidPot = useIOSelector(ItwDecodedPidPotSelector);
const pidDisplayData = getPidDisplayData();
const pidType = CredentialType.PID;

/**
* Dispatches the action to decode the PID on first render.
Expand Down Expand Up @@ -83,6 +84,7 @@ const ItwPidPreviewScreen = () => {
<ItwCredentialCard
pidClaims={decodedPid.pid.claims}
display={pidDisplayData}
type={pidType}
/>
<VSpacer />
<FeatureInfo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ const ItwPrCredentialDetailsScreen = () => {
<SafeAreaView style={{ ...IOStyles.flex }}>
<ScrollView>
<View style={IOStyles.horizontalContentPadding}>
<ItwClaimsWrapper displayData={data.displayData}>
<ItwClaimsWrapper
displayData={data.displayData}
type={data.credentialType}
>
<ItwCredentialClaimsList data={data} />
</ItwClaimsWrapper>
<VSpacer size={spacerSize} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { itwDecodedPidValueSelector } from "../../store/reducers/itwPidDecodeRed
import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList";
import { ItwParamsList } from "../../navigation/ItwParamsList";
import ItwPidClaimsList from "../../components/ItwPidClaimsList";
import { getPidDisplayData } from "../../utils/mocks";
import { CredentialType, getPidDisplayData } from "../../utils/mocks";
import ItwClaimsWrapper from "../../components/ItwClaimsWrapper";
import { ITW_ROUTES } from "../../navigation/ItwRoutes";
import ItwKoView from "../../components/ItwKoView";
Expand Down Expand Up @@ -60,7 +60,10 @@ const ItwPrPidDetails = () => {
<SafeAreaView style={{ ...IOStyles.flex }}>
<ScrollView>
<View style={IOStyles.horizontalContentPadding}>
<ItwClaimsWrapper displayData={pidDisplayData}>
<ItwClaimsWrapper
displayData={pidDisplayData}
type={CredentialType.PID}
>
<ItwPidClaimsList
decodedPid={decodedPid}
claims={["givenName", "familyName", "taxIdCode"]}
Expand Down
37 changes: 29 additions & 8 deletions ts/features/it-wallet/utils/mocks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { PidData } from "@pagopa/io-react-native-cie-pid";
import { IOIcons } from "@pagopa/io-app-design-system";
import { ImageSourcePropType } from "react-native";
import { PidWithToken } from "@pagopa/io-react-native-wallet/lib/typescript/pid/sd-jwt";
import I18n from "../../../i18n";
import { BulletItem } from "../components/ItwBulletList";
Expand Down Expand Up @@ -37,9 +36,18 @@ export const mapAssuranceLevel = (level: AssuranceLevel | string) => {

export const CREDENTIAL_ISSUER = "eFarma";

/**
* Credential types mocks.
*/
export enum CredentialType {
HEALTH_CARD = "HealthCard",
EUROPEAN_DISABILITY_CARD = "EuropeanDisabilityCard",
DRIVING_LICENSE = "DrivingLicense",
PID = "PID"
}

export type CredentialCatalogDisplay = {
textColor: "black" | "white";
image: ImageSourcePropType;
title: string;
icon?: IOIcons;
firstLine?: Array<string>;
Expand Down Expand Up @@ -73,15 +81,14 @@ export type CredentialCatalogItem =
*/
export const getCredentialsCatalog = (): Array<CredentialCatalogItem> => [
{
type: "EuropeanDisabilityCard",
type: CredentialType.EUROPEAN_DISABILITY_CARD,
issuerUrl: "https://api.eudi-wallet-it-issuer.it/rp",
title: I18n.t(
"features.itWallet.verifiableCredentials.type.disabilityCard"
),
icon: "disabilityCard",
incoming: false,
textColor: "black",
image: require("../assets/img/credentials/cards/europeanDisabilityCardFront.png"),
firstLine: ["given_name", "family_name"],
secondLine: ["serial_number"],
order: [
Expand All @@ -98,7 +105,6 @@ export const getCredentialsCatalog = (): Array<CredentialCatalogItem> => [
title: I18n.t("features.itWallet.verifiableCredentials.type.healthCard"),
icon: "healthCard",
textColor: "black",
image: require("../assets/img/credentials/cards/healthInsuranceFront.png"),
firstLine: [],
secondLine: []
},
Expand All @@ -109,12 +115,27 @@ export const getCredentialsCatalog = (): Array<CredentialCatalogItem> => [
icon: "driverLicense",
incoming: true,
textColor: "black",
image: require("../assets/img/credentials/cards/drivingLicenseFront.png"),
firstLine: [],
secondLine: []
}
];

/**
* Returns the mocked background image for the credential.
* @param type - the credential type
* @returns the mocked background image.
*/
export const getImageFromCredentialType = (type: string) => {
switch (type) {
case CredentialType.EUROPEAN_DISABILITY_CARD:
return require("../assets/img/credentials/cards/europeanDisabilityCardFront.png");
case CredentialType.PID:
return require("../assets/img/credentials/cards/pidFront.png");
default:
return require("../assets/img/credentials/cards/default.png");
}
};

/**
* Hard coded display feature for PID
*/
Expand All @@ -123,8 +144,7 @@ export const getPidDisplayData = (): CredentialCatalogDisplay => ({
"features.itWallet.verifiableCredentials.type.digitalCredential"
),
icon: "archive",
textColor: "white",
image: require("../assets/img/credentials/cards/pidFront.png")
textColor: "white"
});

export const getRequestedClaims = (
Expand Down Expand Up @@ -208,5 +228,6 @@ export const rpPidMock: RpMock = {

/**
* Regex to validate the date format of a credential.
* This is mocked because the date format is not yet defined.
*/
export const dateFormatRegex = new RegExp(/^\d{4}-\d{2}-\d{2}$/);

0 comments on commit 0488086

Please sign in to comment.