Skip to content

Commit

Permalink
chore: align default tosVersion to the remote one (#5978)
Browse files Browse the repository at this point in the history
## Short Description
This PR aligns the ToS version number with the [remote
version](https://github.com/pagopa/io-services-metadata/blob/a5ece439327bbcbd03029c9f28f70ab3a17a1687/status/backend.json#L118).
It also updates the app to use the remote `privacyURL` across all
necessary screens and adds a lint rule to prevent using the default
fallback value from `config.ts`.

## List of Changes Proposed in This Pull Request
- Aligned the ToS version number to match the remote version.
- Updated the app to use `privacyURL` from the `backend.json` status
(remote) where needed.
- Added a lint rule to avoid using the `privacyURL` link from
`config.ts`.

## How to Test
Run the app and verify the following:
- The login flow works correctly.
- The ToS screen in the profile section displays the correct remote ToS
URL.
- The ToS screen during the first onboarding shows the correct remote
ToS URL.

---------

Co-authored-by: Alice Di Rico <[email protected]>
  • Loading branch information
shadowsheep1 and Ladirico authored Jul 22, 2024
1 parent 5a809df commit f8b31c3
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 54 deletions.
9 changes: 8 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,14 @@ module.exports = {
importNames: ["pot"],
message: 'Importing { pot } from "@pagopa/ts-commons" is not allowed. Use \'import * as pot from "@pagopa/ts-commons/lib/pot"\' instead.',
}
],
],
patterns: [
{
group: ["**/config"],
importNames: ["privacyUrl"],
message: 'Importing "privacyUrl" from "config.ts" module is restricted. Please use "tosConfigSelector" to obtain it instead.'
}
]
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ import { ThirdPartyMessageWithContent } from "../../../../../definitions/backend
import { thirdPartyFromIdSelector } from "../../store/reducers/thirdPartyById";
import { TagEnum } from "../../../../../definitions/backend/MessageCategoryPN";
import { isPnEnabledSelector } from "../../../../store/reducers/backendStatus";
import * as config from "../../../../config";
import { isLoadingOrUpdatingInbox } from "../../store/reducers/allPaginated";
import { ThirdPartyMessage } from "../../../../../definitions/backend/ThirdPartyMessage";
import { ThirdPartyAttachment } from "../../../../../definitions/backend/ThirdPartyAttachment";

// eslint-disable-next-line functional/immutable-data
Object.defineProperty(config, "euCovidCertificateEnabled", { value: true });
jest.mock("../../../../config.ts", () => ({
...jest.requireActual("../../../../config.ts"),
euCovidCertificateEnabled: true
}));

describe("getPaginatedMessage", () => {
it("when no paginated message is in store, it should dispatch a loadMessageById.request and retrieve its result from the store if it succeeds", () => {
Expand Down
3 changes: 2 additions & 1 deletion ts/features/tos/store/selectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { createSelector } from "reselect";
import { pipe } from "fp-ts/lib/function";
import * as O from "fp-ts/lib/Option";
import { TosConfig } from "../../../../../definitions/content/TosConfig";
// eslint-disable-next-line no-restricted-imports
import { privacyUrl } from "../../../../config";
import { backendStatusSelector } from "../../../../store/reducers/backendStatus";

const DEFAULT_TOS_CONFIG: TosConfig = {
tos_url: privacyUrl,
tos_version: 4.8
tos_version: 4.9
};

export const tosConfigSelector = createSelector(
Expand Down
7 changes: 4 additions & 3 deletions ts/features/wallet/onboarding/paypal/screen/__mocks__/psp.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { NonNegativeNumber } from "@pagopa/ts-commons/lib/numbers";
import { IOPayPalPsp } from "../../types";
import { privacyUrl } from "../../../../../../config";

const mockPrivacyUrl = "https://io.italia.it/app-content/tos_privacy.html";

export const pspList: ReadonlyArray<IOPayPalPsp> = [
{
id: "1",
logoUrl: "https://paytipper.com/wp-content/uploads/2021/02/logo.png",
name: "PayTipper",
fee: 100 as NonNegativeNumber,
privacyUrl
privacyUrl: mockPrivacyUrl
},
{
id: "2",
logoUrl: "https://www.dropbox.com/s/smk5cyxx1qevn6a/mat_bank.png?dl=1",
name: "Mat Bank",
fee: 50 as NonNegativeNumber,
privacyUrl
privacyUrl: mockPrivacyUrl
}
];
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { NonNegativeNumber } from "@pagopa/ts-commons/lib/numbers";
import { render } from "@testing-library/react-native";
import React from "react";
import { PspRadioItem } from "../../components/PspRadioItem";
import { privacyUrl } from "../../../../../../config";
import { IOPayPalPsp } from "../../types";

jest.mock("react-native-safe-area-context", () => ({
Expand All @@ -11,12 +10,14 @@ jest.mock("react-native-safe-area-context", () => ({
.mockReturnValue({ top: 20, left: 0, right: 0, bottom: 0 })
}));

const mockPrivacyUrl = "https://io.italia.it/app-content/tos_privacy.html";

const payPalPsp: IOPayPalPsp = {
id: "1",
logoUrl: "https://paytipper.com/wp-content/uploads/2021/02/logo.png",
name: "PayTipper",
fee: 100 as NonNegativeNumber,
privacyUrl
privacyUrl: mockPrivacyUrl
};

describe("PspRadioItem", () => {
Expand Down
7 changes: 5 additions & 2 deletions ts/screens/authentication/LandingScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import LoadingSpinnerOverlay from "../../components/LoadingSpinnerOverlay";
import SectionStatusComponent from "../../components/SectionStatus";
import { IOStyles } from "../../components/core/variables/IOStyles";
import { ContextualHelpPropsMarkdown } from "../../components/screens/BaseScreenComponent";
import { privacyUrl } from "../../config";
import { isCieLoginUatEnabledSelector } from "../../features/cieLogin/store/selectors";
import { cieFlowForDevServerEnabled } from "../../features/cieLogin/utils";
import {
Expand All @@ -45,6 +44,7 @@ import { useOnFirstRender } from "../../utils/hooks/useOnFirstRender";
import { openWebUrl } from "../../utils/url";
import { useHeaderSecondLevel } from "../../hooks/useHeaderSecondLevel";
import { setAccessibilityFocus } from "../../utils/accessibility";
import { tosConfigSelector } from "../../features/tos/store/selectors";
import {
trackCieLoginSelected,
trackMethodInfo,
Expand All @@ -71,6 +71,9 @@ export const LandingScreen = () => {
const accessibilityFirstFocuseViewRef = React.useRef<View>(null);
const insets = useSafeAreaInsets();

const tosConfig = useIOSelector(tosConfigSelector);
const privacyUrl = tosConfig.tos_url;

const [isRootedOrJailbroken, setIsRootedOrJailbroken] = React.useState<
O.Option<boolean>
>(O.none);
Expand Down Expand Up @@ -185,7 +188,7 @@ export const LandingScreen = () => {
const navigateToPrivacyUrl = React.useCallback(() => {
trackMethodInfo();
openWebUrl(privacyUrl);
}, []);
}, [privacyUrl]);

const navigateToCieUatSelectionScreen = React.useCallback(() => {
if (isCieSupported()) {
Expand Down
14 changes: 0 additions & 14 deletions ts/screens/onboarding/__tests__/OnboardingTosScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import I18n from "../../../i18n";
// WebViewErrorEvent,
// WebViewNavigationEvent
// } from "react-native-webview/lib/WebViewTypes";
import * as config from "../../../config";
import { appReducer } from "../../../store/reducers";
import { applicationChangeState } from "../../../store/actions/application";
import { GlobalState } from "../../../store/reducers/types";
Expand All @@ -20,29 +19,16 @@ import { renderScreenWithNavigationStoreContext } from "../../../utils/testWrapp
import OnboardingTosScreen from "../OnboardingTosScreen";
import { ServicesPreferencesModeEnum } from "../../../../definitions/backend/ServicesPreferencesMode";

const CurrentTestZendeskEnabled = true;
const CurrentTestToSVersion = 2.0;

const zendeskEnabledDefaultValue = config.zendeskEnabled;

// Restore defineProperty
beforeAll(() => {
jest.resetAllMocks();
jest.mock("./../../../config");
// This can be replaced by jest.replaceProperty if we update jest to 29.4+
// eslint-disable-next-line functional/immutable-data
Object.defineProperty(config, "zendeskEnabled", {
value: CurrentTestZendeskEnabled
});
});

afterAll(() => {
jest.resetAllMocks();
// This can be removed if we update jest to 29.4+ and switch to jest.replaceProperty
// eslint-disable-next-line functional/immutable-data
Object.defineProperty(config, "zendeskEnabled", {
value: zendeskEnabledDefaultValue
});
});

describe("TosScreen", () => {
Expand Down
6 changes: 5 additions & 1 deletion ts/screens/profile/TosScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import { View } from "react-native";
import LoadingSpinnerOverlay from "../../components/LoadingSpinnerOverlay";
import { ContextualHelpPropsMarkdown } from "../../components/screens/BaseScreenComponent";
import TosWebviewComponent from "../../components/TosWebviewComponent";
import { privacyUrl } from "../../config";
import { useOnFirstRender } from "../../utils/hooks/useOnFirstRender";
import { getFlowType } from "../../utils/analytics";
import { useHeaderSecondLevel } from "../../hooks/useHeaderSecondLevel";
import I18n from "../../i18n";
import { useIOSelector } from "../../store/hooks";
import { tosConfigSelector } from "../../features/tos/store/selectors";
import { trackTosScreen } from "./analytics";

const contextualHelpMarkdown: ContextualHelpPropsMarkdown = {
Expand All @@ -26,6 +27,9 @@ const contextualHelpMarkdown: ContextualHelpPropsMarkdown = {
const TosScreen = () => {
const [isLoading, setIsLoading] = useState(true);

const tosConfig = useIOSelector(tosConfigSelector);
const privacyUrl = tosConfig.tos_url;

const flow = getFlowType(false, false);

useOnFirstRender(() => {
Expand Down
26 changes: 4 additions & 22 deletions ts/screens/profile/__test__/TosScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import I18n from "../../../i18n";
// WebViewErrorEvent,
// WebViewNavigationEvent
// } from "react-native-webview/lib/WebViewTypes";
import * as config from "../../../config";
import { appReducer } from "../../../store/reducers";
import { applicationChangeState } from "../../../store/actions/application";
import { GlobalState } from "../../../store/reducers/types";
Expand All @@ -18,29 +17,16 @@ import ROUTES from "../../../navigation/routes";
import { renderScreenWithNavigationStoreContext } from "../../../utils/testWrapper";
import TosScreen from "../TosScreen";

const CurrentTestZendeskEnabled = true;
const CurrentTestToSVersion = 2.0;

const zendeskEnabledDefaultValue = config.zendeskEnabled;

// Restore defineProperty
beforeAll(() => {
jest.resetAllMocks();
jest.mock("./../../../config");
// This can be replaced by jest.replaceProperty if we update jest to 29.4+
// eslint-disable-next-line functional/immutable-data
Object.defineProperty(config, "zendeskEnabled", {
value: CurrentTestZendeskEnabled
});
});

afterAll(() => {
jest.resetAllMocks();
// This can be removed if we update jest to 29.4+ and switch to jest.replaceProperty
// eslint-disable-next-line functional/immutable-data
Object.defineProperty(config, "zendeskEnabled", {
value: zendeskEnabledDefaultValue
});
});

describe("TosScreen", () => {
Expand All @@ -64,14 +50,10 @@ describe("TosScreen", () => {
expect(helpButtonRTI).toBeDefined();
});
});
describe("When rendering the screen", () => {
it("The title should have a specific text", () => {
const renderAPI = commonSetup();
const textRTI = renderAPI.queryByText(
I18n.t("profile.main.privacy.title")
);
expect(textRTI).toBeDefined();
});
it("The title should have a specific text", () => {
const renderAPI = commonSetup();
const textRTI = renderAPI.queryByText(I18n.t("profile.main.privacy.title"));
expect(textRTI).toBeDefined();
});
describe("When rendering the screen initially", () => {
it("There should be the loading spinner overlay without the cancel button", async () => {
Expand Down
6 changes: 5 additions & 1 deletion ts/screens/profile/components/ShareDataComponent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { VSpacer } from "@pagopa/io-app-design-system";
import React, { memo } from "react";
import { Body } from "../../../../components/core/typography/Body";
import { Link } from "../../../../components/core/typography/Link";
import { privacyUrl } from "../../../../config";
import I18n from "../../../../i18n";
import { openWebUrl } from "../../../../utils/url";
import { TrackingInfo } from "../../analytics/mixpanel/mixpanelAnalytics";
import { useIOSelector } from "../../../../store/hooks";
import { tosConfigSelector } from "../../../../features/tos/store/selectors";
import {
AnalyticsFeatureInfo,
FeatureProps,
Expand All @@ -14,6 +15,9 @@ import {
} from "./ShareDataFeatureInfos";

export const ShareDataComponent = memo(({ trackAction }: FeatureProps) => {
const tosConfig = useIOSelector(tosConfigSelector);
const privacyUrl = tosConfig.tos_url;

const handleOnPress = () => {
trackAction(TrackingInfo.TOS);
openWebUrl(privacyUrl);
Expand Down
15 changes: 13 additions & 2 deletions ts/screens/profile/components/__test__/ShareDataComponent.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { fireEvent, render } from "@testing-library/react-native";
import { fireEvent } from "@testing-library/react-native";
import React from "react";
import { createStore } from "redux";
import { openWebUrl } from "../../../../utils/url";
import { ShareDataComponent } from "../ShareDataComponent";
import I18n from "../../../../i18n";
import { renderScreenWithNavigationStoreContext } from "../../../../utils/testWrapper";
import { GlobalState } from "../../../../store/reducers/types";
import { appReducer } from "../../../../store/reducers";
import { applicationChangeState } from "../../../../store/actions/application";

const mockPresentFn = jest.fn();
const mockTrackInfo = jest.fn();
Expand Down Expand Up @@ -76,5 +81,11 @@ describe("Test ShareDataComponent", () => {
});
});

const globalState = appReducer(undefined, applicationChangeState("active"));
const renderComponent = () =>
render(<ShareDataComponent trackAction={mockTrackInfo} />);
renderScreenWithNavigationStoreContext<GlobalState>(
() => <ShareDataComponent trackAction={mockTrackInfo} />,
"DUMMY",
{},
createStore(appReducer, globalState as any)
);
4 changes: 2 additions & 2 deletions ts/utils/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { WebViewNavigation } from "react-native-webview/lib/WebViewTypes";
import URLParse from "url-parse";
import * as O from "fp-ts/lib/Option";
import * as E from "fp-ts/lib/Either";
import * as config from "../config";
import { SessionToken } from "../types/SessionToken";
import { trackLoginSpidError } from "../screens/authentication/analytics/spidAnalytics";
import { apiUrlPrefix, spidRelayState } from "../config";
import { isStringNullyOrEmpty } from "./strings";
/**
* Helper functions for handling the SPID login flow through a webview.
Expand Down Expand Up @@ -76,7 +76,7 @@ export const extractLoginResult = (url: string): LoginResult | undefined => {

/** for a given idp id get the relative login uri */
export const getIdpLoginUri = (idpId: string, level: number) =>
`${config.apiUrlPrefix}/login?authLevel=SpidL${level}&entityID=${idpId}&RelayState=${config.spidRelayState}`;
`${apiUrlPrefix}/login?authLevel=SpidL${level}&entityID=${idpId}&RelayState=${spidRelayState}`;

/**
* Extract the login result from the given url.
Expand Down

0 comments on commit f8b31c3

Please sign in to comment.