diff --git a/ts/components/SectionStatus/__tests__/index.test.tsx b/ts/components/SectionStatus/__tests__/index.test.tsx index 56878897c45..bdf32f573ab 100644 --- a/ts/components/SectionStatus/__tests__/index.test.tsx +++ b/ts/components/SectionStatus/__tests__/index.test.tsx @@ -5,14 +5,13 @@ import configureMockStore from "redux-mock-store"; import { IOColors } from "@pagopa/io-app-design-system"; import * as pot from "@pagopa/ts-commons/lib/pot"; import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; -import { BackendStatus } from "../../../../definitions/content/BackendStatus"; import { Config } from "../../../../definitions/content/Config"; import { LevelEnum, SectionStatus } from "../../../../definitions/content/SectionStatus"; import I18n, { setLocale } from "../../../i18n"; -import { SectionStatusKey } from "../../../store/reducers/backendStatus"; +import { SectionStatusKey } from "../../../store/reducers/backendStatus/sectionStatus"; import { renderScreenWithNavigationStoreContext } from "../../../utils/testWrapper"; import { openWebUrl } from "../../../utils/url"; import SectionStatusComponent from "../index"; @@ -22,6 +21,7 @@ import { TrialSystemState } from "../../../features/trialSystem/store/reducers"; import { PersistedFeaturesState } from "../../../features/common/store/reducers"; import { ItwLifecycleState } from "../../../features/itwallet/lifecycle/store/reducers"; import { ItWalletState } from "../../../features/itwallet/common/store/reducers"; +import { GlobalState } from "../../../store/reducers/types"; jest.mock("../../../utils/url"); @@ -40,41 +40,38 @@ const sectionStatus: SectionStatus = { const mockSectionStatusState = ( sectionKey: SectionStatusKey, - sectionStatus: SectionStatus -) => ({ - backendStatus: { - status: O.some({ - sections: { [sectionKey]: sectionStatus }, - config: { - assistanceTool: { tool: ToolEnum.none }, - cgn: { enabled: true }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { enabled: true }, - itw: { - enabled: true, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } + status: SectionStatus +) => + ({ + sectionStatus: O.some({ [sectionKey]: status }), + remoteConfig: O.some({ + assistanceTool: { tool: ToolEnum.none }, + cgn: { enabled: true }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" } - } as Config - } as BackendStatus) - }, - features: { - itWallet: { - lifecycle: ItwLifecycleState.ITW_LIFECYCLE_INSTALLED - } as ItWalletState - } as PersistedFeaturesState, - trialSystem: { - [itwTrialId]: pot.some(SubscriptionStateEnum.UNSUBSCRIBED) - } as TrialSystemState -}); + }, + fims: { enabled: true }, + itw: { + enabled: true, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + } + } as Config), + features: { + itWallet: { + lifecycle: ItwLifecycleState.ITW_LIFECYCLE_INSTALLED + } as ItWalletState + } as PersistedFeaturesState, + trialSystem: { + [itwTrialId]: pot.some(SubscriptionStateEnum.UNSUBSCRIBED) + } as TrialSystemState + } as unknown as GlobalState); const mockStore = configureMockStore(); @@ -186,9 +183,8 @@ describe("Section Status Component should return null", () => { const component = getComponent( "messages", mockStore({ - backendStatus: { - status: O.none - }, + remoteConfig: O.none, + sectionStatus: O.none, trialSystem: { [itwTrialId]: pot.some(SubscriptionStateEnum.UNSUBSCRIBED) } as TrialSystemState, diff --git a/ts/components/SectionStatus/index.tsx b/ts/components/SectionStatus/index.tsx index b56e510a5b3..97f68ad87f0 100644 --- a/ts/components/SectionStatus/index.tsx +++ b/ts/components/SectionStatus/index.tsx @@ -9,7 +9,7 @@ import { messageForSectionSelector, SectionStatusKey, webUrlForSectionSelector -} from "../../store/reducers/backendStatus"; +} from "../../store/reducers/backendStatus/sectionStatus"; import { getFullLocale } from "../../utils/locale"; import { openWebUrl } from "../../utils/url"; import { useIOSelector } from "../../store/hooks"; diff --git a/ts/components/SectionStatus/modal/index.tsx b/ts/components/SectionStatus/modal/index.tsx index 720e6ec221a..f47db63ab9a 100644 --- a/ts/components/SectionStatus/modal/index.tsx +++ b/ts/components/SectionStatus/modal/index.tsx @@ -10,7 +10,7 @@ import { messageForSectionSelector, SectionStatusKey, webUrlForSectionSelector -} from "../../../store/reducers/backendStatus"; +} from "../../../store/reducers/backendStatus/sectionStatus"; import { getFullLocale } from "../../../utils/locale"; import { openWebUrl } from "../../../utils/url"; import { useIOSelector } from "../../../store/hooks"; diff --git a/ts/components/screens/BaseHeader.tsx b/ts/components/screens/BaseHeader.tsx index 5f85472eac5..413cb271953 100644 --- a/ts/components/screens/BaseHeader.tsx +++ b/ts/components/screens/BaseHeader.tsx @@ -24,7 +24,7 @@ import { useFocusEffect } from "@react-navigation/native"; import I18n from "../../i18n"; import { navigateBack } from "../../store/actions/navigation"; import { Dispatch } from "../../store/actions/types"; -import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus/remoteConfig"; import { isSearchEnabledSelector } from "../../store/reducers/search"; import { GlobalState } from "../../store/reducers/types"; import variables from "../../theme/variables"; diff --git a/ts/components/screens/BaseScreenComponent/__tests__/BaseScreenComponent.test.tsx b/ts/components/screens/BaseScreenComponent/__tests__/BaseScreenComponent.test.tsx index 86b20fc6fb4..6d945053252 100644 --- a/ts/components/screens/BaseScreenComponent/__tests__/BaseScreenComponent.test.tsx +++ b/ts/components/screens/BaseScreenComponent/__tests__/BaseScreenComponent.test.tsx @@ -4,17 +4,16 @@ import React from "react"; import { Store } from "redux"; import configureMockStore from "redux-mock-store"; import { ToolEnum } from "../../../../../definitions/content/AssistanceToolConfig"; -import { BackendStatus } from "../../../../../definitions/content/BackendStatus"; import { Config } from "../../../../../definitions/content/Config"; import * as zendeskActions from "../../../../features/zendesk/store/actions"; import { applicationChangeState } from "../../../../store/actions/application"; import { appReducer } from "../../../../store/reducers"; -import { BackendStatusState } from "../../../../store/reducers/backendStatus"; import { GlobalState } from "../../../../store/reducers/types"; import { renderScreenWithNavigationStoreContext } from "../../../../utils/testWrapper"; import BaseScreenComponent, { Props } from "../index"; import { MESSAGES_ROUTES } from "../../../../features/messages/navigation/routes"; +import { RemoteConfigState } from "../../../../store/reducers/backendStatus/remoteConfig"; jest.useFakeTimers(); @@ -28,13 +27,9 @@ describe("BaseScreenComponent", () => { const mockStore = configureMockStore(); const state = { ...globalState, - backendStatus: { - status: O.some({ - config: { - assistanceTool: { tool: ToolEnum.none } - } as Config - } as BackendStatus) - } as BackendStatusState + remoteConfig: O.some({ + assistanceTool: { tool: ToolEnum.none } + } as Config) as RemoteConfigState }; it.each` @@ -49,29 +44,25 @@ describe("BaseScreenComponent", () => { defaultProps, mockStore({ ...state, - backendStatus: { - status: O.some({ - config: { - assistanceTool: { tool }, - cgn: { enabled: true }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { enabled: true }, - itw: { - enabled: true, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - } - } as Config - } as BackendStatus) - } as BackendStatusState + remoteConfig: O.some({ + assistanceTool: { tool }, + cgn: { enabled: true }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + fims: { enabled: true }, + itw: { + enabled: true, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + } + } as Config) as RemoteConfigState }) ); expect(component.queryByTestId("helpButton")).toBeNull(); @@ -83,29 +74,25 @@ describe("BaseScreenComponent", () => { defaultProps, mockStore({ ...state, - backendStatus: { - status: O.some({ - config: { - assistanceTool: { tool: ToolEnum.zendesk }, - cgn: { enabled: true }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { enabled: true }, - itw: { - enabled: true, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - } - } as Config - } as BackendStatus) - } as BackendStatusState + remoteConfig: O.some({ + assistanceTool: { tool: ToolEnum.zendesk }, + cgn: { enabled: true }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + fims: { enabled: true }, + itw: { + enabled: true, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + } + } as Config) as RemoteConfigState }) ); const helpButton = component.queryByTestId("helpButton"); diff --git a/ts/components/screens/BaseScreenComponent/index.tsx b/ts/components/screens/BaseScreenComponent/index.tsx index 14df2f7f91c..cf16250ccd3 100644 --- a/ts/components/screens/BaseScreenComponent/index.tsx +++ b/ts/components/screens/BaseScreenComponent/index.tsx @@ -5,7 +5,7 @@ import { TranslationKeys } from "../../../../locales/locales"; import { zendeskSupportStart } from "../../../features/zendesk/store/actions"; import { useIODispatch, useIOSelector } from "../../../store/hooks"; import { canShowHelpSelector } from "../../../store/reducers/assistanceTools"; -import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { currentRouteSelector } from "../../../store/reducers/navigation"; import { FAQsCategoriesType } from "../../../utils/faq"; import { diff --git a/ts/components/wallet/PaymentMethodsList.tsx b/ts/components/wallet/PaymentMethodsList.tsx index 5e30ae1e75b..d9283cfc141 100644 --- a/ts/components/wallet/PaymentMethodsList.tsx +++ b/ts/components/wallet/PaymentMethodsList.tsx @@ -21,9 +21,9 @@ import { BackendStatus } from "../../../definitions/content/BackendStatus"; import { LevelEnum } from "../../../definitions/content/SectionStatus"; import I18n from "../../i18n"; import { - backendStatusSelector, - SectionStatusKey -} from "../../store/reducers/backendStatus"; + SectionStatusKey, + sectionStatusSelector +} from "../../store/reducers/backendStatus/sectionStatus"; import { GlobalState } from "../../store/reducers/types"; import { getFullLocale } from "../../utils/locale"; import { IOBadge, IOBadgeOutlineColors } from "../core/IOBadge"; @@ -78,11 +78,11 @@ export const showPaymentMethodIncomingAlert = () => * if it is critical status, it returns also an alert function, undefined otherwise * the alert display a title (section.badge) and a message (section.message) with default dismiss button * @param paymentMethod - * @param backendStatus + * @param sectionStatus */ const getBadgeStatus = ( paymentMethod: IPaymentMethod, - backendStatus: O.Option + sectionStatus: O.Option ): null | { badge: React.ReactNode; alert?: () => void } => { const itemSection = paymentMethod.section; @@ -97,8 +97,7 @@ const getBadgeStatus = ( return null; } return pipe( - backendStatus, - O.chainNullableK(bs => bs.sections), + sectionStatus, O.fold( () => null, sections => { @@ -134,11 +133,11 @@ const getBadgeStatus = ( const renderListItem = ( itemInfo: ListRenderItemInfo, - backendStatus: O.Option + sectionStatus: O.Option ) => { switch (itemInfo.item.status) { case "implemented": { - const badgeStatus = getBadgeStatus(itemInfo.item, backendStatus); + const badgeStatus = getBadgeStatus(itemInfo.item, sectionStatus); return ( = (props: Props) => ( ); const mapStateToProps = (state: GlobalState) => ({ - sectionStatus: backendStatusSelector(state) + sectionStatus: sectionStatusSelector(state) }); export default connect(mapStateToProps)( withLightModalContext(PaymentMethodsList) diff --git a/ts/features/barcode/components/BarcodeScanBaseScreenComponent.tsx b/ts/features/barcode/components/BarcodeScanBaseScreenComponent.tsx index 5deac6fd91a..005806e9156 100644 --- a/ts/features/barcode/components/BarcodeScanBaseScreenComponent.tsx +++ b/ts/features/barcode/components/BarcodeScanBaseScreenComponent.tsx @@ -31,7 +31,7 @@ import { } from "../../../navigation/params/AppParamsList"; import { useIODispatch, useIOSelector } from "../../../store/hooks"; import { canShowHelpSelector } from "../../../store/reducers/assistanceTools"; -import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { currentRouteSelector } from "../../../store/reducers/navigation"; import { FAQsCategoriesType } from "../../../utils/faq"; import { isAndroid } from "../../../utils/platform"; diff --git a/ts/features/barcode/screens/BarcodeScanScreen.tsx b/ts/features/barcode/screens/BarcodeScanScreen.tsx index b0c083f61f5..848572d1ba5 100644 --- a/ts/features/barcode/screens/BarcodeScanScreen.tsx +++ b/ts/features/barcode/screens/BarcodeScanScreen.tsx @@ -22,7 +22,7 @@ import { useIODispatch, useIOSelector } from "../../../store/hooks"; import { barcodesScannerConfigSelector, isIdPayEnabledSelector -} from "../../../store/reducers/backendStatus"; +} from "../../../store/reducers/backendStatus/remoteConfig"; import { emptyContextualHelp } from "../../../utils/emptyContextualHelp"; import { useIOBottomSheetAutoresizableModal } from "../../../utils/hooks/bottomSheet"; import { IdPayPaymentRoutes } from "../../idpay/payment/navigation/routes"; diff --git a/ts/features/bonus/cgn/screens/CgnDetailScreen.tsx b/ts/features/bonus/cgn/screens/CgnDetailScreen.tsx index 0c10b4f89f2..3c3eba0f722 100644 --- a/ts/features/bonus/cgn/screens/CgnDetailScreen.tsx +++ b/ts/features/bonus/cgn/screens/CgnDetailScreen.tsx @@ -32,7 +32,7 @@ import { useIOSelector } from "../../../../store/hooks"; import { cgnMerchantVersionSelector, isCGNEnabledSelector -} from "../../../../store/reducers/backendStatus"; +} from "../../../../store/reducers/backendStatus/remoteConfig"; import { profileSelector } from "../../../../store/reducers/profile"; import { GlobalState } from "../../../../store/reducers/types"; import { formatDateAsShortFormat } from "../../../../utils/dates"; diff --git a/ts/features/bonus/cgn/screens/activation/CgnCTAStartActivationScreen.tsx b/ts/features/bonus/cgn/screens/activation/CgnCTAStartActivationScreen.tsx index 77840436db2..532898094b9 100644 --- a/ts/features/bonus/cgn/screens/activation/CgnCTAStartActivationScreen.tsx +++ b/ts/features/bonus/cgn/screens/activation/CgnCTAStartActivationScreen.tsx @@ -5,7 +5,7 @@ import { Alert } from "react-native"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import I18n from "../../../../../i18n"; -import { isCGNEnabledSelector } from "../../../../../store/reducers/backendStatus"; +import { isCGNEnabledSelector } from "../../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../../store/reducers/types"; import { useActionOnFocus } from "../../../../../utils/hooks/useOnFocus"; import { ID_CGN_TYPE } from "../../../common/utils"; diff --git a/ts/features/bonus/common/screens/AvailableBonusScreen.tsx b/ts/features/bonus/common/screens/AvailableBonusScreen.tsx index f9b6665cc16..4d2593e18c3 100644 --- a/ts/features/bonus/common/screens/AvailableBonusScreen.tsx +++ b/ts/features/bonus/common/screens/AvailableBonusScreen.tsx @@ -31,7 +31,7 @@ import { Dispatch } from "../../../../store/actions/types"; import { isCGNEnabledSelector, isCdcEnabledSelector -} from "../../../../store/reducers/backendStatus"; +} from "../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../store/reducers/types"; import { storeUrl } from "../../../../utils/appVersion"; import { loadServiceDetail } from "../../../services/details/store/actions/details"; diff --git a/ts/features/cieLogin/store/selectors/index.ts b/ts/features/cieLogin/store/selectors/index.ts index 1eff8056be7..976d8386bf3 100644 --- a/ts/features/cieLogin/store/selectors/index.ts +++ b/ts/features/cieLogin/store/selectors/index.ts @@ -1,16 +1,16 @@ import { createSelector } from "reselect"; import { GlobalState } from "../../../../store/reducers/types"; -import { backendStatusSelector } from "../../../../store/reducers/backendStatus"; +import { remoteConfigSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { isPropertyWithMinAppVersionEnabled } from "../../../../store/reducers/featureFlagWithMinAppVersionStatus"; export const isCieLoginUatEnabledSelector = (state: GlobalState) => state.features.loginFeatures.cieLogin.useUat; const isCieIdMinAppVersionEnabledSelector = createSelector( - backendStatusSelector, - backendStatus => + remoteConfigSelector, + remoteConfig => isPropertyWithMinAppVersionEnabled({ - backendStatus, + remoteConfig, mainLocalFlag: true, configPropertyName: "cie_id" }) diff --git a/ts/features/fastLogin/store/selectors/__tests__/fastLogin.test.ts b/ts/features/fastLogin/store/selectors/__tests__/fastLogin.test.ts index a23fe751a10..5716f6b3f0e 100644 --- a/ts/features/fastLogin/store/selectors/__tests__/fastLogin.test.ts +++ b/ts/features/fastLogin/store/selectors/__tests__/fastLogin.test.ts @@ -5,6 +5,7 @@ import { baseRawBackendStatus } from "../../../../../store/reducers/__mock__/bac import { GlobalState } from "../../../../../store/reducers/types"; import { getAppVersion } from "../../../../../utils/appVersion"; import { isFastLoginEnabledSelector } from ".."; +import { Config } from "../../../../../../definitions/content/Config"; jest.mock("react-native-device-info", () => ({ getReadableVersion: jest.fn().mockReturnValue("1.2.3.4"), @@ -33,18 +34,13 @@ describe("FastLogin remote flag test", () => { } } }, - backendStatus: { - status: O.some({ - ...status, - config: {} - }) - } + remoteConfig: O.some({}) } as unknown as GlobalState; const actualStatus = - customStoreWithMissingMinAppVersionInFastLoginConfig.backendStatus.status; + customStoreWithMissingMinAppVersionInFastLoginConfig.remoteConfig; expect(O.isSome(actualStatus)).toBe(true); if (O.isSome(actualStatus)) { - expect(actualStatus.value.config.fastLogin).toBeUndefined(); + expect(actualStatus.value.fastLogin).toBeUndefined(); } const isFastLoginEnabled = isFastLoginEnabledSelector( customStoreWithMissingMinAppVersionInFastLoginConfig @@ -54,12 +50,12 @@ describe("FastLogin remote flag test", () => { function checkBrokenFastLoginFlagTest( minAppVersion: string | undefined, - currentAppVersion: string, + appVersion: string, expectedValue: boolean ) { const testTitle = `FastLogin${ expectedValue ? "" : " NOT" - } enabled with min version ${minAppVersion} for actual version ${currentAppVersion}`; + } enabled with min version ${minAppVersion} for actual version ${appVersion}`; it(testTitle, () => { checkFastLoginFlagWithBrokenStatus(expectedValue); }); @@ -103,20 +99,15 @@ describe("FastLogin remote flag test", () => { } } }, - backendStatus: { - status: O.some({ - ...status, - config: { - ...status.config, - fastLogin: { - min_app_version: { - android: minAppVersion, - ios: minAppVersion - } - } + remoteConfig: O.some({ + ...status.config, + fastLogin: { + min_app_version: { + android: minAppVersion, + ios: minAppVersion } - }) - } + } + } as Config) } as unknown as GlobalState; const isFastLoginEnabled = isFastLoginEnabledSelector(customStore); @@ -125,12 +116,12 @@ describe("FastLogin remote flag test", () => { function checkFastLoginFlagTest( minAppVersion: string | undefined, - currentAppVersion: string, + appVersion: string, expectedValue: boolean ) { const testTitle = `FastLogin${ expectedValue ? "" : " NOT" - } enabled with min version ${minAppVersion} for actual version ${currentAppVersion}`; + } enabled with min version ${minAppVersion} for actual version ${appVersion}`; it(testTitle, () => { checkIfFastLoginFlagIsEnableForThisAppVersion( minAppVersion, diff --git a/ts/features/fastLogin/store/selectors/index.ts b/ts/features/fastLogin/store/selectors/index.ts index 41a9875bbd3..1a760fbb1e4 100644 --- a/ts/features/fastLogin/store/selectors/index.ts +++ b/ts/features/fastLogin/store/selectors/index.ts @@ -1,6 +1,6 @@ import { createSelector } from "reselect"; import { uniqWith, isEqual } from "lodash"; -import { backendStatusSelector } from "../../../../store/reducers/backendStatus"; +import { remoteConfigSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { fastLoginOptIn, fastLoginEnabled } from "../../../../config"; import { GlobalState } from "../../../../store/reducers/types"; import { isPropertyWithMinAppVersionEnabled } from "../../../../store/reducers/featureFlagWithMinAppVersionStatus"; @@ -31,10 +31,10 @@ export const isSecurityAdviceReadyToShow = (state: GlobalState) => * if there is no data, false is the default value -> (FastLoginOptIn disabled) */ export const fastLoginOptInFFEnabled = createSelector( - backendStatusSelector, - backendStatus => + remoteConfigSelector, + remoteConfig => isPropertyWithMinAppVersionEnabled({ - backendStatus, + remoteConfig, mainLocalFlag: fastLoginEnabled, configPropertyName: "fastLogin", optionalLocalFlag: fastLoginOptIn, @@ -59,10 +59,10 @@ const isFastLoginOptInEnabledSelector = createSelector( * if there is no data, false is the default value -> (FastLogin disabled) */ export const isFastLoginFFEnabledSelector = createSelector( - backendStatusSelector, - backendStatus => + remoteConfigSelector, + remoteConfig => isPropertyWithMinAppVersionEnabled({ - backendStatus, + remoteConfig, mainLocalFlag: fastLoginEnabled, configPropertyName: "fastLogin" }) diff --git a/ts/features/fci/components/ErrorComponent.tsx b/ts/features/fci/components/ErrorComponent.tsx index b74d06224a7..fbfec3bcec9 100644 --- a/ts/features/fci/components/ErrorComponent.tsx +++ b/ts/features/fci/components/ErrorComponent.tsx @@ -31,7 +31,7 @@ import { zendeskSupportStart } from "../../zendesk/store/actions"; import { fciSignatureRequestIdSelector } from "../store/reducers/fciSignatureRequest"; -import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; import { InfoScreenComponent } from "./InfoScreenComponent"; diff --git a/ts/features/fci/screens/FciRouterScreen.tsx b/ts/features/fci/screens/FciRouterScreen.tsx index 245e2d1b219..6c001486589 100644 --- a/ts/features/fci/screens/FciRouterScreen.tsx +++ b/ts/features/fci/screens/FciRouterScreen.tsx @@ -13,7 +13,7 @@ import { fciEndRequest, fciSignatureRequestFromId } from "../store/actions"; import { fciSignatureRequestSelector } from "../store/reducers/fciSignatureRequest"; import SuccessComponent from "../components/SuccessComponent"; import GenericErrorComponent from "../components/GenericErrorComponent"; -import { isFciEnabledSelector } from "../../../store/reducers/backendStatus"; +import { isFciEnabledSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { isTestEnv } from "../../../utils/environment"; import { NetworkError, diff --git a/ts/features/fci/screens/valid/FciSignatureRequestsScreen.tsx b/ts/features/fci/screens/valid/FciSignatureRequestsScreen.tsx index e05434beaf7..bd57ac5eacb 100644 --- a/ts/features/fci/screens/valid/FciSignatureRequestsScreen.tsx +++ b/ts/features/fci/screens/valid/FciSignatureRequestsScreen.tsx @@ -7,7 +7,7 @@ import { fciSignaturesListSelector } from "../../store/reducers/fciSignaturesLis import { fciSignaturesListRequest } from "../../store/actions"; import LoadingSpinnerOverlay from "../../../../components/LoadingSpinnerOverlay"; import I18n from "../../../../i18n"; -import { assistanceToolConfigSelector } from "../../../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { addTicketCustomField, assistanceToolRemoteConfig, diff --git a/ts/features/fims/history/screens/HistoryScreen.tsx b/ts/features/fims/history/screens/HistoryScreen.tsx index c6e937f1762..b4b010168b3 100644 --- a/ts/features/fims/history/screens/HistoryScreen.tsx +++ b/ts/features/fims/history/screens/HistoryScreen.tsx @@ -4,7 +4,7 @@ import * as React from "react"; import { useHeaderSecondLevel } from "../../../../hooks/useHeaderSecondLevel"; import I18n from "../../../../i18n"; import { useIODispatch, useIOSelector } from "../../../../store/hooks"; -import { fimsRequiresAppUpdateSelector } from "../../../../store/reducers/backendStatus"; +import { fimsRequiresAppUpdateSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { trackHistoryFailure, trackHistoryScreen diff --git a/ts/features/fims/history/store/selectors/__tests__/index.test.ts b/ts/features/fims/history/store/selectors/__tests__/index.test.ts index 6975fa15b4f..c640f848578 100644 --- a/ts/features/fims/history/store/selectors/__tests__/index.test.ts +++ b/ts/features/fims/history/store/selectors/__tests__/index.test.ts @@ -5,26 +5,20 @@ import { GlobalState } from "../../../../../../store/reducers/types"; describe("fimsIsHistoryEnabledSelector", () => { it("should return 'false' if 'backendStatus' is 'O.none'", () => { const globalState = { - backendStatus: { - status: O.none - } + remoteConfig: O.none } as GlobalState; const fimsHistoryEnabled = fimsIsHistoryEnabledSelector(globalState); expect(fimsHistoryEnabled).toBe(false); }); [undefined, false, true].forEach(historyEnabled => { const expectedOutput = historyEnabled !== false; - it(`should return '${expectedOutput}' if 'backendStatus' is 'O.some(${historyEnabled})'`, () => { + it(`should return '${expectedOutput}' if 'remoteConfig' is 'O.some(${historyEnabled})'`, () => { const globalState = { - backendStatus: { - status: O.some({ - config: { - fims: { - historyEnabled - } - } - }) - } + remoteConfig: O.some({ + fims: { + historyEnabled + } + }) } as GlobalState; const fimsHistoryEnabled = fimsIsHistoryEnabledSelector(globalState); expect(fimsHistoryEnabled).toBe(expectedOutput); diff --git a/ts/features/fims/history/store/selectors/index.ts b/ts/features/fims/history/store/selectors/index.ts index 65d6211212d..24a7cfa7a4f 100644 --- a/ts/features/fims/history/store/selectors/index.ts +++ b/ts/features/fims/history/store/selectors/index.ts @@ -1,7 +1,7 @@ import * as pot from "@pagopa/ts-commons/lib/pot"; import * as O from "fp-ts/Option"; import { constUndefined, pipe } from "fp-ts/lib/function"; -import { backendStatusSelector } from "../../../../../store/reducers/backendStatus"; +import { remoteConfigSelector } from "../../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../../store/reducers/types"; import { potFoldWithDefault } from "../../../../../utils/pot"; @@ -29,8 +29,8 @@ export const fimsHistoryErrorSelector = ( export const fimsIsHistoryEnabledSelector = (state: GlobalState) => pipe( state, - backendStatusSelector, - O.map(backendStatus => backendStatus.config.fims.historyEnabled !== false), + remoteConfigSelector, + O.map(remoteConfig => remoteConfig.fims.historyEnabled !== false), O.getOrElse(() => false) ); diff --git a/ts/features/fims/singleSignOn/saga/handleFimsAbortOrCancel.ts b/ts/features/fims/singleSignOn/saga/handleFimsAbortOrCancel.ts index 542004a05ea..59517bea461 100644 --- a/ts/features/fims/singleSignOn/saga/handleFimsAbortOrCancel.ts +++ b/ts/features/fims/singleSignOn/saga/handleFimsAbortOrCancel.ts @@ -4,7 +4,7 @@ import { nativeRequest } from "@pagopa/io-react-native-http-client"; import { call, select } from "typed-redux-saga/macro"; -import { fimsDomainSelector } from "../../../../store/reducers/backendStatus"; +import { fimsDomainSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { fimsPartialAbortUrl } from "../store/selectors"; import { deallocateFimsResourcesAndNavigateBack } from "./handleFimsResourcesDeallocation"; import { diff --git a/ts/features/fims/singleSignOn/saga/handleFimsGetConsentsList.ts b/ts/features/fims/singleSignOn/saga/handleFimsGetConsentsList.ts index f290b095e32..adb33c88d4d 100644 --- a/ts/features/fims/singleSignOn/saga/handleFimsGetConsentsList.ts +++ b/ts/features/fims/singleSignOn/saga/handleFimsGetConsentsList.ts @@ -10,7 +10,7 @@ import { identity, pipe } from "fp-ts/lib/function"; import { call, put, select } from "typed-redux-saga/macro"; import { ActionType, isActionOf } from "typesafe-actions"; import { fimsTokenSelector } from "../../../../store/reducers/authentication"; -import { fimsDomainSelector } from "../../../../store/reducers/backendStatus"; +import { fimsDomainSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { fimsGetConsentsListAction } from "../store/actions"; import { ConsentData } from "../types"; import { deallocateFimsAndRenewFastLoginSession } from "./handleFimsResourcesDeallocation"; diff --git a/ts/features/fims/singleSignOn/saga/handleFimsGetRedirectUrlAndOpenIAB.ts b/ts/features/fims/singleSignOn/saga/handleFimsGetRedirectUrlAndOpenIAB.ts index 718157cb8ee..4a6c9cea599 100644 --- a/ts/features/fims/singleSignOn/saga/handleFimsGetRedirectUrlAndOpenIAB.ts +++ b/ts/features/fims/singleSignOn/saga/handleFimsGetRedirectUrlAndOpenIAB.ts @@ -15,7 +15,7 @@ import { } from "react-native-url-polyfill"; import { call, put, select } from "typed-redux-saga/macro"; import { ActionType } from "typesafe-actions"; -import { fimsDomainSelector } from "../../../../store/reducers/backendStatus"; +import { fimsDomainSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { ReduxSagaEffect } from "../../../../types/utils"; import { LollipopConfig } from "../../../lollipop"; import { generateKeyInfo } from "../../../lollipop/saga"; diff --git a/ts/features/fims/singleSignOn/saga/handleFimsResourcesDeallocation.ts b/ts/features/fims/singleSignOn/saga/handleFimsResourcesDeallocation.ts index 734201f8399..fbeea5b4d11 100644 --- a/ts/features/fims/singleSignOn/saga/handleFimsResourcesDeallocation.ts +++ b/ts/features/fims/singleSignOn/saga/handleFimsResourcesDeallocation.ts @@ -5,7 +5,7 @@ import { import { StackActions } from "@react-navigation/native"; import { call, put, select } from "typed-redux-saga/macro"; import NavigationService from "../../../../navigation/NavigationService"; -import { fimsDomainSelector } from "../../../../store/reducers/backendStatus"; +import { fimsDomainSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { refreshSessionToken } from "../../../fastLogin/store/actions/tokenRefreshActions"; import { fimsRelyingPartyDomainSelector } from "../store/selectors"; diff --git a/ts/features/fims/singleSignOn/screens/FimsFlowHandlerScreen.tsx b/ts/features/fims/singleSignOn/screens/FimsFlowHandlerScreen.tsx index e0b177ea986..96835bed9d4 100644 --- a/ts/features/fims/singleSignOn/screens/FimsFlowHandlerScreen.tsx +++ b/ts/features/fims/singleSignOn/screens/FimsFlowHandlerScreen.tsx @@ -10,7 +10,7 @@ import { useHeaderSecondLevel } from "../../../../hooks/useHeaderSecondLevel"; import I18n from "../../../../i18n"; import { IOStackNavigationRouteProps } from "../../../../navigation/params/AppParamsList"; import { useIODispatch, useIOSelector } from "../../../../store/hooks"; -import { fimsRequiresAppUpdateSelector } from "../../../../store/reducers/backendStatus"; +import { fimsRequiresAppUpdateSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { trackAuthenticationError } from "../../common/analytics"; import { FimsUpdateAppAlert } from "../../common/components/FimsUpdateAppAlert"; import { FimsParamsList } from "../../common/navigation"; diff --git a/ts/features/idpay/configuration/screens/IbanConfigurationLandingScreen.tsx b/ts/features/idpay/configuration/screens/IbanConfigurationLandingScreen.tsx index 3507eb1338a..8872d2b88ef 100644 --- a/ts/features/idpay/configuration/screens/IbanConfigurationLandingScreen.tsx +++ b/ts/features/idpay/configuration/screens/IbanConfigurationLandingScreen.tsx @@ -13,7 +13,7 @@ import { IOStyles } from "../../../../components/core/variables/IOStyles"; import BaseScreenComponent from "../../../../components/screens/BaseScreenComponent"; import I18n from "../../../../i18n"; import { useIOSelector } from "../../../../store/hooks"; -import { isSettingsVisibleAndHideProfileSelector } from "../../../../store/reducers/backendStatus"; +import { isSettingsVisibleAndHideProfileSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp"; import { useIOBottomSheetAutoresizableModal } from "../../../../utils/hooks/bottomSheet"; import { IdPayConfigurationMachineContext } from "../machine/provider"; diff --git a/ts/features/idpay/configuration/screens/IbanEnrollmentScreen.tsx b/ts/features/idpay/configuration/screens/IbanEnrollmentScreen.tsx index 22e6bb44cdc..41bfe23b1cd 100644 --- a/ts/features/idpay/configuration/screens/IbanEnrollmentScreen.tsx +++ b/ts/features/idpay/configuration/screens/IbanEnrollmentScreen.tsx @@ -17,7 +17,7 @@ import BaseScreenComponent from "../../../../components/screens/BaseScreenCompon import ListItemComponent from "../../../../components/screens/ListItemComponent"; import I18n from "../../../../i18n"; import { useIOSelector } from "../../../../store/hooks"; -import { isSettingsVisibleAndHideProfileSelector } from "../../../../store/reducers/backendStatus"; +import { isSettingsVisibleAndHideProfileSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import customVariables from "../../../../theme/variables"; import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp"; import { diff --git a/ts/features/idpay/configuration/screens/IbanOnboardingScreen.tsx b/ts/features/idpay/configuration/screens/IbanOnboardingScreen.tsx index ce5c513e90d..c27ee866bfe 100644 --- a/ts/features/idpay/configuration/screens/IbanOnboardingScreen.tsx +++ b/ts/features/idpay/configuration/screens/IbanOnboardingScreen.tsx @@ -18,7 +18,7 @@ import { IOStyles } from "../../../../components/core/variables/IOStyles"; import BaseScreenComponent from "../../../../components/screens/BaseScreenComponent"; import I18n from "../../../../i18n"; import { useIOSelector } from "../../../../store/hooks"; -import { isSettingsVisibleAndHideProfileSelector } from "../../../../store/reducers/backendStatus"; +import { isSettingsVisibleAndHideProfileSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp"; import { isLoadingSelector } from "../../common/machine/selectors"; import { IdPayConfigurationMachineContext } from "../machine/provider"; diff --git a/ts/features/idpay/wallet/store/reducers/__test__/reducer.test.ts b/ts/features/idpay/wallet/store/reducers/__test__/reducer.test.ts index d80c4c35c61..ccb5fc68d78 100644 --- a/ts/features/idpay/wallet/store/reducers/__test__/reducer.test.ts +++ b/ts/features/idpay/wallet/store/reducers/__test__/reducer.test.ts @@ -11,7 +11,7 @@ import { InitiativesWithInstrumentDTO } from "../../../../../../../definitions/i import { WalletDTO } from "../../../../../../../definitions/idpay/WalletDTO"; import { applicationChangeState } from "../../../../../../store/actions/application"; import { appReducer } from "../../../../../../store/reducers"; -import { isIdPayEnabledSelector } from "../../../../../../store/reducers/backendStatus"; +import { isIdPayEnabledSelector } from "../../../../../../store/reducers/backendStatus/remoteConfig"; import { NetworkError } from "../../../../../../utils/errors"; import { idPayInitiativesFromInstrumentGet, diff --git a/ts/features/idpay/wallet/store/reducers/index.ts b/ts/features/idpay/wallet/store/reducers/index.ts index 4c3f750137b..eabd124edd5 100644 --- a/ts/features/idpay/wallet/store/reducers/index.ts +++ b/ts/features/idpay/wallet/store/reducers/index.ts @@ -7,7 +7,7 @@ import { StatusEnum as InstrumentInitiativeStatus } from "../../../../../../defi import { InitiativesWithInstrumentDTO } from "../../../../../../definitions/idpay/InitiativesWithInstrumentDTO"; import { WalletDTO } from "../../../../../../definitions/idpay/WalletDTO"; import { Action } from "../../../../../store/actions/types"; -import { isIdPayEnabledSelector } from "../../../../../store/reducers/backendStatus"; +import { isIdPayEnabledSelector } from "../../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../../store/reducers/types"; import { NetworkError } from "../../../../../utils/errors"; import { diff --git a/ts/features/ingress/__test__/IngressScreen.test.tsx b/ts/features/ingress/__test__/IngressScreen.test.tsx index 32d0412eda6..b43e514376b 100644 --- a/ts/features/ingress/__test__/IngressScreen.test.tsx +++ b/ts/features/ingress/__test__/IngressScreen.test.tsx @@ -8,7 +8,7 @@ import { renderScreenWithNavigationStoreContext } from "../../../utils/testWrapp import { applicationChangeState } from "../../../store/actions/application"; import { appReducer } from "../../../store/reducers"; import I18n from "../../../i18n"; -import * as backendStatusSelectors from "../../../store/reducers/backendStatus"; +import * as backendStatusSelectors from "../../../store/reducers/backendStatus/remoteConfig"; jest.useFakeTimers(); diff --git a/ts/features/ingress/screens/IngressScreen.tsx b/ts/features/ingress/screens/IngressScreen.tsx index 21c165cde26..d58476d85f0 100644 --- a/ts/features/ingress/screens/IngressScreen.tsx +++ b/ts/features/ingress/screens/IngressScreen.tsx @@ -15,7 +15,7 @@ import { trackIngressScreen } from "../../../screens/profile/analytics"; import LoadingScreenContent from "../../../components/screens/LoadingScreenContent"; import { OperationResultScreenContent } from "../../../components/screens/OperationResultScreenContent"; import { useIODispatch, useIOSelector } from "../../../store/hooks"; -import { isBackendStatusLoadedSelector } from "../../../store/reducers/backendStatus"; +import { isBackendStatusLoadedSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { setIsBlockingScreen } from "../store/actions"; import ModalSectionStatusComponent from "../../../components/SectionStatus/modal"; import { isMixpanelInitializedSelector } from "../../mixpanel/store/selectors"; diff --git a/ts/features/itwallet/common/components/ItwDiscoveryBanner.tsx b/ts/features/itwallet/common/components/ItwDiscoveryBanner.tsx index 0b12d58865c..b2a95e68187 100644 --- a/ts/features/itwallet/common/components/ItwDiscoveryBanner.tsx +++ b/ts/features/itwallet/common/components/ItwDiscoveryBanner.tsx @@ -8,7 +8,7 @@ import { useIOSelector } from "../../../../store/hooks"; import { isItwTrialActiveSelector } from "../../../trialSystem/store/reducers"; import { ITW_ROUTES } from "../../navigation/routes"; import { itwLifecycleIsValidSelector } from "../../lifecycle/store/selectors"; -import { isItwEnabledSelector } from "../../../../store/reducers/backendStatus"; +import { isItwEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { trackItWalletBannerTap, trackItWalletBannerClosure, diff --git a/ts/features/itwallet/common/components/__tests__/ItwDiscoveryBanner.test.tsx b/ts/features/itwallet/common/components/__tests__/ItwDiscoveryBanner.test.tsx index 501b614aa9b..dd4f9c5af00 100644 --- a/ts/features/itwallet/common/components/__tests__/ItwDiscoveryBanner.test.tsx +++ b/ts/features/itwallet/common/components/__tests__/ItwDiscoveryBanner.test.tsx @@ -3,13 +3,12 @@ import * as O from "fp-ts/lib/Option"; import _ from "lodash"; import configureMockStore from "redux-mock-store"; import { ToolEnum } from "../../../../../../definitions/content/AssistanceToolConfig"; -import { BackendStatus } from "../../../../../../definitions/content/BackendStatus"; import { Config } from "../../../../../../definitions/content/Config"; import { SubscriptionStateEnum } from "../../../../../../definitions/trial_system/SubscriptionState"; import ROUTES from "../../../../../navigation/routes"; import { applicationChangeState } from "../../../../../store/actions/application"; import { appReducer } from "../../../../../store/reducers"; -import { BackendStatusState } from "../../../../../store/reducers/backendStatus"; +import { RemoteConfigState } from "../../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../../store/reducers/types"; import { renderScreenWithNavigationStoreContext } from "../../../../../utils/testWrapper"; import { ItwLifecycleState } from "../../../lifecycle/store/reducers"; @@ -75,29 +74,25 @@ const renderComponent = ({ lifecycle: ItwLifecycleState.ITW_LIFECYCLE_INSTALLED } }, - backendStatus: { - status: O.some({ - config: { - itw: { - enabled: isItwEnabled, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - assistanceTool: { tool: ToolEnum.none }, - cgn: { enabled: true }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { enabled: true } - } as Config - } as BackendStatus) - } as BackendStatusState + remoteConfig: O.some({ + itw: { + enabled: isItwEnabled, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + assistanceTool: { tool: ToolEnum.none }, + cgn: { enabled: true }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + fims: { enabled: true } + } as Config) as RemoteConfigState } as GlobalState) ); diff --git a/ts/features/itwallet/common/components/__tests__/ItwUpcomingWalletBanner.test.tsx b/ts/features/itwallet/common/components/__tests__/ItwUpcomingWalletBanner.test.tsx index f85a2803e8a..b3e54dbcef3 100644 --- a/ts/features/itwallet/common/components/__tests__/ItwUpcomingWalletBanner.test.tsx +++ b/ts/features/itwallet/common/components/__tests__/ItwUpcomingWalletBanner.test.tsx @@ -3,13 +3,11 @@ import * as O from "fp-ts/lib/Option"; import _ from "lodash"; import configureMockStore from "redux-mock-store"; import { ToolEnum } from "../../../../../../definitions/content/AssistanceToolConfig"; -import { BackendStatus } from "../../../../../../definitions/content/BackendStatus"; import { Config } from "../../../../../../definitions/content/Config"; import { SubscriptionStateEnum } from "../../../../../../definitions/trial_system/SubscriptionState"; import ROUTES from "../../../../../navigation/routes"; import { applicationChangeState } from "../../../../../store/actions/application"; import { appReducer } from "../../../../../store/reducers"; -import { BackendStatusState } from "../../../../../store/reducers/backendStatus"; import { GlobalState } from "../../../../../store/reducers/types"; import { renderScreenWithNavigationStoreContext } from "../../../../../utils/testWrapper"; import { itwTrialId } from "../../../../../config"; @@ -60,29 +58,25 @@ const renderComponent = ({ trialSystem: { [itwTrialId]: pot.some(itwTrialStatus) }, - backendStatus: { - status: O.some({ - config: { - itw: { - enabled: isItwEnabled, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - assistanceTool: { tool: ToolEnum.none }, - cgn: { enabled: true }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { enabled: true } - } as Config - } as BackendStatus) - } as BackendStatusState + remoteConfig: O.some({ + itw: { + enabled: isItwEnabled, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + assistanceTool: { tool: ToolEnum.none }, + cgn: { enabled: true }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + fims: { enabled: true } + } as Config) } as GlobalState) ); diff --git a/ts/features/itwallet/navigation/useItwLinkingOptions.tsx b/ts/features/itwallet/navigation/useItwLinkingOptions.tsx index f7d02f5bdff..f11f0c0bfd7 100644 --- a/ts/features/itwallet/navigation/useItwLinkingOptions.tsx +++ b/ts/features/itwallet/navigation/useItwLinkingOptions.tsx @@ -2,7 +2,7 @@ import { PathConfigMap } from "@react-navigation/native"; import { useIOSelector } from "../../../store/hooks"; import { isItwTrialActiveSelector } from "../../trialSystem/store/reducers"; import { itwLifecycleIsValidSelector } from "../lifecycle/store/selectors"; -import { isItwEnabledSelector } from "../../../store/reducers/backendStatus"; +import { isItwEnabledSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { AppParamsList } from "../../../navigation/params/AppParamsList"; import { ITW_ROUTES } from "./routes"; diff --git a/ts/features/itwallet/onboarding/screens/WalletCardOnboardingScreen.tsx b/ts/features/itwallet/onboarding/screens/WalletCardOnboardingScreen.tsx index 90e94fddb80..29a3ac6f281 100644 --- a/ts/features/itwallet/onboarding/screens/WalletCardOnboardingScreen.tsx +++ b/ts/features/itwallet/onboarding/screens/WalletCardOnboardingScreen.tsx @@ -14,7 +14,7 @@ import { IOScrollViewWithLargeHeader } from "../../../../components/ui/IOScrollV import I18n from "../../../../i18n"; import { useIONavigation } from "../../../../navigation/params/AppParamsList"; import { useIODispatch, useIOSelector } from "../../../../store/hooks"; -import { isItwEnabledSelector } from "../../../../store/reducers/backendStatus"; +import { isItwEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { emptyContextualHelp } from "../../../../utils/emptyContextualHelp"; import { cgnActivationStart } from "../../../bonus/cgn/store/actions/activation"; import { diff --git a/ts/features/itwallet/onboarding/screens/__tests__/WalletCardOnboardingScreen.test.tsx b/ts/features/itwallet/onboarding/screens/__tests__/WalletCardOnboardingScreen.test.tsx index d443e1bbc0f..2d71dfb8947 100644 --- a/ts/features/itwallet/onboarding/screens/__tests__/WalletCardOnboardingScreen.test.tsx +++ b/ts/features/itwallet/onboarding/screens/__tests__/WalletCardOnboardingScreen.test.tsx @@ -4,7 +4,6 @@ import _ from "lodash"; import * as React from "react"; import configureMockStore from "redux-mock-store"; import { ToolEnum } from "../../../../../../definitions/content/AssistanceToolConfig"; -import { BackendStatus } from "../../../../../../definitions/content/BackendStatus"; import { Config } from "../../../../../../definitions/content/Config"; import { SubscriptionState, @@ -14,7 +13,7 @@ import { TrialId } from "../../../../../../definitions/trial_system/TrialId"; import { itwTrialId } from "../../../../../config"; import { applicationChangeState } from "../../../../../store/actions/application"; import { appReducer } from "../../../../../store/reducers"; -import { BackendStatusState } from "../../../../../store/reducers/backendStatus"; +import { RemoteConfigState } from "../../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../../store/reducers/types"; import { renderScreenWithNavigationStoreContext } from "../../../../../utils/testWrapper"; import { CredentialType } from "../../../common/utils/itwMocksUtils"; @@ -95,35 +94,31 @@ const renderComponent = ({ persistedPreferences: { isIdPayTestEnabled: isIdPayEnabled }, - backendStatus: { - status: O.some({ - config: { - itw: { - enabled: isItwEnabled, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - idPay: isIdPayEnabled && { - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - assistanceTool: { tool: ToolEnum.none }, - cgn: { enabled: true }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { enabled: true } - } as Config - } as BackendStatus) - } as BackendStatusState + remoteConfig: O.some({ + itw: { + enabled: isItwEnabled, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + idPay: isIdPayEnabled && { + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + assistanceTool: { tool: ToolEnum.none }, + cgn: { enabled: true }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + fims: { enabled: true } + } as Config) as RemoteConfigState } as GlobalState) ); const logic = itwCredentialIssuanceMachine.provide({ diff --git a/ts/features/messages/components/Home/PreconditionsContent.tsx b/ts/features/messages/components/Home/PreconditionsContent.tsx index a68e6a01482..1e78e78e52c 100644 --- a/ts/features/messages/components/Home/PreconditionsContent.tsx +++ b/ts/features/messages/components/Home/PreconditionsContent.tsx @@ -13,7 +13,7 @@ import { preconditionsContentSelector } from "../../store/reducers/messagePrecondition"; import I18n from "../../../../i18n"; -import { pnMinAppVersionSelector } from "../../../../store/reducers/backendStatus"; +import { pnMinAppVersionSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { MessageMarkdown } from "../MessageDetail/MessageMarkdown"; import { errorPreconditionStatusAction, diff --git a/ts/features/messages/components/Home/__tests__/PreconditionsContent.test.tsx b/ts/features/messages/components/Home/__tests__/PreconditionsContent.test.tsx index 0d37de2af43..f71d0f86fb6 100644 --- a/ts/features/messages/components/Home/__tests__/PreconditionsContent.test.tsx +++ b/ts/features/messages/components/Home/__tests__/PreconditionsContent.test.tsx @@ -8,7 +8,7 @@ import { renderScreenWithNavigationStoreContext } from "../../../../../utils/tes import { PreconditionsContent } from "../PreconditionsContent"; import { MESSAGES_ROUTES } from "../../../navigation/routes"; import * as messagePreconditions from "../../../store/reducers/messagePrecondition"; -import * as backendStatus from "../../../../../store/reducers/backendStatus"; +import * as backendStatus from "../../../../../store/reducers/backendStatus/remoteConfig"; import { MarkdownProps } from "../../../../../components/ui/Markdown/Markdown"; import { errorPreconditionStatusAction, diff --git a/ts/features/messages/components/MessageDetail/MessageDetailsPaymentButton.tsx b/ts/features/messages/components/MessageDetail/MessageDetailsPaymentButton.tsx index d074b74543c..ae687ab2598 100644 --- a/ts/features/messages/components/MessageDetail/MessageDetailsPaymentButton.tsx +++ b/ts/features/messages/components/MessageDetail/MessageDetailsPaymentButton.tsx @@ -11,7 +11,7 @@ import { getRptIdStringFromPaymentData, initializeAndNavigateToWalletForPayment } from "../../utils"; -import { isNewPaymentSectionEnabledSelector } from "../../../../store/reducers/backendStatus"; +import { isNewPaymentSectionEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { ServiceId } from "../../../../../definitions/backend/ServiceId"; import { computeAndTrackPaymentStart } from "./detailsUtils"; diff --git a/ts/features/messages/components/MessageDetail/MessagePaymentItem.tsx b/ts/features/messages/components/MessageDetail/MessagePaymentItem.tsx index ccdce45e004..ee6514c4cf9 100644 --- a/ts/features/messages/components/MessageDetail/MessagePaymentItem.tsx +++ b/ts/features/messages/components/MessageDetail/MessagePaymentItem.tsx @@ -41,7 +41,7 @@ import { import { initializeAndNavigateToWalletForPayment } from "../../utils"; import { getBadgeTextByPaymentNoticeStatus } from "../../utils/strings"; import { formatPaymentNoticeNumber } from "../../../payments/common/utils"; -import { isNewPaymentSectionEnabledSelector } from "../../../../store/reducers/backendStatus"; +import { isNewPaymentSectionEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { ServiceId } from "../../../../../definitions/backend/ServiceId"; import { trackPNPaymentStart } from "../../../pn/analytics"; import { computeAndTrackPaymentStart } from "./detailsUtils"; diff --git a/ts/features/messages/navigation/MessagesNavigator.tsx b/ts/features/messages/navigation/MessagesNavigator.tsx index 78653b4d5aa..4c52b674995 100644 --- a/ts/features/messages/navigation/MessagesNavigator.tsx +++ b/ts/features/messages/navigation/MessagesNavigator.tsx @@ -8,7 +8,7 @@ import { MessageRouterScreen } from "../screens/MessageRouterScreen"; import { PnStackNavigator } from "../../pn/navigation/navigator"; import PN_ROUTES from "../../pn/navigation/routes"; import { useIOSelector } from "../../../store/hooks"; -import { isPnEnabledSelector } from "../../../store/reducers/backendStatus"; +import { isPnEnabledSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { MessageAttachmentScreen } from "../screens/MessageAttachmentScreen"; import { MessagesParamsList } from "./params"; import { MESSAGES_ROUTES } from "./routes"; diff --git a/ts/features/messages/saga/__test__/handleLoadMessageData.test.ts b/ts/features/messages/saga/__test__/handleLoadMessageData.test.ts index 8a071615483..2bdf322fb13 100644 --- a/ts/features/messages/saga/__test__/handleLoadMessageData.test.ts +++ b/ts/features/messages/saga/__test__/handleLoadMessageData.test.ts @@ -18,7 +18,7 @@ import { messageDetailsByIdSelector } from "../../store/reducers/detailsById"; import { ThirdPartyMessageWithContent } from "../../../../../definitions/backend/ThirdPartyMessageWithContent"; import { thirdPartyFromIdSelector } from "../../store/reducers/thirdPartyById"; import { TagEnum } from "../../../../../definitions/backend/MessageCategoryPN"; -import { isPnEnabledSelector } from "../../../../store/reducers/backendStatus"; +import { isPnEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { isLoadingOrUpdatingInbox } from "../../store/reducers/allPaginated"; import { ThirdPartyMessage } from "../../../../../definitions/backend/ThirdPartyMessage"; import { ThirdPartyAttachment } from "../../../../../definitions/backend/ThirdPartyAttachment"; diff --git a/ts/features/messages/saga/handleLoadMessageData.ts b/ts/features/messages/saga/handleLoadMessageData.ts index de5b221d78c..9e90e377df9 100644 --- a/ts/features/messages/saga/handleLoadMessageData.ts +++ b/ts/features/messages/saga/handleLoadMessageData.ts @@ -25,7 +25,7 @@ import { thirdPartyFromIdSelector } from "../store/reducers/thirdPartyById"; import { isLoadingOrUpdatingInbox } from "../store/reducers/allPaginated"; import { TagEnum } from "../../../../definitions/backend/MessageCategoryPN"; import { euCovidCertificateEnabled } from "../../../config"; -import { isPnEnabledSelector } from "../../../store/reducers/backendStatus"; +import { isPnEnabledSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { trackPNPushOpened } from "../../pn/analytics"; import { isTestEnv } from "../../../utils/environment"; import { ThirdPartyMessageWithContent } from "../../../../definitions/backend/ThirdPartyMessageWithContent"; diff --git a/ts/features/messages/store/reducers/__tests__/messagePrecondition.test.ts b/ts/features/messages/store/reducers/__tests__/messagePrecondition.test.ts index f5dcda12d73..0ee3acbefe0 100644 --- a/ts/features/messages/store/reducers/__tests__/messagePrecondition.test.ts +++ b/ts/features/messages/store/reducers/__tests__/messagePrecondition.test.ts @@ -42,7 +42,7 @@ import { toUpdateRequiredMPS } from "../messagePrecondition"; import { GlobalState } from "../../../../../store/reducers/types"; -import * as backendStatus from "../../../../../store/reducers/backendStatus"; +import * as backendStatus from "../../../../../store/reducers/backendStatus/remoteConfig"; import { MessageCategory } from "../../../../../../definitions/backend/MessageCategory"; const messageId = "01J1FJADCJ53SN4A11J3TBSKQE" as UIMessageId; diff --git a/ts/features/messages/store/reducers/messagePrecondition.ts b/ts/features/messages/store/reducers/messagePrecondition.ts index 1e854e2f332..8abf4a4aaa8 100644 --- a/ts/features/messages/store/reducers/messagePrecondition.ts +++ b/ts/features/messages/store/reducers/messagePrecondition.ts @@ -19,7 +19,7 @@ import { updateRequiredPreconditionStatusAction } from "../actions/preconditions"; import { GlobalState } from "../../../../store/reducers/types"; -import { isPnAppVersionSupportedSelector } from "../../../../store/reducers/backendStatus"; +import { isPnAppVersionSupportedSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { TagEnum as SENDTagEnum } from "../../../../../definitions/backend/MessageCategoryPN"; import { MessageCategory } from "../../../../../definitions/backend/MessageCategory"; diff --git a/ts/features/nativeLogin/store/selectors/__tests__/nativeLogin.test.ts b/ts/features/nativeLogin/store/selectors/__tests__/nativeLogin.test.ts index 58ccc183f5f..7eea0b3e04b 100644 --- a/ts/features/nativeLogin/store/selectors/__tests__/nativeLogin.test.ts +++ b/ts/features/nativeLogin/store/selectors/__tests__/nativeLogin.test.ts @@ -24,19 +24,13 @@ describe("NativeLogin remote flag test", () => { function checkNativeLoginFlagWithBrokenStatus(expectedValue: boolean) { const customStoreWithMissingMinAppVersionInNativeLoginConfig = { - backendStatus: { - status: O.some({ - ...status, - config: {} - }) - } + remoteConfig: O.some({}) } as unknown as GlobalState; const actualStatus = - customStoreWithMissingMinAppVersionInNativeLoginConfig.backendStatus - .status; + customStoreWithMissingMinAppVersionInNativeLoginConfig.remoteConfig; expect(O.isSome(actualStatus)).toBe(true); if (O.isSome(actualStatus)) { - expect(actualStatus.value.config.nativeLogin).toBeUndefined(); + expect(actualStatus.value.nativeLogin).toBeUndefined(); } const isNativeLoginEnabled = isNativeLoginEnabledSelector( customStoreWithMissingMinAppVersionInNativeLoginConfig @@ -46,12 +40,12 @@ describe("NativeLogin remote flag test", () => { function checkBrokenNativeLoginFlagTest( minAppVersion: string | undefined, - currentAppVersion: string, + appVersion: string, expectedValue: boolean ) { const testTitle = `NativeLogin${ expectedValue ? "" : " NOT" - } enabled with min version ${minAppVersion} for actual version ${currentAppVersion}`; + } enabled with min version ${minAppVersion} for actual version ${appVersion}`; it(testTitle, () => { checkNativeLoginFlagWithBrokenStatus(expectedValue); }); @@ -86,20 +80,15 @@ describe("NativeLogin remote flag test", () => { expectedValue: boolean ) { const customStore = { - backendStatus: { - status: O.some({ - ...status, - config: { - ...status.config, - nativeLogin: { - min_app_version: { - android: minAppVersion, - ios: minAppVersion - } - } + remoteConfig: O.some({ + ...status.config, + nativeLogin: { + min_app_version: { + android: minAppVersion, + ios: minAppVersion } - }) - } + } + }) } as unknown as GlobalState; const isNativeLoginEnabled = isNativeLoginEnabledSelector(customStore); @@ -108,12 +97,12 @@ describe("NativeLogin remote flag test", () => { function checkNativeLoginFlagTest( minAppVersion: string | undefined, - currentAppVersion: string, + appVersion: string, expectedValue: boolean ) { const testTitle = `NativeLogin${ expectedValue ? "" : " NOT" - } enabled with min version ${minAppVersion} for actual version ${currentAppVersion}`; + } enabled with min version ${minAppVersion} for actual version ${appVersion}`; it(testTitle, () => { checkIfNativeLoginFlagIsEnableForThisAppVersion( minAppVersion, diff --git a/ts/features/nativeLogin/store/selectors/index.ts b/ts/features/nativeLogin/store/selectors/index.ts index 285d6983e6f..62dbc965da7 100644 --- a/ts/features/nativeLogin/store/selectors/index.ts +++ b/ts/features/nativeLogin/store/selectors/index.ts @@ -1,5 +1,5 @@ import { createSelector } from "reselect"; -import { backendStatusSelector } from "../../../../store/reducers/backendStatus"; +import { remoteConfigSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { nativeLoginEnabled } from "../../../../config"; import { isPropertyWithMinAppVersionEnabled } from "../../../../store/reducers/featureFlagWithMinAppVersionStatus"; @@ -9,10 +9,10 @@ import { isPropertyWithMinAppVersionEnabled } from "../../../../store/reducers/f * if there is no data, false is the default value -> (NativeLogin disabled) */ export const isNativeLoginEnabledSelector = createSelector( - backendStatusSelector, - backendStatus => + remoteConfigSelector, + remoteConfig => isPropertyWithMinAppVersionEnabled({ - backendStatus, + remoteConfig, mainLocalFlag: nativeLoginEnabled, configPropertyName: "nativeLogin" }) diff --git a/ts/features/newWallet/components/WalletCardsContainer.tsx b/ts/features/newWallet/components/WalletCardsContainer.tsx index b3f16a670a3..53f2b582f01 100644 --- a/ts/features/newWallet/components/WalletCardsContainer.tsx +++ b/ts/features/newWallet/components/WalletCardsContainer.tsx @@ -9,7 +9,7 @@ import Animated, { LinearTransition } from "react-native-reanimated"; import { useFocusEffect } from "@react-navigation/native"; import I18n from "../../../i18n"; import { useIOSelector } from "../../../store/hooks"; -import { isItwEnabledSelector } from "../../../store/reducers/backendStatus"; +import { isItwEnabledSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { ItwDiscoveryBanner } from "../../itwallet/common/components/ItwDiscoveryBanner"; import { itwLifecycleIsValidSelector } from "../../itwallet/lifecycle/store/selectors"; import { isItwTrialActiveSelector } from "../../trialSystem/store/reducers"; diff --git a/ts/features/newWallet/components/__tests__/WalletCardsContainer.test.tsx b/ts/features/newWallet/components/__tests__/WalletCardsContainer.test.tsx index 1d6123fa7e7..ea4131deae5 100644 --- a/ts/features/newWallet/components/__tests__/WalletCardsContainer.test.tsx +++ b/ts/features/newWallet/components/__tests__/WalletCardsContainer.test.tsx @@ -4,13 +4,12 @@ import _ from "lodash"; import * as React from "react"; import configureMockStore from "redux-mock-store"; import { ToolEnum } from "../../../../../definitions/content/AssistanceToolConfig"; -import { BackendStatus } from "../../../../../definitions/content/BackendStatus"; import { Config } from "../../../../../definitions/content/Config"; import { SubscriptionStateEnum } from "../../../../../definitions/trial_system/SubscriptionState"; import ROUTES from "../../../../navigation/routes"; import { applicationChangeState } from "../../../../store/actions/application"; import { appReducer } from "../../../../store/reducers"; -import { BackendStatusState } from "../../../../store/reducers/backendStatus"; +import { RemoteConfigState } from "../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../store/reducers/types"; import { renderScreenWithNavigationStoreContext } from "../../../../utils/testWrapper"; import { CredentialType } from "../../../itwallet/common/utils/itwMocksUtils"; @@ -226,29 +225,25 @@ const renderComponent = ({ }) } }, - backendStatus: { - status: O.some({ - config: { - itw: { - enabled: isItwEnabled, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - assistanceTool: { tool: ToolEnum.none }, - cgn: { enabled: true }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { enabled: true } - } as Config - } as BackendStatus) - } as BackendStatusState + remoteConfig: O.some({ + itw: { + enabled: isItwEnabled, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + assistanceTool: { tool: ToolEnum.none }, + cgn: { enabled: true }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + fims: { enabled: true } + } as Config) as RemoteConfigState } as GlobalState) ); diff --git a/ts/features/payments/barcode/screens/PaymentsBarcodeScanScreen.tsx b/ts/features/payments/barcode/screens/PaymentsBarcodeScanScreen.tsx index 2ee00fe4038..2f9605280e8 100644 --- a/ts/features/payments/barcode/screens/PaymentsBarcodeScanScreen.tsx +++ b/ts/features/payments/barcode/screens/PaymentsBarcodeScanScreen.tsx @@ -16,7 +16,7 @@ import { import ROUTES from "../../../../navigation/routes"; import { paymentInitializeState } from "../../../../store/actions/wallet/payment"; import { useIODispatch, useIOSelector } from "../../../../store/hooks"; -import { barcodesScannerConfigSelector } from "../../../../store/reducers/backendStatus"; +import { barcodesScannerConfigSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { isDesignSystemEnabledSelector } from "../../../../store/reducers/persistedPreferences"; import { BarcodeFailure, diff --git a/ts/features/payments/checkout/components/WalletPaymentFeedbackBanner.tsx b/ts/features/payments/checkout/components/WalletPaymentFeedbackBanner.tsx index e1ecf57e1fd..ff326c5a0a4 100644 --- a/ts/features/payments/checkout/components/WalletPaymentFeedbackBanner.tsx +++ b/ts/features/payments/checkout/components/WalletPaymentFeedbackBanner.tsx @@ -7,7 +7,7 @@ import { useIOSelector } from "../../../../store/hooks"; import { isPaymentsFeedbackBannerEnabledSelector, paymentsFeedbackBannerConfigSelector -} from "../../../../store/reducers/backendStatus"; +} from "../../../../store/reducers/backendStatus/remoteConfig"; import { getFullLocale } from "../../../../utils/locale"; const WalletPaymentFeebackBanner = () => { diff --git a/ts/features/payments/checkout/hooks/usePagoPaPayment.ts b/ts/features/payments/checkout/hooks/usePagoPaPayment.ts index 81e92d44cda..d2ad8b81bcf 100644 --- a/ts/features/payments/checkout/hooks/usePagoPaPayment.ts +++ b/ts/features/payments/checkout/hooks/usePagoPaPayment.ts @@ -16,7 +16,7 @@ import { PaymentInitStateParams, initPaymentStateAction } from "../store/actions/orchestration"; -import { isNewPaymentSectionEnabledSelector } from "../../../../store/reducers/backendStatus"; +import { isNewPaymentSectionEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; type PagoPaPaymentParams = Omit; diff --git a/ts/features/payments/checkout/hooks/usePaymentFailureSupportModal.tsx b/ts/features/payments/checkout/hooks/usePaymentFailureSupportModal.tsx index d35cf026519..8f68f5a1210 100644 --- a/ts/features/payments/checkout/hooks/usePaymentFailureSupportModal.tsx +++ b/ts/features/payments/checkout/hooks/usePaymentFailureSupportModal.tsx @@ -16,7 +16,7 @@ import { Linking } from "react-native"; import { ToolEnum } from "../../../../../definitions/content/AssistanceToolConfig"; import I18n from "../../../../i18n"; import { useIODispatch, useIOSelector } from "../../../../store/hooks"; -import { assistanceToolConfigSelector } from "../../../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { clipboardSetStringWithFeedback } from "../../../../utils/clipboard"; import { useIOBottomSheetAutoresizableModal } from "../../../../utils/hooks/bottomSheet"; import { diff --git a/ts/features/payments/details/components/WalletDetailsPaymentMethodFeatures.tsx b/ts/features/payments/details/components/WalletDetailsPaymentMethodFeatures.tsx index c6bbcf15053..81610155361 100644 --- a/ts/features/payments/details/components/WalletDetailsPaymentMethodFeatures.tsx +++ b/ts/features/payments/details/components/WalletDetailsPaymentMethodFeatures.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import { WalletInfo } from "../../../../../definitions/pagopa/walletv3/WalletInfo"; import I18n from "../../../../i18n"; import { useIOSelector } from "../../../../store/hooks"; -import { isIdPayEnabledSelector } from "../../../../store/reducers/backendStatus"; +import { isIdPayEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { isPaymentMethodExpired } from "../../common/utils"; import PaymentMethodInitiatives from "./WalletDetailsPaymentMethodInitiatives"; import PaymentMethodSettings from "./WalletDetailsPaymentMethodSettings"; diff --git a/ts/features/payments/details/screens/PaymentsMethodDetailsScreen.tsx b/ts/features/payments/details/screens/PaymentsMethodDetailsScreen.tsx index 04983ed903e..4d61fc60200 100644 --- a/ts/features/payments/details/screens/PaymentsMethodDetailsScreen.tsx +++ b/ts/features/payments/details/screens/PaymentsMethodDetailsScreen.tsx @@ -3,7 +3,7 @@ import * as pot from "@pagopa/ts-commons/lib/pot"; import { RouteProp, useRoute } from "@react-navigation/native"; import * as React from "react"; import { useIODispatch, useIOSelector } from "../../../../store/hooks"; -import { isIdPayEnabledSelector } from "../../../../store/reducers/backendStatus"; +import { isIdPayEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { capitalize } from "../../../../utils/strings"; import { idPayInitiativesFromInstrumentGet } from "../../../idpay/wallet/store/actions"; import { idPayAreInitiativesFromInstrumentLoadingSelector } from "../../../idpay/wallet/store/reducers"; diff --git a/ts/features/payments/home/components/PaymentsAlertStatus.tsx b/ts/features/payments/home/components/PaymentsAlertStatus.tsx index ad593d4545b..c0da4e2739d 100644 --- a/ts/features/payments/home/components/PaymentsAlertStatus.tsx +++ b/ts/features/payments/home/components/PaymentsAlertStatus.tsx @@ -5,13 +5,13 @@ import Animated, { FadeIn, FadeOut, Layout } from "react-native-reanimated"; import { GestureResponderEvent } from "react-native"; import I18n from "../../../../i18n"; import { useIOSelector } from "../../../../store/hooks"; -import { sectionStatusSelector } from "../../../../store/reducers/backendStatus"; +import { sectionStatusByKeySelector } from "../../../../store/reducers/backendStatus/sectionStatus"; import { getFullLocale } from "../../../../utils/locale"; import { openWebUrl } from "../../../../utils/url"; import { getAlertVariant } from "../../common/utils"; export const PaymentsAlertStatus = () => { - const alertInfo = useIOSelector(sectionStatusSelector("payments")); + const alertInfo = useIOSelector(sectionStatusByKeySelector("payments")); if (!alertInfo || !alertInfo.is_visible) { return null; } diff --git a/ts/features/pn/components/MessageFooter.tsx b/ts/features/pn/components/MessageFooter.tsx index 6fce6821b11..0b6e76938ff 100644 --- a/ts/features/pn/components/MessageFooter.tsx +++ b/ts/features/pn/components/MessageFooter.tsx @@ -17,7 +17,7 @@ import { trackPNPaymentStart, trackPNShowAllPayments } from "../analytics"; import { initializeAndNavigateToWalletForPayment } from "../../messages/utils"; import { paymentsButtonStateSelector } from "../store/reducers/payments"; import { shouldUseBottomSheetForPayments } from "../utils"; -import { isNewPaymentSectionEnabledSelector } from "../../../store/reducers/backendStatus"; +import { isNewPaymentSectionEnabledSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { ServiceId } from "../../../../definitions/backend/ServiceId"; type MessageFooterProps = { diff --git a/ts/features/pn/components/TimelineListItem.tsx b/ts/features/pn/components/TimelineListItem.tsx index 87164d7ebb9..a8d45a182fd 100644 --- a/ts/features/pn/components/TimelineListItem.tsx +++ b/ts/features/pn/components/TimelineListItem.tsx @@ -17,7 +17,7 @@ import { import { trackPNShowTimeline, trackPNTimelineExternal } from "../analytics"; import { handleItemOnPress } from "../../../utils/url"; import { useIOSelector } from "../../../store/hooks"; -import { pnFrontendUrlSelector } from "../../../store/reducers/backendStatus"; +import { pnFrontendUrlSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { Timeline, TimelineItemProps } from "./Timeline"; const topBottomSheetMargin = 122; diff --git a/ts/features/pn/components/__test__/TimelineListItem.test.tsx b/ts/features/pn/components/__test__/TimelineListItem.test.tsx index e3e5612997e..0e07ac14478 100644 --- a/ts/features/pn/components/__test__/TimelineListItem.test.tsx +++ b/ts/features/pn/components/__test__/TimelineListItem.test.tsx @@ -94,38 +94,33 @@ const renderComponent = ( ); const finalState: GlobalState = { ...dsEnabledState, - backendStatus: { - ...dsEnabledState.backendStatus, - status: frontendUrlDefined - ? O.some({ - config: { - cgn: { - enabled: false - }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { - enabled: false - }, - pn: { - frontend_url: "https://www.domain.com/sendUrl" - }, - itw: { - enabled: true, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - } + remoteConfig: frontendUrlDefined + ? O.some({ + cgn: { + enabled: false + }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" } - } as BackendStatus) - : O.none - } + }, + fims: { + enabled: false + }, + pn: { + frontend_url: "https://www.domain.com/sendUrl" + }, + itw: { + enabled: true, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + } + } as BackendStatus["config"]) + : O.none }; const store = createStore(appReducer, finalState as any); return renderScreenWithNavigationStoreContext( diff --git a/ts/features/pn/utils/__tests__/index.test.ts b/ts/features/pn/utils/__tests__/index.test.ts index 6743f114e1b..92981678cd6 100644 --- a/ts/features/pn/utils/__tests__/index.test.ts +++ b/ts/features/pn/utils/__tests__/index.test.ts @@ -17,15 +17,11 @@ const getMockPnOptInServiceId = () => "optInServiceId" as ServiceId; const getMockState = () => ({ - backendStatus: { - status: O.some({ - config: { - pn: { - optInServiceId: getMockPnOptInServiceId() - } - } - }) - } + remoteConfig: O.some({ + pn: { + optInServiceId: getMockPnOptInServiceId() + } + }) } as GlobalState); const getMockCTAs = () => @@ -217,15 +213,11 @@ const isPNOptInMessageTestInput: Array = [ serviceId: getMockPnOptInServiceId(), state: { ...getMockState(), - backendStatus: { - status: O.some({ - config: { - pn: { - optInServiceId: "notTheOptInServiceId" - } - } - }) - } + remoteConfig: O.some({ + pn: { + optInServiceId: "notTheOptInServiceId" + } + }) } as GlobalState }, output: { @@ -242,9 +234,7 @@ const isPNOptInMessageTestInput: Array = [ serviceId: getMockPnOptInServiceId(), state: { ...getMockState(), - backendStatus: { - status: O.none - } + remoteConfig: O.none } as GlobalState }, output: { diff --git a/ts/features/pn/utils/index.ts b/ts/features/pn/utils/index.ts index 88ba746f50e..2beefb1c4a6 100644 --- a/ts/features/pn/utils/index.ts +++ b/ts/features/pn/utils/index.ts @@ -54,10 +54,8 @@ export const extractPNOptInMessageInfoIfAvailable = ( O.fromNullable, O.chain(serviceId => pipe( - state.backendStatus.status, - O.map( - backendStatus => backendStatus.config.pn.optInServiceId === serviceId - ) + state.remoteConfig, + O.map(remoteConfig => remoteConfig.pn.optInServiceId === serviceId) ) ), O.filter(identity), diff --git a/ts/features/services/details/components/ServiceDetailsPreferences.tsx b/ts/features/services/details/components/ServiceDetailsPreferences.tsx index 7b4cd34ce5f..bf0536439b0 100644 --- a/ts/features/services/details/components/ServiceDetailsPreferences.tsx +++ b/ts/features/services/details/components/ServiceDetailsPreferences.tsx @@ -14,7 +14,7 @@ import { NotificationChannelEnum } from "../../../../../definitions/backend/Noti import { ServiceId } from "../../../../../definitions/backend/ServiceId"; import I18n from "../../../../i18n"; import { useIODispatch, useIOSelector } from "../../../../store/hooks"; -import { isPremiumMessagesOptInOutEnabledSelector } from "../../../../store/reducers/backendStatus"; +import { isPremiumMessagesOptInOutEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { useOnFirstRender } from "../../../../utils/hooks/useOnFirstRender"; import { EnabledChannels } from "../../../../utils/profile"; import * as analytics from "../../common/analytics"; diff --git a/ts/features/services/details/components/ServiceSpecialAction.tsx b/ts/features/services/details/components/ServiceSpecialAction.tsx index 8de8d7ef77f..0ccb3b7461c 100644 --- a/ts/features/services/details/components/ServiceSpecialAction.tsx +++ b/ts/features/services/details/components/ServiceSpecialAction.tsx @@ -10,7 +10,7 @@ import { isCGNEnabledSelector, isPnEnabledSelector, isPnAppVersionSupportedSelector -} from "../../../../store/reducers/backendStatus"; +} from "../../../../store/reducers/backendStatus/remoteConfig"; import { openAppStoreUrl } from "../../../../utils/url"; import { CgnServiceCta } from "../../../bonus/cgn/components/CgnServiceCTA"; import { PnServiceCta } from "../../../pn/components/ServiceCTA"; diff --git a/ts/features/tos/store/selectors/__tests__/index.ts b/ts/features/tos/store/selectors/__tests__/index.ts index b775f12b6c6..7fedf0359ef 100644 --- a/ts/features/tos/store/selectors/__tests__/index.ts +++ b/ts/features/tos/store/selectors/__tests__/index.ts @@ -16,22 +16,17 @@ const status: BackendStatus = { }; const customStore = { - backendStatus: { - status: O.some({ - ...status, - config: { - ...status.config, - tos: TOS_CONFIG - } - }) - } + remoteConfig: O.some({ + ...status.config, + tos: TOS_CONFIG + }) } as unknown as GlobalState; function runTest(store: GlobalState, test: (tosConfig: TosConfig) => void) { - const actualStatus = store.backendStatus.status; + const actualStatus = store.remoteConfig; expect(O.isSome(actualStatus)).toBe(true); if (O.isSome(actualStatus)) { - const tosConfig = actualStatus.value.config.tos; + const tosConfig = actualStatus.value.tos; expect(tosConfig).not.toBeUndefined(); test(tosConfig); } else { diff --git a/ts/features/tos/store/selectors/index.ts b/ts/features/tos/store/selectors/index.ts index 4258158d411..9977e1c4fd7 100644 --- a/ts/features/tos/store/selectors/index.ts +++ b/ts/features/tos/store/selectors/index.ts @@ -4,7 +4,7 @@ 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"; +import { remoteConfigSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; const DEFAULT_TOS_CONFIG: TosConfig = { tos_url: privacyUrl, @@ -12,11 +12,11 @@ const DEFAULT_TOS_CONFIG: TosConfig = { }; export const tosConfigSelector = createSelector( - backendStatusSelector, - backendStatus => + remoteConfigSelector, + remoteConfig => pipe( - backendStatus, - O.chainNullableK(bs => bs.config.tos), + remoteConfig, + O.chainNullableK(config => config.tos), O.fold( () => DEFAULT_TOS_CONFIG, v => v diff --git a/ts/features/wallet/bancomatpay/component/__test__/BPayWalletPreview.test.tsx b/ts/features/wallet/bancomatpay/component/__test__/BPayWalletPreview.test.tsx index 17efe9831d8..78c3d78b774 100644 --- a/ts/features/wallet/bancomatpay/component/__test__/BPayWalletPreview.test.tsx +++ b/ts/features/wallet/bancomatpay/component/__test__/BPayWalletPreview.test.tsx @@ -6,7 +6,6 @@ import { Store } from "redux"; import configureMockStore from "redux-mock-store"; import * as pot from "@pagopa/ts-commons/lib/pot"; import { ToolEnum } from "../../../../../../definitions/content/AssistanceToolConfig"; -import { BackendStatus } from "../../../../../../definitions/content/BackendStatus"; import { Config } from "../../../../../../definitions/content/Config"; import NavigationService from "../../../../../navigation/NavigationService"; import ROUTES from "../../../../../navigation/routes"; @@ -51,29 +50,25 @@ describe("BPayWalletPreview component", () => { trialSystem: { [itwTrialId]: pot.some(SubscriptionStateEnum.UNSUBSCRIBED) } as TrialSystemState, - backendStatus: { - status: O.some({ - config: { - assistanceTool: { tool: ToolEnum.none }, - cgn: { enabled: true }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { enabled: true }, - itw: { - enabled: true, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - } - } as Config - } as BackendStatus) - }, + remoteConfig: O.some({ + assistanceTool: { tool: ToolEnum.none }, + cgn: { enabled: true }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + fims: { enabled: true }, + itw: { + enabled: true, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + } + } as Config), features: { itWallet: { lifecycle: ItwLifecycleState.ITW_LIFECYCLE_INSTALLED diff --git a/ts/features/wallet/cobadge/component/__tests__/CobadgeWalletPreview.test.tsx b/ts/features/wallet/cobadge/component/__tests__/CobadgeWalletPreview.test.tsx index 8c93fee07d4..f4a2a381cb0 100644 --- a/ts/features/wallet/cobadge/component/__tests__/CobadgeWalletPreview.test.tsx +++ b/ts/features/wallet/cobadge/component/__tests__/CobadgeWalletPreview.test.tsx @@ -6,7 +6,6 @@ import { Store } from "redux"; import configureMockStore from "redux-mock-store"; import * as pot from "@pagopa/ts-commons/lib/pot"; import { ToolEnum } from "../../../../../../definitions/content/AssistanceToolConfig"; -import { BackendStatus } from "../../../../../../definitions/content/BackendStatus"; import { Config } from "../../../../../../definitions/content/Config"; import NavigationService from "../../../../../navigation/NavigationService"; import ROUTES from "../../../../../navigation/routes"; @@ -60,29 +59,25 @@ describe("CobadgeWalletPreview component", () => { trialSystem: { [itwTrialId]: pot.some(SubscriptionStateEnum.UNSUBSCRIBED) } as TrialSystemState, - backendStatus: { - status: O.some({ - config: { - assistanceTool: { tool: ToolEnum.none }, - cgn: { enabled: true }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { enabled: true }, - itw: { - enabled: true, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - } - } as Config - } as BackendStatus) - }, + remoteConfig: O.some({ + assistanceTool: { tool: ToolEnum.none }, + cgn: { enabled: true }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + }, + fims: { enabled: true }, + itw: { + enabled: true, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + } + } as Config), features: { itWallet: { lifecycle: ItwLifecycleState.ITW_LIFECYCLE_INSTALLED diff --git a/ts/features/wallet/component/card/FeaturedCardCarousel.tsx b/ts/features/wallet/component/card/FeaturedCardCarousel.tsx index af02cdbe5d4..83206a30fde 100644 --- a/ts/features/wallet/component/card/FeaturedCardCarousel.tsx +++ b/ts/features/wallet/component/card/FeaturedCardCarousel.tsx @@ -22,7 +22,7 @@ import { useIODispatch, useIOSelector } from "../../../../store/hooks"; import { isCGNEnabledSelector, isCdcEnabledSelector -} from "../../../../store/reducers/backendStatus"; +} from "../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../store/reducers/types"; import { cgnActivationStart } from "../../../bonus/cgn/store/actions/activation"; import { isCgnEnrolledSelector } from "../../../bonus/cgn/store/reducers/details"; diff --git a/ts/features/wallet/component/card/WalletV2PreviewCards.tsx b/ts/features/wallet/component/card/WalletV2PreviewCards.tsx index 0b7240fc194..6ca9e2f5de6 100644 --- a/ts/features/wallet/component/card/WalletV2PreviewCards.tsx +++ b/ts/features/wallet/component/card/WalletV2PreviewCards.tsx @@ -5,7 +5,7 @@ import { Dispatch } from "redux"; import { bancomatPayConfigSelector, isPaypalEnabledSelector -} from "../../../../store/reducers/backendStatus"; +} from "../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../store/reducers/types"; import { paymentMethodListVisibleInWalletSelector } from "../../../../store/reducers/wallet/wallets"; import { PaymentMethod } from "../../../../types/pagopa"; diff --git a/ts/features/wallet/component/features/PaymentMethodFeatures.tsx b/ts/features/wallet/component/features/PaymentMethodFeatures.tsx index c8942581e7f..f979f76d0da 100644 --- a/ts/features/wallet/component/features/PaymentMethodFeatures.tsx +++ b/ts/features/wallet/component/features/PaymentMethodFeatures.tsx @@ -4,7 +4,7 @@ import { pipe } from "fp-ts/lib/function"; import * as React from "react"; import I18n from "../../../../i18n"; -import { isIdPayEnabledSelector } from "../../../../store/reducers/backendStatus"; +import { isIdPayEnabledSelector } from "../../../../store/reducers/backendStatus/remoteConfig"; import { PaymentMethod } from "../../../../types/pagopa"; import { isPaymentMethodExpired } from "../../../../utils/paymentMethod"; diff --git a/ts/features/wallet/creditCard/screen/__tests__/CreditCardDetailScreen.test.tsx b/ts/features/wallet/creditCard/screen/__tests__/CreditCardDetailScreen.test.tsx index f7898d87a47..922b1835953 100644 --- a/ts/features/wallet/creditCard/screen/__tests__/CreditCardDetailScreen.test.tsx +++ b/ts/features/wallet/creditCard/screen/__tests__/CreditCardDetailScreen.test.tsx @@ -58,7 +58,7 @@ const initiativesFromInstrumentMock = jest ) .mockImplementation(() => [mockInitiative]); const isIDPayEnabledMock = jest.spyOn( - require("../../../../../store/reducers/backendStatus"), + require("../../../../../store/reducers/backendStatus/remoteConfig"), "isIdPayEnabledSelector" ); @@ -165,13 +165,10 @@ describe("Test CreditCardDetailScreen", () => { ); }); -const renderDetailScreen = ( - store: Store, - creditCard: CreditCardPaymentMethod -) => +const renderDetailScreen = (store: Store, card: CreditCardPaymentMethod) => renderScreenWithNavigationStoreContext( CreditCardDetailScreen, ROUTES.WALLET_CREDIT_CARD_DETAIL, - { creditCard }, + { creditCard: card }, store ); diff --git a/ts/features/wallet/onboarding/common/searchBank/SearchBankScreen.tsx b/ts/features/wallet/onboarding/common/searchBank/SearchBankScreen.tsx index c18d8f9612f..70704e70379 100644 --- a/ts/features/wallet/onboarding/common/searchBank/SearchBankScreen.tsx +++ b/ts/features/wallet/onboarding/common/searchBank/SearchBankScreen.tsx @@ -16,7 +16,7 @@ import BaseScreenComponent from "../../../../../components/screens/BaseScreenCom import { fetchPagoPaTimeout } from "../../../../../config"; import I18n from "../../../../../i18n"; import { navigateBack } from "../../../../../store/actions/navigation"; -import { SectionStatusKey } from "../../../../../store/reducers/backendStatus"; +import { SectionStatusKey } from "../../../../../store/reducers/backendStatus/sectionStatus"; import { GlobalState } from "../../../../../store/reducers/types"; import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; import { loadAbi } from "../../bancomat/store/actions"; diff --git a/ts/features/wallet/onboarding/common/searchBank/SearchStartScreen.tsx b/ts/features/wallet/onboarding/common/searchBank/SearchStartScreen.tsx index 4ae290d4269..ecf0c0d03f6 100644 --- a/ts/features/wallet/onboarding/common/searchBank/SearchStartScreen.tsx +++ b/ts/features/wallet/onboarding/common/searchBank/SearchStartScreen.tsx @@ -8,7 +8,7 @@ import SectionStatusComponent from "../../../../../components/SectionStatus"; import { IOStyles } from "../../../../../components/core/variables/IOStyles"; import BaseScreenComponent from "../../../../../components/screens/BaseScreenComponent"; import I18n from "../../../../../i18n"; -import { SectionStatusKey } from "../../../../../store/reducers/backendStatus"; +import { SectionStatusKey } from "../../../../../store/reducers/backendStatus/sectionStatus"; import { GlobalState } from "../../../../../store/reducers/types"; import { WithTestID } from "../../../../../types/WithTestID"; import { emptyContextualHelp } from "../../../../../utils/emptyContextualHelp"; diff --git a/ts/hooks/useCreatePin.tsx b/ts/hooks/useCreatePin.tsx index e214757f101..d56cfc4451f 100644 --- a/ts/hooks/useCreatePin.tsx +++ b/ts/hooks/useCreatePin.tsx @@ -4,7 +4,7 @@ import { AccessibilityInfo, Platform } from "react-native"; import I18n from "../i18n"; import { createPinSuccess } from "../store/actions/pinset"; import { useIODispatch, useIOSelector } from "../store/hooks"; -import { assistanceToolConfigSelector } from "../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../store/reducers/backendStatus/remoteConfig"; import { PinString } from "../types/PinString"; import { setPin } from "../utils/keychain"; import { diff --git a/ts/hooks/useStartSupportRequest.ts b/ts/hooks/useStartSupportRequest.ts index b9e7a41a0a0..81dfe163e24 100644 --- a/ts/hooks/useStartSupportRequest.ts +++ b/ts/hooks/useStartSupportRequest.ts @@ -7,7 +7,7 @@ import { } from "../components/screens/BaseScreenComponent"; import { zendeskSupportStart } from "../features/zendesk/store/actions"; import { useIODispatch, useIOSelector } from "../store/hooks"; -import { assistanceToolConfigSelector } from "../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../store/reducers/backendStatus/remoteConfig"; import { FAQsCategoriesType } from "../utils/faq"; import { assistanceToolRemoteConfig, diff --git a/ts/hooks/useStatusAlertProps.ts b/ts/hooks/useStatusAlertProps.ts index 60c1005df06..c5c652a27e4 100644 --- a/ts/hooks/useStatusAlertProps.ts +++ b/ts/hooks/useStatusAlertProps.ts @@ -1,7 +1,7 @@ import { AlertEdgeToEdgeProps } from "@pagopa/io-app-design-system"; import { useMemo } from "react"; import { useIOSelector } from "../store/hooks"; -import { statusMessageByRouteSelector } from "../store/reducers/backendStatus"; +import { statusMessageByRouteSelector } from "../store/reducers/backendStatus/statusMessages"; import { getFullLocale } from "../utils/locale"; import { LevelEnum } from "../../definitions/content/StatusMessage"; diff --git a/ts/navigation/AppStackNavigator.tsx b/ts/navigation/AppStackNavigator.tsx index 11b67e829e4..2f40941b659 100644 --- a/ts/navigation/AppStackNavigator.tsx +++ b/ts/navigation/AppStackNavigator.tsx @@ -22,7 +22,7 @@ import { trackScreen } from "../store/middlewares/navigation"; import { isCGNEnabledSelector, isNewPaymentSectionEnabledSelector -} from "../store/reducers/backendStatus"; +} from "../store/reducers/backendStatus/remoteConfig"; import { StartupStatusEnum, isStartupLoaded } from "../store/reducers/startup"; import { IONavigationDarkTheme, diff --git a/ts/navigation/AuthenticatedStackNavigator.tsx b/ts/navigation/AuthenticatedStackNavigator.tsx index b7828900aa8..7c8d0c52e0a 100644 --- a/ts/navigation/AuthenticatedStackNavigator.tsx +++ b/ts/navigation/AuthenticatedStackNavigator.tsx @@ -60,7 +60,7 @@ import { isCGNEnabledSelector, isFciEnabledSelector, isIdPayEnabledSelector -} from "../store/reducers/backendStatus"; +} from "../store/reducers/backendStatus/remoteConfig"; import { isGestureEnabled } from "../utils/navigation"; import { ItwStackNavigator } from "../features/itwallet/navigation/ItwStackNavigator"; import { ITW_ROUTES } from "../features/itwallet/navigation/routes"; diff --git a/ts/navigation/ProfileNavigator.tsx b/ts/navigation/ProfileNavigator.tsx index 6fbbb897d5a..8b6762c1916 100644 --- a/ts/navigation/ProfileNavigator.tsx +++ b/ts/navigation/ProfileNavigator.tsx @@ -31,7 +31,7 @@ import { isGestureEnabled } from "../utils/navigation"; import TrialSystemPlayground from "../screens/profile/TrialSystemPlayground"; import ProfileMainScreen from "../screens/profile/ProfileMainScreen"; import { useIOSelector } from "../store/hooks"; -import { isSettingsVisibleAndHideProfileSelector } from "../store/reducers/backendStatus"; +import { isSettingsVisibleAndHideProfileSelector } from "../store/reducers/backendStatus/remoteConfig"; import { IOMarkdownPlayground } from "../screens/profile/playgrounds/IOMarkdownPlayground"; import { ProfileParamsList } from "./params/ProfileParamsList"; import ROUTES from "./routes"; diff --git a/ts/navigation/TabNavigator.tsx b/ts/navigation/TabNavigator.tsx index 6a49c30d748..cbbf416ad4f 100644 --- a/ts/navigation/TabNavigator.tsx +++ b/ts/navigation/TabNavigator.tsx @@ -18,7 +18,7 @@ import { useIOSelector } from "../store/hooks"; import { isNewPaymentSectionEnabledSelector, isSettingsVisibleAndHideProfileSelector -} from "../store/reducers/backendStatus"; +} from "../store/reducers/backendStatus/remoteConfig"; import { isDesignSystemEnabledSelector } from "../store/reducers/persistedPreferences"; import { StartupStatusEnum, isStartupLoaded } from "../store/reducers/startup"; import { HeaderFirstLevelHandler } from "./components/HeaderFirstLevelHandler"; diff --git a/ts/navigation/components/HeaderFirstLevelHandler.tsx b/ts/navigation/components/HeaderFirstLevelHandler.tsx index ded1a28db05..2c14fc6ff02 100644 --- a/ts/navigation/components/HeaderFirstLevelHandler.tsx +++ b/ts/navigation/components/HeaderFirstLevelHandler.tsx @@ -21,7 +21,7 @@ import { useIONavigation } from "../params/AppParamsList"; import { isNewPaymentSectionEnabledSelector, isSettingsVisibleAndHideProfileSelector -} from "../../store/reducers/backendStatus"; +} from "../../store/reducers/backendStatus/remoteConfig"; import * as analytics from "../../features/services/common/analytics"; import { isArchivingInProcessingModeSelector, diff --git a/ts/sagas/__tests__/initializeApplicationSaga.test.ts b/ts/sagas/__tests__/initializeApplicationSaga.test.ts index 82ac0f99ae2..c775e4d947e 100644 --- a/ts/sagas/__tests__/initializeApplicationSaga.test.ts +++ b/ts/sagas/__tests__/initializeApplicationSaga.test.ts @@ -38,7 +38,7 @@ import { import { lollipopPublicKeySelector } from "../../features/lollipop/store/reducers/lollipop"; import { isFastLoginEnabledSelector } from "../../features/fastLogin/store/selectors"; import { refreshSessionToken } from "../../features/fastLogin/store/actions/tokenRefreshActions"; -import { backendStatusSelector } from "../../store/reducers/backendStatus"; +import { remoteConfigSelector } from "../../store/reducers/backendStatus/remoteConfig"; import { watchLogoutSaga } from "../startup/watchLogoutSaga"; import { cancellAllLocalNotifications } from "../../features/pushNotifications/utils"; import { handleApplicationStartupTransientError } from "../../features/startup/sagas"; @@ -115,7 +115,7 @@ describe("initializeApplicationSaga", () => { .next(generateLollipopKeySaga) .call(checkPublicKeyAndBlockIfNeeded) // is device unsupported? .next(false) // the device is supported - .select(backendStatusSelector) + .select(remoteConfigSelector) .next(O.some({})) .select(sessionTokenSelector) .next(aSessionToken) @@ -170,7 +170,7 @@ describe("initializeApplicationSaga", () => { .next(generateLollipopKeySaga) .call(checkPublicKeyAndBlockIfNeeded) // is device unsupported? .next(false) // the device is supported - .select(backendStatusSelector) + .select(remoteConfigSelector) .next(O.some({})) .select(sessionTokenSelector) .next(aSessionToken) @@ -219,7 +219,7 @@ describe("initializeApplicationSaga", () => { .next(generateLollipopKeySaga) .call(checkPublicKeyAndBlockIfNeeded) // is device unsupported? .next(false) // the device is supported - .select(backendStatusSelector) + .select(remoteConfigSelector) .next(O.some({})) .select(sessionTokenSelector) .next(aSessionToken) @@ -273,7 +273,7 @@ describe("initializeApplicationSaga", () => { .next(generateLollipopKeySaga) .call(checkPublicKeyAndBlockIfNeeded) // is device unsupported? .next(false) // the device is supported - .select(backendStatusSelector) + .select(remoteConfigSelector) .next(O.some({})) .select(sessionTokenSelector) .next(aSessionToken) @@ -338,7 +338,7 @@ describe("initializeApplicationSaga", () => { .next(generateLollipopKeySaga) .call(checkPublicKeyAndBlockIfNeeded) // is device unsupported? .next(false) // the device is supported - .select(backendStatusSelector) + .select(remoteConfigSelector) .next(O.some({})) .select(sessionTokenSelector) .next(aSessionToken) @@ -392,7 +392,7 @@ describe("initializeApplicationSaga", () => { .next(generateLollipopKeySaga) .call(checkPublicKeyAndBlockIfNeeded) // is device unsupported? .next(false) // the device is supported - .select(backendStatusSelector) + .select(remoteConfigSelector) .next(O.some({})) .select(sessionTokenSelector) .next(aSessionToken) diff --git a/ts/sagas/backendStatus.ts b/ts/sagas/backendStatus.ts index 44adf734179..bc48f9b84ff 100644 --- a/ts/sagas/backendStatus.ts +++ b/ts/sagas/backendStatus.ts @@ -7,7 +7,10 @@ import { call, fork, put, select } from "typed-redux-saga/macro"; import { CdnBackendStatusClient } from "../api/backendPublic"; import { contentRepoUrl } from "../config"; import { backendStatusLoadSuccess } from "../store/actions/backendStatus"; -import { backendServicesStatusSelector } from "../store/reducers/backendStatus"; +import { + deadsCounterSelector, + isBackendServicesStatusOffSelector +} from "../store/reducers/backendStatus/backendInfo"; import { ReduxSagaEffect, SagaCallReturnType } from "../types/utils"; import { startTimer } from "../utils/timer"; @@ -49,23 +52,28 @@ export function* backendStatusWatcherLoop( backendStatusSaga, getStatus ); - const currentState: ReturnType = - yield* select(backendServicesStatusSelector); // if we have no information increase rate if (response === false) { yield* call(startTimer, BACKEND_SERVICES_STATUS_FAILURE_INTERVAL); continue; } + + const areSystemsDead = yield* select(isBackendServicesStatusOffSelector); + // if backend is off increase rate - if (currentState.areSystemsDead) { + if (areSystemsDead) { yield* call(startTimer, BACKEND_SERVICES_STATUS_FAILURE_INTERVAL); continue; } + const deadsCounter: ReturnType = yield* select( + deadsCounterSelector + ); + // if counter of dead > 0 but areSystem if false (must do other check to valid this information) // we change the sleep timeout (more frequent when dead is detected) const sleepTime = - currentState.deadsCounter > 0 && currentState.areSystemsDead === false + deadsCounter > 0 && areSystemsDead === false ? BACKEND_SERVICES_STATUS_FAILURE_INTERVAL : BACKEND_SERVICES_STATUS_LOAD_INTERVAL; yield* call(startTimer, sleepTime); diff --git a/ts/sagas/profile.ts b/ts/sagas/profile.ts index ade55051623..dcf46df4e0f 100644 --- a/ts/sagas/profile.ts +++ b/ts/sagas/profile.ts @@ -36,7 +36,7 @@ import { startEmailValidation } from "../store/actions/profile"; import { upsertUserDataProcessing } from "../store/actions/userDataProcessing"; -import { isCGNEnabledSelector } from "../store/reducers/backendStatus"; +import { isCGNEnabledSelector } from "../store/reducers/backendStatus/remoteConfig"; import { isDifferentFiscalCodeSelector } from "../store/reducers/crossSessions"; import { profileSelector } from "../store/reducers/profile"; import { ProfileError } from "../store/reducers/profileErrorType"; diff --git a/ts/sagas/startup.ts b/ts/sagas/startup.ts index 3eb8a03004a..a829f84424a 100644 --- a/ts/sagas/startup.ts +++ b/ts/sagas/startup.ts @@ -79,10 +79,10 @@ import { sessionTokenSelector } from "../store/reducers/authentication"; import { - backendStatusSelector, + remoteConfigSelector, isPnEnabledSelector, isSettingsVisibleAndHideProfileSelector -} from "../store/reducers/backendStatus"; +} from "../store/reducers/backendStatus/remoteConfig"; import { IdentificationResult } from "../store/reducers/identification"; import { isIdPayTestEnabledSelector, @@ -241,8 +241,8 @@ export function* initializeApplicationSaga( // Since the backend.json is done in parallel with the startup saga, // we need to synchronize the two tasks, to be sure to have loaded the remote FF // before using them. - const backendStatus = yield* select(backendStatusSelector); - if (O.isNone(backendStatus)) { + const remoteConfig = yield* select(remoteConfigSelector); + if (O.isNone(remoteConfig)) { yield* take(backendStatusLoadSuccess); } diff --git a/ts/sagas/wallet/pagopaApis.ts b/ts/sagas/wallet/pagopaApis.ts index f273f43833f..65c16d02463 100644 --- a/ts/sagas/wallet/pagopaApis.ts +++ b/ts/sagas/wallet/pagopaApis.ts @@ -46,7 +46,7 @@ import { setFavouriteWalletSuccess, updatePaymentStatus } from "../../store/actions/wallet/wallets"; -import { preferredPspsByOriginSelector } from "../../store/reducers/backendStatus"; +import { preferredPspsByOriginSelector } from "../../store/reducers/backendStatus/remoteConfig"; import { isPagoPATestEnabledSelector } from "../../store/reducers/persistedPreferences"; import { paymentStartOriginSelector } from "../../store/reducers/wallet/payment"; import { PaymentManagerToken, Wallet } from "../../types/pagopa"; diff --git a/ts/screens/authentication/IdpLoginScreen.tsx b/ts/screens/authentication/IdpLoginScreen.tsx index d1bca6f5bff..9e297ceaea1 100644 --- a/ts/screens/authentication/IdpLoginScreen.tsx +++ b/ts/screens/authentication/IdpLoginScreen.tsx @@ -36,7 +36,7 @@ import { loggedOutWithIdpAuthSelector, selectedIdentityProviderSelector } from "../../store/reducers/authentication"; -import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus/remoteConfig"; import { idpContextualHelpDataFromIdSelector } from "../../store/reducers/content"; import { SessionToken } from "../../types/SessionToken"; import { trackSpidLoginError } from "../../utils/analytics"; diff --git a/ts/screens/authentication/IdpSelectionScreen.tsx b/ts/screens/authentication/IdpSelectionScreen.tsx index c93f63aacf7..cf44b6c6e5e 100644 --- a/ts/screens/authentication/IdpSelectionScreen.tsx +++ b/ts/screens/authentication/IdpSelectionScreen.tsx @@ -17,7 +17,7 @@ import { idpsRemoteValueSelector } from "../../store/reducers/content"; import { SpidIdp } from "../../../definitions/content/SpidIdp"; import { idps as idpsFallback, LocalIdpsFallback } from "../../utils/idps"; import { loadIdps } from "../../store/actions/content"; -import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus/remoteConfig"; import { assistanceToolRemoteConfig, handleSendAssistanceLog diff --git a/ts/screens/authentication/cie/CieCardReaderScreen.tsx b/ts/screens/authentication/cie/CieCardReaderScreen.tsx index 543762bb817..a25ed2d44d7 100644 --- a/ts/screens/authentication/cie/CieCardReaderScreen.tsx +++ b/ts/screens/authentication/cie/CieCardReaderScreen.tsx @@ -46,7 +46,7 @@ import { cieAuthenticationError } from "../../../store/actions/cie"; import { ReduxProps } from "../../../store/actions/types"; -import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../store/reducers/types"; import { isScreenReaderEnabled, diff --git a/ts/screens/authentication/idpAuthSessionHandler.tsx b/ts/screens/authentication/idpAuthSessionHandler.tsx index 6aa8a5e07a6..e6bca89ae4d 100644 --- a/ts/screens/authentication/idpAuthSessionHandler.tsx +++ b/ts/screens/authentication/idpAuthSessionHandler.tsx @@ -42,7 +42,7 @@ import { } from "../../store/actions/authentication"; import { useIODispatch, useIOSelector, useIOStore } from "../../store/hooks"; import { selectedIdentityProviderSelector } from "../../store/reducers/authentication"; -import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus/remoteConfig"; import { idpContextualHelpDataFromIdSelector } from "../../store/reducers/content"; import { isMixpanelEnabled } from "../../store/reducers/persistedPreferences"; import themeVariables from "../../theme/variables"; diff --git a/ts/screens/modal/RootModal.tsx b/ts/screens/modal/RootModal.tsx index 4c6becc3785..c3279418f44 100644 --- a/ts/screens/modal/RootModal.tsx +++ b/ts/screens/modal/RootModal.tsx @@ -7,7 +7,7 @@ import { import UnsupportedDeviceScreen from "../../features/lollipop/screens/UnsupportedDeviceScreen"; import { isDeviceSupportedSelector } from "../../features/lollipop/store/reducers/lollipop"; import { mixpanelTrack } from "../../mixpanel"; -import { isBackendServicesStatusOffSelector } from "../../store/reducers/backendStatus"; +import { isBackendServicesStatusOffSelector } from "../../store/reducers/backendStatus/backendInfo"; import { isFastLoginUserInteractionNeededForSessionExpiredSelector, tokenRefreshSelector diff --git a/ts/screens/modal/SystemOffModal.tsx b/ts/screens/modal/SystemOffModal.tsx index 16f0d9ca1ef..ce632503abf 100644 --- a/ts/screens/modal/SystemOffModal.tsx +++ b/ts/screens/modal/SystemOffModal.tsx @@ -3,32 +3,23 @@ * not work properly. This is due to avoid user tries to access features or services potentially can't work * as expected */ -import { NonEmptyString } from "@pagopa/ts-commons/lib/strings"; -import * as O from "fp-ts/lib/Option"; -import { pipe } from "fp-ts/lib/function"; import * as React from "react"; import { Modal } from "react-native"; import { useSelector } from "react-redux"; import _ from "lodash"; import { OperationResultScreenContent } from "../../components/screens/OperationResultScreenContent"; import I18n from "../../i18n"; -import { backendStatusSelector } from "../../store/reducers/backendStatus"; +import { backendInfoMessageSelector } from "../../store/reducers/backendStatus/backendInfo"; import { getFullLocale } from "../../utils/locale"; const SystemOffModal = () => { - const backendStatus = useSelector(backendStatusSelector, _.isEqual); + const backendInfoMessage = useSelector(backendInfoMessageSelector, _.isEqual); const locale = getFullLocale(); const subtitle = React.useMemo(() => { - const message = pipe( - backendStatus, - O.fold( - () => undefined, - s => pipe(s, NonEmptyString.decode, () => s.message[locale]) - ) - ); + const message = backendInfoMessage && backendInfoMessage[locale]; return `${message ? message + "\n" : ""}${I18n.t("systemsOff.closeApp")}`; - }, [locale, backendStatus]); + }, [locale, backendInfoMessage]); return ( diff --git a/ts/screens/onboarding/__tests__/OnboardingTosScreen.test.tsx b/ts/screens/onboarding/__tests__/OnboardingTosScreen.test.tsx index d0ec0d22122..a8516f213fa 100644 --- a/ts/screens/onboarding/__tests__/OnboardingTosScreen.test.tsx +++ b/ts/screens/onboarding/__tests__/OnboardingTosScreen.test.tsx @@ -315,40 +315,35 @@ const commonSetup = ({ : pot.some(testProfile); const testState = { ...globalState, - backendStatus: { - ...globalState.backendStatus, - status: O.some({ - config: { - assistanceTool: { - tool: ToolEnum.zendesk - }, - cgn: { - enabled: false - }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { - enabled: false - }, - tos: { - tos_version: CurrentTestToSVersion, - tos_url: "https://www.example.com" - }, - itw: { - enabled: true, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - } + remoteConfig: O.some({ + assistanceTool: { + tool: ToolEnum.zendesk + }, + cgn: { + enabled: false + }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" } - }) - }, + }, + fims: { + enabled: false + }, + tos: { + tos_version: CurrentTestToSVersion, + tos_url: "https://www.example.com" + }, + itw: { + enabled: true, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + } + }), profile: testProfilePot } as GlobalState; diff --git a/ts/screens/onboarding/biometric&securityChecks/FingerprintScreen.tsx b/ts/screens/onboarding/biometric&securityChecks/FingerprintScreen.tsx index 238f0bb88af..f6a8bd9895d 100644 --- a/ts/screens/onboarding/biometric&securityChecks/FingerprintScreen.tsx +++ b/ts/screens/onboarding/biometric&securityChecks/FingerprintScreen.tsx @@ -17,7 +17,7 @@ import { FAQsCategoriesType } from "../../../utils/faq"; import { IOScrollView } from "../../../components/ui/IOScrollView"; import { useOnboardingAbortAlert } from "../../../utils/hooks/useOnboardingAbortAlert"; import useContentWithFF from "../../profile/useContentWithFF"; -import { isSettingsVisibleAndHideProfileSelector } from "../../../store/reducers/backendStatus"; +import { isSettingsVisibleAndHideProfileSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { trackBiometricActivationAccepted, trackBiometricActivationDeclined, diff --git a/ts/screens/onboarding/biometric&securityChecks/MissingDeviceBiometricScreen.tsx b/ts/screens/onboarding/biometric&securityChecks/MissingDeviceBiometricScreen.tsx index 3541420415a..4c22448c4d2 100644 --- a/ts/screens/onboarding/biometric&securityChecks/MissingDeviceBiometricScreen.tsx +++ b/ts/screens/onboarding/biometric&securityChecks/MissingDeviceBiometricScreen.tsx @@ -5,7 +5,7 @@ import { useHeaderSecondLevel } from "../../../hooks/useHeaderSecondLevel"; import I18n from "../../../i18n"; import { preferenceFingerprintIsEnabledSaveSuccess } from "../../../store/actions/persistedPreferences"; import { useIODispatch, useIOSelector } from "../../../store/hooks"; -import { isSettingsVisibleAndHideProfileSelector } from "../../../store/reducers/backendStatus"; +import { isSettingsVisibleAndHideProfileSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { isProfileFirstOnBoardingSelector } from "../../../store/reducers/profile"; import { getFlowType } from "../../../utils/analytics"; import { FAQsCategoriesType } from "../../../utils/faq"; diff --git a/ts/screens/onboarding/biometric&securityChecks/MissingDevicePinScreen.tsx b/ts/screens/onboarding/biometric&securityChecks/MissingDevicePinScreen.tsx index 183213c2c9f..febf37b0258 100644 --- a/ts/screens/onboarding/biometric&securityChecks/MissingDevicePinScreen.tsx +++ b/ts/screens/onboarding/biometric&securityChecks/MissingDevicePinScreen.tsx @@ -11,7 +11,7 @@ import { useOnFirstRender } from "../../../utils/hooks/useOnFirstRender"; import { useOnboardingAbortAlert } from "../../../utils/hooks/useOnboardingAbortAlert"; import { useHeaderSecondLevel } from "../../../hooks/useHeaderSecondLevel"; import { FAQsCategoriesType } from "../../../utils/faq"; -import { isSettingsVisibleAndHideProfileSelector } from "../../../store/reducers/backendStatus"; +import { isSettingsVisibleAndHideProfileSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { IOScrollViewWithListItems } from "../../../components/ui/IOScrollViewWithListItems"; import { IOScrollViewActions } from "../../../components/ui/IOScrollView"; import { trackPinEducationalScreen } from "./analytics"; diff --git a/ts/screens/profile/LanguagesPreferencesScreen.tsx b/ts/screens/profile/LanguagesPreferencesScreen.tsx index d2a70952feb..abed062a006 100644 --- a/ts/screens/profile/LanguagesPreferencesScreen.tsx +++ b/ts/screens/profile/LanguagesPreferencesScreen.tsx @@ -35,7 +35,7 @@ import { preferredLanguageSaveSuccess } from "../../store/actions/persistedPrefe import LoadingSpinnerOverlay from "../../components/LoadingSpinnerOverlay"; import { openWebUrl } from "../../utils/url"; import { IOScrollViewWithLargeHeader } from "../../components/ui/IOScrollViewWithLargeHeader"; -import { sectionStatusSelector } from "../../store/reducers/backendStatus"; +import { sectionStatusByKeySelector } from "../../store/reducers/backendStatus/sectionStatus"; import { LightModalContext } from "../../components/ui/LightModal"; import { AlertModal } from "../../components/ui/AlertModal"; @@ -58,7 +58,7 @@ const LanguagesPreferencesScreen = () => { const profile = useIOSelector(profileSelector, _.isEqual); const prevProfile = usePrevious(profile); const bannerInfoSelector = useIOSelector( - sectionStatusSelector("favourite_language") + sectionStatusByKeySelector("favourite_language") ); const isBannerVisible = bannerInfoSelector && bannerInfoSelector.is_visible; const preferredLanguageSelect = useIOSelector( diff --git a/ts/screens/profile/ProfileMainScreen.tsx b/ts/screens/profile/ProfileMainScreen.tsx index 46239c25e83..0936b18eeef 100644 --- a/ts/screens/profile/ProfileMainScreen.tsx +++ b/ts/screens/profile/ProfileMainScreen.tsx @@ -28,7 +28,7 @@ import { useIONavigation } from "../../navigation/params/AppParamsList"; import ROUTES from "../../navigation/routes"; import { setDebugModeEnabled } from "../../store/actions/debug"; import { useIODispatch, useIOSelector } from "../../store/hooks"; -import { isSettingsVisibleAndHideProfileSelector } from "../../store/reducers/backendStatus"; +import { isSettingsVisibleAndHideProfileSelector } from "../../store/reducers/backendStatus/remoteConfig"; import { isDebugModeEnabledSelector } from "../../store/reducers/debug"; import { isDevEnv } from "../../utils/environment"; import DeveloperModeSection from "./DeveloperModeSection"; diff --git a/ts/screens/profile/SecurityScreen.tsx b/ts/screens/profile/SecurityScreen.tsx index d58d0991e57..0069cfeefb3 100644 --- a/ts/screens/profile/SecurityScreen.tsx +++ b/ts/screens/profile/SecurityScreen.tsx @@ -17,7 +17,7 @@ import ROUTES from "../../navigation/routes"; import { identificationRequest } from "../../store/actions/identification"; import { preferenceFingerprintIsEnabledSaveSuccess } from "../../store/actions/persistedPreferences"; import { useIODispatch, useIOSelector } from "../../store/hooks"; -import { isIdPayEnabledSelector } from "../../store/reducers/backendStatus"; +import { isIdPayEnabledSelector } from "../../store/reducers/backendStatus/remoteConfig"; import { isFingerprintEnabledSelector } from "../../store/reducers/persistedPreferences"; import { getFlowType } from "../../utils/analytics"; import { diff --git a/ts/screens/profile/__test__/TosScreen.test.tsx b/ts/screens/profile/__test__/TosScreen.test.tsx index 13e525f07b1..0e3e91343b5 100644 --- a/ts/screens/profile/__test__/TosScreen.test.tsx +++ b/ts/screens/profile/__test__/TosScreen.test.tsx @@ -176,40 +176,35 @@ const commonSetup = () => { }; const testState = { ...globalState, - backendStatus: { - ...globalState.backendStatus, - status: O.some({ - config: { - assistanceTool: { - tool: ToolEnum.zendesk - }, - cgn: { - enabled: false - }, - newPaymentSection: { - enabled: false, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - }, - fims: { - enabled: false - }, - tos: { - tos_version: 3.2, - tos_url: "https://www.example.com" - }, - itw: { - enabled: true, - min_app_version: { - android: "0.0.0.0", - ios: "0.0.0.0" - } - } + remoteConfig: O.some({ + assistanceTool: { + tool: ToolEnum.zendesk + }, + cgn: { + enabled: false + }, + newPaymentSection: { + enabled: false, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" } - }) - }, + }, + fims: { + enabled: false + }, + tos: { + tos_version: 3.2, + tos_url: "https://www.example.com" + }, + itw: { + enabled: true, + min_app_version: { + android: "0.0.0.0", + ios: "0.0.0.0" + } + } + }), profile: pot.some(testProfile) } as GlobalState; diff --git a/ts/screens/profile/useContentWithFF.tsx b/ts/screens/profile/useContentWithFF.tsx index 7e4e44470bc..d436ae0d9ce 100644 --- a/ts/screens/profile/useContentWithFF.tsx +++ b/ts/screens/profile/useContentWithFF.tsx @@ -3,7 +3,7 @@ import _ from "lodash"; import { TranslationKeys } from "../../../locales/locales"; import I18n from "../../i18n"; import { useIOSelector } from "../../store/hooks"; -import { isSettingsVisibleAndHideProfileSelector } from "../../store/reducers/backendStatus"; +import { isSettingsVisibleAndHideProfileSelector } from "../../store/reducers/backendStatus/remoteConfig"; /** * diff --git a/ts/screens/wallet/AddPaymentMethodScreen.tsx b/ts/screens/wallet/AddPaymentMethodScreen.tsx index 1c56df0bcb7..ea295e9b714 100644 --- a/ts/screens/wallet/AddPaymentMethodScreen.tsx +++ b/ts/screens/wallet/AddPaymentMethodScreen.tsx @@ -34,7 +34,7 @@ import { Dispatch } from "../../store/actions/types"; import { bancomatPayConfigSelector, isPaypalEnabledSelector -} from "../../store/reducers/backendStatus"; +} from "../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../store/reducers/types"; import { paypalSelector } from "../../store/reducers/wallet/wallets"; import { AsyncAlert } from "../../utils/asyncAlert"; diff --git a/ts/screens/wallet/PaymentHistoryDetailsScreen.tsx b/ts/screens/wallet/PaymentHistoryDetailsScreen.tsx index dcf6a8c9b24..58a5f86160e 100644 --- a/ts/screens/wallet/PaymentHistoryDetailsScreen.tsx +++ b/ts/screens/wallet/PaymentHistoryDetailsScreen.tsx @@ -33,7 +33,7 @@ import { import { WalletParamsList } from "../../navigation/params/WalletParamsList"; import { Dispatch } from "../../store/actions/types"; import { canShowHelpSelector } from "../../store/reducers/assistanceTools"; -import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../store/reducers/backendStatus/remoteConfig"; import { PaymentHistory } from "../../store/reducers/payments/history"; import { isPaymentDoneSuccessfully } from "../../store/reducers/payments/utils"; import { GlobalState } from "../../store/reducers/types"; diff --git a/ts/screens/wallet/WalletHomeScreen.tsx b/ts/screens/wallet/WalletHomeScreen.tsx index 9e9f6f15765..a2832130d19 100644 --- a/ts/screens/wallet/WalletHomeScreen.tsx +++ b/ts/screens/wallet/WalletHomeScreen.tsx @@ -73,7 +73,7 @@ import { import { isCGNEnabledSelector, isIdPayEnabledSelector -} from "../../store/reducers/backendStatus"; +} from "../../store/reducers/backendStatus/remoteConfig"; import { paymentsHistorySelector } from "../../store/reducers/payments/history"; import { isPagoPATestEnabledSelector } from "../../store/reducers/persistedPreferences"; import { GlobalState } from "../../store/reducers/types"; diff --git a/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptDetailScreen.tsx b/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptDetailScreen.tsx index e2c28d87516..66ad844aa87 100644 --- a/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptDetailScreen.tsx +++ b/ts/screens/wallet/creditCardOnboardingAttempts/CreditCardOnboardingAttemptDetailScreen.tsx @@ -20,7 +20,7 @@ import I18n from "../../../i18n"; import { useIONavigation } from "../../../navigation/params/AppParamsList"; import { useIODispatch, useIOSelector } from "../../../store/hooks"; import { canShowHelpSelector } from "../../../store/reducers/assistanceTools"; -import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { CreditCardInsertion } from "../../../store/reducers/wallet/creditCard"; import { outcomeCodesSelector } from "../../../store/reducers/wallet/outcomeCode"; import customVariables from "../../../theme/variables"; diff --git a/ts/screens/wallet/payment/ConfirmPaymentMethodScreen.tsx b/ts/screens/wallet/payment/ConfirmPaymentMethodScreen.tsx index a260c127b6f..ff6a3f6c9fd 100644 --- a/ts/screens/wallet/payment/ConfirmPaymentMethodScreen.tsx +++ b/ts/screens/wallet/payment/ConfirmPaymentMethodScreen.tsx @@ -74,7 +74,7 @@ import { fetchTransactionsRequestWithExpBackoff } from "../../../store/actions/w import { bancomatPayConfigSelector, isPaypalEnabledSelector -} from "../../../store/reducers/backendStatus"; +} from "../../../store/reducers/backendStatus/remoteConfig"; import { isPagoPATestEnabledSelector } from "../../../store/reducers/persistedPreferences"; import { GlobalState } from "../../../store/reducers/types"; import { outcomeCodesSelector } from "../../../store/reducers/wallet/outcomeCode"; diff --git a/ts/screens/wallet/payment/PickPaymentMethodScreen.tsx b/ts/screens/wallet/payment/PickPaymentMethodScreen.tsx index 5be94ba608c..5d2964ef869 100644 --- a/ts/screens/wallet/payment/PickPaymentMethodScreen.tsx +++ b/ts/screens/wallet/payment/PickPaymentMethodScreen.tsx @@ -46,7 +46,7 @@ import { Dispatch } from "../../../store/actions/types"; import { bancomatPayConfigSelector, isPaypalEnabledSelector -} from "../../../store/reducers/backendStatus"; +} from "../../../store/reducers/backendStatus/remoteConfig"; import { profileNameSurnameSelector } from "../../../store/reducers/profile"; import { GlobalState } from "../../../store/reducers/types"; import { pspV2ListSelector } from "../../../store/reducers/wallet/payment"; diff --git a/ts/screens/wallet/payment/TransactionErrorScreen.tsx b/ts/screens/wallet/payment/TransactionErrorScreen.tsx index dc8bd483e65..fd728429d23 100644 --- a/ts/screens/wallet/payment/TransactionErrorScreen.tsx +++ b/ts/screens/wallet/payment/TransactionErrorScreen.tsx @@ -42,7 +42,7 @@ import { paymentVerifica } from "../../../store/actions/wallet/payment"; import { canShowHelpSelector } from "../../../store/reducers/assistanceTools"; -import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus"; +import { assistanceToolConfigSelector } from "../../../store/reducers/backendStatus/remoteConfig"; import { PaymentHistory, paymentsHistorySelector diff --git a/ts/screens/wallet/payment/TransactionSummaryScreen.tsx b/ts/screens/wallet/payment/TransactionSummaryScreen.tsx index fcb3d84be16..ff537313e65 100644 --- a/ts/screens/wallet/payment/TransactionSummaryScreen.tsx +++ b/ts/screens/wallet/payment/TransactionSummaryScreen.tsx @@ -43,7 +43,7 @@ import { useIODispatch, useIOSelector } from "../../../store/hooks"; import { bancomatPayConfigSelector, isPaypalEnabledSelector -} from "../../../store/reducers/backendStatus"; +} from "../../../store/reducers/backendStatus/remoteConfig"; import { getFavoriteWallet } from "../../../store/reducers/wallet/wallets"; import { PayloadForAction } from "../../../types/utils"; import { emptyContextualHelp } from "../../../utils/emptyContextualHelp"; diff --git a/ts/screens/wallet/payment/__tests__/ConfirmPaymentMethodScreen.test.tsx b/ts/screens/wallet/payment/__tests__/ConfirmPaymentMethodScreen.test.tsx index d70afceef1e..d29cc73a76b 100644 --- a/ts/screens/wallet/payment/__tests__/ConfirmPaymentMethodScreen.test.tsx +++ b/ts/screens/wallet/payment/__tests__/ConfirmPaymentMethodScreen.test.tsx @@ -8,7 +8,7 @@ import { appReducer } from "../../../../store/reducers/"; import { bancomatPayConfigSelector, isPaypalEnabledSelector -} from "../../../../store/reducers/backendStatus"; +} from "../../../../store/reducers/backendStatus/remoteConfig"; import { GlobalState } from "../../../../store/reducers/types"; import { pspSelectedV2ListSelector } from "../../../../store/reducers/wallet/payment"; import { paymentMethodByIdSelector } from "../../../../store/reducers/wallet/wallets"; @@ -76,9 +76,9 @@ jest.mock("../../../../store/reducers/wallet/payment", () => { }); // Mock feature flags -jest.mock("../../../../store/reducers/backendStatus", () => { +jest.mock("../../../../store/reducers/backendStatus/remoteConfig", () => { const actualModule = jest.requireActual( - "../../../../store/reducers/backendStatus" + "../../../../store/reducers/backendStatus/remoteConfig" ); return { diff --git a/ts/store/reducers/__mock__/backendStatus.ts b/ts/store/reducers/__mock__/backendStatus.ts index 53a5531b51a..83b9a37d7ca 100644 --- a/ts/store/reducers/__mock__/backendStatus.ts +++ b/ts/store/reducers/__mock__/backendStatus.ts @@ -1,10 +1,7 @@ -import { pipe } from "fp-ts/lib/function"; -import * as O from "fp-ts/lib/Option"; import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; import { BackendStatus } from "../../../../definitions/content/BackendStatus"; import { Config } from "../../../../definitions/content/Config"; import { LevelEnum } from "../../../../definitions/content/SectionStatus"; -import { BackendStatusState } from "../backendStatus"; export const baseRawBackendStatus: BackendStatus = { is_alive: true, @@ -308,12 +305,6 @@ export const baseRawBackendStatus: BackendStatus = { } }; -export const baseBackendState: BackendStatusState = { - status: O.some(baseRawBackendStatus), - areSystemsDead: false, - deadsCounter: 0 -}; - export const baseBackendConfig: Config = { premiumMessages: { opt_in_out_enabled: false @@ -401,17 +392,3 @@ export const baseBackendConfig: Config = { } } }; - -export const withBpdRankingConfig = ( - baseState: BackendStatusState, - newConfig: Config -): BackendStatusState => ({ - ...baseState, - status: pipe( - baseState.status, - O.map(s => ({ - ...s, - config: { ...newConfig } - })) - ) -}); diff --git a/ts/store/reducers/__tests__/backendStatus.test.ts b/ts/store/reducers/__tests__/backendStatus.test.ts deleted file mode 100644 index 84b620ba19b..00000000000 --- a/ts/store/reducers/__tests__/backendStatus.test.ts +++ /dev/null @@ -1,211 +0,0 @@ -import * as O from "fp-ts/lib/Option"; -import { BackendStatus } from "../../../../definitions/content/BackendStatus"; -import { baseRawBackendStatus } from "../__mock__/backendStatus"; -import { - areSystemsDeadReducer, - BackendStatusState, - barcodesScannerConfigSelector, - isPnAppVersionSupportedSelector, - isPremiumMessagesOptInOutEnabledSelector -} from "../backendStatus"; -import { GlobalState } from "../types"; -import * as appVersion from "../../../utils/appVersion"; - -describe("backend service status reducer", () => { - // smoke tests: valid / invalid - const responseON: BackendStatus = { - ...baseRawBackendStatus, - is_alive: true, - message: { - "it-IT": "messaggio in italiano", - "en-EN": "english message" - } - }; - - const responseOff: BackendStatus = { - ...baseRawBackendStatus, - is_alive: false, - message: { - "it-IT": "messaggio in italiano", - "en-EN": "english message" - } - }; - - const currentState: BackendStatusState = { - status: O.none, - areSystemsDead: false, - deadsCounter: 0 - }; - - it("should decode the backend status", () => { - const newState = areSystemsDeadReducer(currentState, responseON); - expect(newState.areSystemsDead).toBeFalsy(); - expect(newState.deadsCounter).toEqual(0); - expect(O.isSome(newState.status)).toBeTruthy(); - }); - - it("should return a new state with alive false", () => { - // dead one - const newState = areSystemsDeadReducer(currentState, responseOff); - expect(newState.areSystemsDead).toBeFalsy(); - expect(newState.deadsCounter).toEqual(1); - - // dead two - const newState2 = areSystemsDeadReducer(newState, responseOff); - expect(newState2.areSystemsDead).toBeTruthy(); - expect(newState2.deadsCounter).toEqual(2); - }); - - it("should return a new state with dead counter reset when it processes positive-negative", () => { - // dead one (positive) - const newState = areSystemsDeadReducer(currentState, responseOff); - expect(newState.areSystemsDead).toBeFalsy(); - expect(newState.deadsCounter).toEqual(1); - - // negative - const newState2 = areSystemsDeadReducer(currentState, responseON); - expect(newState2.areSystemsDead).toBeFalsy(); - expect(newState2.deadsCounter).toEqual(0); - }); -}); - -// TODO: refactor using baseBackendState -describe("test selectors", () => { - // smoke tests: valid / invalid - const noneStore = { - backendStatus: { - status: O.none - } - } as any as GlobalState; - - describe("premium messages opt-in/out selectors", () => { - it("should return false if the remote flag is undefined", () => { - const output = isPremiumMessagesOptInOutEnabledSelector(noneStore); - expect(output).toBeFalsy(); - }); - - it("should return false if the remote flag is false", () => { - const customStore = { - backendStatus: { - status: O.some({ - config: { - premiumMessages: { opt_in_out_enabled: false } - } - }) - } - } as unknown as GlobalState; - - const output = isPremiumMessagesOptInOutEnabledSelector(customStore); - - expect(output).toBeFalsy(); - }); - - it("should return true if the remote flag is true", () => { - const customStore = { - backendStatus: { - status: O.some({ - config: { - premiumMessages: { opt_in_out_enabled: true } - } - }) - } - } as unknown as GlobalState; - - const output = isPremiumMessagesOptInOutEnabledSelector(customStore); - - expect(output).toBeTruthy(); - }); - }); - - describe("barcodes scanner remote config selectors", () => { - it("should return an all-false object if the remote flag is undefined", () => { - const output = barcodesScannerConfigSelector(noneStore); - expect(output.dataMatrixPosteEnabled).toBe(false); - }); - - it("should return the correct configuration", () => { - const customStore = { - backendStatus: { - status: O.some({ - config: { - barcodesScanner: { dataMatrixPosteEnabled: true } - } - }) - } - } as unknown as GlobalState; - - const output = barcodesScannerConfigSelector(customStore); - - expect(output.dataMatrixPosteEnabled).toBe(true); - }); - }); -}); - -describe("isPnAppVersionSupportedSelector", () => { - it("should return false, when 'backendStatus' is O.none", () => { - const state = { - backendStatus: { - status: O.none - } - } as GlobalState; - const isSupported = isPnAppVersionSupportedSelector(state); - expect(isSupported).toBe(false); - }); - it("should return false, when min_app_version is greater than `getAppVersion`", () => { - const state = { - backendStatus: { - status: O.some({ - config: { - pn: { - min_app_version: { - android: "2.0.0.0", - ios: "2.0.0.0" - } - } - } - }) - } - } as GlobalState; - jest.spyOn(appVersion, "getAppVersion").mockImplementation(() => "1.0.0.0"); - const isSupported = isPnAppVersionSupportedSelector(state); - expect(isSupported).toBe(false); - }); - it("should return true, when min_app_version is equal to `getAppVersion`", () => { - const state = { - backendStatus: { - status: O.some({ - config: { - pn: { - min_app_version: { - android: "2.0.0.0", - ios: "2.0.0.0" - } - } - } - }) - } - } as GlobalState; - jest.spyOn(appVersion, "getAppVersion").mockImplementation(() => "2.0.0.0"); - const isSupported = isPnAppVersionSupportedSelector(state); - expect(isSupported).toBe(true); - }); - it("should return true, when min_app_version is less than `getAppVersion`", () => { - const state = { - backendStatus: { - status: O.some({ - config: { - pn: { - min_app_version: { - android: "2.0.0.0", - ios: "2.0.0.0" - } - } - } - }) - } - } as GlobalState; - jest.spyOn(appVersion, "getAppVersion").mockImplementation(() => "3.0.0.0"); - const isSupported = isPnAppVersionSupportedSelector(state); - expect(isSupported).toBe(true); - }); -}); diff --git a/ts/store/reducers/__tests__/featureFlagWithMinAppVersionStatus.test.ts b/ts/store/reducers/__tests__/featureFlagWithMinAppVersionStatus.test.ts index 69c94fbc65e..e45d5163aea 100644 --- a/ts/store/reducers/__tests__/featureFlagWithMinAppVersionStatus.test.ts +++ b/ts/store/reducers/__tests__/featureFlagWithMinAppVersionStatus.test.ts @@ -9,12 +9,10 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio const customConfigNativeLogin = ( nativeLoginConfig: object - ): O.Option => + ): O.Option => O.some({ - config: { - nativeLogin: nativeLoginConfig - } - }) as unknown as O.Option; + nativeLogin: nativeLoginConfig + }) as unknown as O.Option; it("should return (nativelogin) enabled --- eq min version & local flag enabled", () => { const store = customConfigNativeLogin({ @@ -22,7 +20,7 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "nativeLogin" }) @@ -35,7 +33,7 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "nativeLogin" }) @@ -48,7 +46,7 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "nativeLogin" }) @@ -61,7 +59,7 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: false, configPropertyName: "nativeLogin" }) @@ -74,7 +72,7 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: false, configPropertyName: "nativeLogin" }) @@ -87,7 +85,7 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: false, configPropertyName: "nativeLogin" }) @@ -98,7 +96,7 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio const store = customConfigNativeLogin({}); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: false, configPropertyName: "nativeLogin" }) @@ -109,7 +107,7 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio const store = customConfigNativeLogin({}); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "nativeLogin" }) @@ -119,10 +117,10 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio it("should return (nativelogin) disabled --- nativelogin undefined & local flag enabled", () => { const store = O.some({ config: {} - }) as unknown as O.Option; + }) as unknown as O.Option; expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "nativeLogin" }) @@ -132,10 +130,10 @@ describe("backend service Feature Flag (nativeLogin example) with min app versio it("should return (nativelogin) disabled --- nativelogin undefined & local flag disabled", () => { const store = O.some({ config: {} - }) as unknown as O.Option; + }) as unknown as O.Option; expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: false, configPropertyName: "nativeLogin" }) @@ -149,12 +147,10 @@ describe("backend service Feature Flag (fastLogin example) with min app version const customConfigFastLogin = ( fastLoginConfig: object - ): O.Option => + ): O.Option => O.some({ - config: { - fastLogin: fastLoginConfig - } - }) as unknown as O.Option; + fastLogin: fastLoginConfig + }) as unknown as O.Option; it("should return (fastlogin) enabled --- eq min version & local flag enabled & optional config undefined", () => { const store = customConfigFastLogin({ @@ -162,7 +158,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin" }) @@ -178,7 +174,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin" }) @@ -194,7 +190,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin" }) @@ -210,7 +206,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin" }) @@ -226,7 +222,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin" }) @@ -242,7 +238,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -260,7 +256,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -278,7 +274,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -296,7 +292,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: false, @@ -314,7 +310,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: false, @@ -332,7 +328,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: false, @@ -350,7 +346,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -368,7 +364,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: false, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -386,7 +382,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -404,7 +400,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: false, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -421,7 +417,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -438,7 +434,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: false, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -456,7 +452,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: false, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -471,7 +467,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -487,7 +483,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: true, @@ -502,7 +498,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: false, @@ -518,7 +514,7 @@ describe("backend service Feature Flag (fastLogin example) with min app version }); expect( isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: true, configPropertyName: "fastLogin", optionalLocalFlag: false, diff --git a/ts/store/reducers/assistanceTools.ts b/ts/store/reducers/assistanceTools.ts index f58e131b0b0..b8af8ca9c5a 100644 --- a/ts/store/reducers/assistanceTools.ts +++ b/ts/store/reducers/assistanceTools.ts @@ -8,7 +8,7 @@ import { assistanceToolRemoteConfig, canShowHelp } from "../../utils/supportAssistance"; -import { assistanceToolConfigSelector } from "./backendStatus"; +import { assistanceToolConfigSelector } from "./backendStatus/remoteConfig"; export type AssistanceToolsState = { zendesk: ZendeskState; diff --git a/ts/store/reducers/backendStatus.ts b/ts/store/reducers/backendStatus.ts deleted file mode 100644 index 6caf01d5a30..00000000000 --- a/ts/store/reducers/backendStatus.ts +++ /dev/null @@ -1,547 +0,0 @@ -/** - * Implements the reducers for BackendServicesState. - */ - -import * as O from "fp-ts/lib/Option"; -import { constFalse, pipe } from "fp-ts/lib/function"; -import { Platform } from "react-native"; - -import { createSelector } from "reselect"; -import { getType } from "typesafe-actions"; - -import { ToolEnum } from "../../../definitions/content/AssistanceToolConfig"; -import { BackendStatus } from "../../../definitions/content/BackendStatus"; -import { BancomatPayConfig } from "../../../definitions/content/BancomatPayConfig"; -import { BarcodesScannerConfig } from "../../../definitions/content/BarcodesScannerConfig"; -import { SectionStatus } from "../../../definitions/content/SectionStatus"; -import { Sections } from "../../../definitions/content/Sections"; -import { Banner } from "../../../definitions/content/Banner"; -import { - cdcEnabled, - cgnMerchantsV2Enabled, - fciEnabled, - premiumMessagesOptInEnabled, - scanAdditionalBarcodesEnabled -} from "../../config"; -import { LocalizedMessageKeys } from "../../i18n"; -import { getAppVersion, isVersionSupported } from "../../utils/appVersion"; -import { backendStatusLoadSuccess } from "../actions/backendStatus"; -import { Action } from "../actions/types"; -import { StatusMessage } from "../../../definitions/content/StatusMessage"; -import { isIdPayTestEnabledSelector } from "./persistedPreferences"; -import { GlobalState } from "./types"; -import { isPropertyWithMinAppVersionEnabled } from "./featureFlagWithMinAppVersionStatus"; -import { currentRouteSelector } from "./navigation"; - -export type SectionStatusKey = keyof Sections; -/** note that this state is not persisted so Option type is accepted - * if you want to persist an option take care of persinsting/rehydrating - * see https://www.pivotaltracker.com/story/show/170998374 - */ -export type BackendStatusState = { - status: O.Option; - areSystemsDead: boolean; - deadsCounter: number; -}; -const initialBackendInfoState: BackendStatusState = { - status: O.none, - areSystemsDead: false, - deadsCounter: 0 -}; - -export const backendServicesStatusSelector = ( - state: GlobalState -): BackendStatusState => state.backendStatus; - -export const backendStatusSelector = ( - state: GlobalState -): O.Option => state.backendStatus.status; - -export const isBackendStatusLoadedSelector = (state: GlobalState) => - O.isSome(backendStatusSelector(state)); - -// return the section status for the given key. if it is not present, returns undefined -export const sectionStatusSelector = (sectionStatusKey: SectionStatusKey) => - createSelector( - backendStatusSelector, - (backendStatus): SectionStatus | undefined => - pipe( - backendStatus, - O.map(bs => bs.sections?.[sectionStatusKey]), - O.toUndefined - ) - ); - -export const isSectionVisibleSelector = ( - state: GlobalState, - sectionStatusKey: SectionStatusKey -) => - pipe( - sectionStatusUncachedSelector(state, sectionStatusKey), - O.map(section => section.is_visible), - O.getOrElse(constFalse) - ); -export const webUrlForSectionSelector = ( - state: GlobalState, - sectionStatusKey: SectionStatusKey, - locale: LocalizedMessageKeys -) => - pipe( - sectionStatusUncachedSelector(state, sectionStatusKey), - O.chainNullableK(section => section.web_url), - O.chainNullableK(statusMessage => statusMessage[locale]), - O.toUndefined - ); -export const messageForSectionSelector = ( - state: GlobalState, - sectionStatusKey: SectionStatusKey, - locale: LocalizedMessageKeys -) => - pipe( - sectionStatusUncachedSelector(state, sectionStatusKey), - O.chainNullableK(section => section.message), - O.chainNullableK(messageTranslations => messageTranslations[locale]), - O.toUndefined - ); -export const levelForSectionSelector = ( - state: GlobalState, - sectionStatusKey: SectionStatusKey -) => - pipe( - sectionStatusUncachedSelector(state, sectionStatusKey), - O.map(section => section.level), - O.toUndefined - ); - -export const cgnMerchantVersionSelector = createSelector( - backendStatusSelector, - (backendStatus): boolean | undefined => - cgnMerchantsV2Enabled && - pipe( - backendStatus, - O.chainNullableK(bs => bs.config), - O.chainNullableK(config => config.cgn.merchants_v2), - O.toUndefined - ) -); - -export const assistanceToolConfigSelector = createSelector( - backendStatusSelector, - (backendStatus): ToolEnum | undefined => - pipe( - backendStatus, - O.map(bs => bs.config.assistanceTool.tool), - O.toUndefined - ) -); - -/** - * return the remote config about paypal enabled/disabled - * if there is no data, false is the default value -> (paypal disabled) - */ -export const isPaypalEnabledSelector = createSelector( - backendStatusSelector, - (backendStatus): boolean => - pipe( - backendStatus, - O.map(bs => bs.config.paypal.enabled), - O.toUndefined - ) ?? false -); - -/** - * return the remote config about BancomatPay - * if no data is available the default is considering all flags set to false - */ -export const bancomatPayConfigSelector = createSelector( - backendStatusSelector, - (backendStatus): BancomatPayConfig => - pipe( - backendStatus, - O.map(bs => bs.config.bancomatPay), - O.getOrElseW(() => ({ - display: false, - onboarding: false, - payment: false - })) - ) -); - -/** - * return the remote config about CGN enabled/disabled - * if there is no data, false is the default value -> (CGN disabled) - */ -export const isCGNEnabledSelector = createSelector( - backendStatusSelector, - (backendStatus): boolean => - pipe( - backendStatus, - O.map(bs => bs.config.cgn.enabled), - O.toUndefined - ) ?? false -); - -export const fimsRequiresAppUpdateSelector = (state: GlobalState) => - pipe( - state, - backendStatusSelector, - backendStatus => - !isPropertyWithMinAppVersionEnabled({ - backendStatus, - mainLocalFlag: true, - configPropertyName: "fims" - }) - ); - -export const fimsDomainSelector = createSelector( - backendStatusSelector, - (backendStatus): string | undefined => - pipe( - backendStatus, - O.map(bs => bs.config.fims.domain), - O.toUndefined - ) -); - -/** - * Return the remote config about the Premium Messages opt-in/out - * screens enabled/disable. If there is no data or the local Feature Flag is - * disabled, false is the default value -> (Opt-in/out screen disabled) - */ -export const isPremiumMessagesOptInOutEnabledSelector = createSelector( - backendStatusSelector, - (backendStatus): boolean => - (premiumMessagesOptInEnabled && - pipe( - backendStatus, - O.map(bs => bs.config.premiumMessages.opt_in_out_enabled), - O.toUndefined - )) ?? - false -); - -/** - * return the remote config about CDC enabled/disabled - * if there is no data or the local Feature Flag is disabled, - * false is the default value -> (CDC disabled) - */ -export const isCdcEnabledSelector = createSelector( - backendStatusSelector, - (backendStatus): boolean => - cdcEnabled && - pipe( - backendStatus, - O.map(bs => bs.config.cdc.enabled), - O.getOrElse(() => false) - ) -); - -/** - * Return the remote config about the barcodes scanner. - * If no data is available or the local feature flag is falsy - * the default is considering all flags set to false. - */ -export const barcodesScannerConfigSelector = createSelector( - backendStatusSelector, - (backendStatus): BarcodesScannerConfig => - pipe( - backendStatus, - O.map(bs => bs.config.barcodesScanner), - // If the local feature flag is disabled all the - // configurations should be set as `false`. - O.filter(() => scanAdditionalBarcodesEnabled), - O.getOrElseW(() => ({ - dataMatrixPosteEnabled: false - })) - ) -); - -/** - * Return the remote config about PN enabled/disabled - * if there is no data, false is the default value -> (PN disabled) - */ -export const isPnEnabledSelector = (state: GlobalState) => - pipe( - state.backendStatus.status, - O.map(s => s.config.pn.enabled), - O.getOrElse(() => false) - ); - -/** - * Return false if the app needs to be updated in order to use PN. - */ -export const isPnAppVersionSupportedSelector = (state: GlobalState) => - pipe( - state, - backendStatusSelector, - O.map(bs => - isVersionSupported( - Platform.OS === "ios" - ? bs.config.pn.min_app_version.ios - : bs.config.pn.min_app_version.android, - getAppVersion() - ) - ), - O.getOrElse(() => false) - ); - -/** - * Return the minimum app version required to use PN. - */ -export const pnMinAppVersionSelector = (state: GlobalState) => - pipe( - state.backendStatus.status, - O.map(bs => - Platform.OS === "ios" - ? bs.config.pn.min_app_version.ios - : bs.config.pn.min_app_version.android - ), - O.getOrElse(() => "-") - ); - -/** - * Return the url of the PN frontend. - */ -export const pnFrontendUrlSelector = (state: GlobalState) => - pipe( - state.backendStatus.status, - O.map(bs => bs.config.pn.frontend_url), - O.getOrElse(() => "") - ); - -export const configSelector = createSelector( - backendStatusSelector, - backendStatus => - pipe( - backendStatus, - O.map(bs => bs.config) - ) -); - -export const paymentsConfigSelector = createSelector(configSelector, config => - pipe( - config, - O.map(c => c.payments) - ) -); - -export const preferredPspsByOriginSelector = createSelector( - paymentsConfigSelector, - config => - pipe( - config, - O.map(c => c.preferredPspsByOrigin), - O.toUndefined - ) -); - -/** - * Return the remote config about FCI enabled/disabled - * if there is no data or the local Feature Flag is disabled, - * false is the default value -> (FCI disabled) - */ -export const isFciEnabledSelector = createSelector( - backendStatusSelector, - (backendStatus): boolean => - fciEnabled && - pipe( - backendStatus, - O.map(bs => - isVersionSupported( - Platform.OS === "ios" - ? bs.config.fci.min_app_version.ios - : bs.config.fci.min_app_version.android, - getAppVersion() - ) - ), - O.getOrElse(() => false) - ) -); - -export const isIdPayEnabledSelector = createSelector( - backendStatusSelector, - isIdPayTestEnabledSelector, - (backendStatus, isIdPayTestEnabled): boolean => - isIdPayTestEnabled && - pipe( - backendStatus, - O.map(bs => - isVersionSupported( - Platform.OS === "ios" - ? bs.config.idPay.min_app_version.ios - : bs.config.idPay.min_app_version.android, - getAppVersion() - ) - ), - O.getOrElse(() => false) - ) -); - -/** - * Return the remote config about the new payment section enabled/disabled - * If the local feature flag is enabled, the remote config is ignored - */ -export const isNewPaymentSectionEnabledSelector = createSelector( - backendStatusSelector, - (backendStatus): boolean => - pipe( - backendStatus, - O.map(bs => - isVersionSupported( - Platform.OS === "ios" - ? bs.config.newPaymentSection.min_app_version.ios - : bs.config.newPaymentSection.min_app_version.android, - getAppVersion() - ) - ), - O.getOrElse(() => false) - ) -); -/* -This selector checks that both the new wallet section and the -new document scan section are included in the tab bar. -In this case, the navigation to the profile section in the tab bar -is replaced with the 'settings' section accessed by clicking -on the icon in the headers of the top-level screens. -It will be possible to delete this control and all the code it carries -it carries when isNewPaymentSectionEnabledSelector and -isNewScanSectionLocallyEnabled will be deleted. - -NOTE: Since there is a lot of logic attached to this selector, -this reassignment of its value has been done for the moment, -but as soon as the FF can be eliminated, all the logic on which -it depends and both selectors will also be eliminated. - */ -export const isSettingsVisibleAndHideProfileSelector = - isNewPaymentSectionEnabledSelector; - -// systems could be consider dead when we have no updates for at least DEAD_COUNTER_THRESHOLD times -export const DEAD_COUNTER_THRESHOLD = 2; - -// true if we have data and it says backend is off -export const isBackendServicesStatusOffSelector = createSelector( - backendServicesStatusSelector, - bss => bss.areSystemsDead -); - -/** - * Return the remote config about IT-WALLET enabled/disabled - * if there is no data or the local Feature Flag is disabled, - * false is the default value -> (IT-WALLET disabled) - */ -export const isItwEnabledSelector = createSelector( - backendStatusSelector, - (backendStatus): boolean => - pipe( - backendStatus, - O.map( - bs => - isVersionSupported( - Platform.OS === "ios" - ? bs.config.itw.min_app_version.ios - : bs.config.itw.min_app_version.android, - getAppVersion() - ) && bs.config.itw.enabled - ), - O.getOrElse(() => false) - ) -); - -/** - * Return the remote feature flag about the payment feedback banner enabled/disabled - * that is shown after a successful payment. - */ -export const isPaymentsFeedbackBannerEnabledSelector = createSelector( - backendStatusSelector, - (backendStatus): boolean => - pipe( - backendStatus, - O.map(bs => - isVersionSupported( - Platform.OS === "ios" - ? bs.config.newPaymentSection.feedbackBanner?.min_app_version.ios - : bs.config.newPaymentSection.feedbackBanner?.min_app_version - .android, - getAppVersion() - ) - ), - O.getOrElse(() => false) - ) -); - -/** - * Return the remote config about the payment feedback banner - */ -export const paymentsFeedbackBannerConfigSelector = createSelector( - backendStatusSelector, - (backendStatus): Banner | undefined => - pipe( - backendStatus, - O.map(bs => bs.config.newPaymentSection.feedbackBanner), - O.toUndefined - ) -); - -export const areSystemsDeadReducer = ( - currentState: BackendStatusState, - backendStatus: BackendStatus -): BackendStatusState => { - const deadsCounter = - backendStatus.is_alive === false - ? Math.min(currentState.deadsCounter + 1, DEAD_COUNTER_THRESHOLD) - : 0; - return { - ...currentState, - status: O.some(backendStatus), - areSystemsDead: deadsCounter >= DEAD_COUNTER_THRESHOLD, - deadsCounter - }; -}; - -export default function backendServicesStatusReducer( - state: BackendStatusState = initialBackendInfoState, - action: Action -): BackendStatusState { - if (action.type === getType(backendStatusLoadSuccess)) { - return areSystemsDeadReducer(state, action.payload); - } - return state; -} - -const sectionStatusUncachedSelector = ( - state: GlobalState, - sectionStatusKey: SectionStatusKey -) => - pipe( - state.backendStatus.status, - O.chainNullableK(status => status.sections?.[sectionStatusKey]) - ); - -const statusMessagesSelector = (state: GlobalState) => - pipe( - state, - backendStatusSelector, - O.map(bs => bs.statusMessages), - O.toUndefined - ); - -const EMPTY_ARRAY: ReadonlyArray = []; - -// Since the return of the selector comes from an array.filter function it is important to cache the result -// to avoid unintended rerender on components. -export const statusMessageByRouteSelector = (routeName?: string) => - createSelector( - [statusMessagesSelector, currentRouteSelector], - (statusMessages, currentRoute): ReadonlyArray | undefined => - pipe( - statusMessages, - O.fromNullable, - O.map(({ items }) => { - const messages = items.filter(message => - message.routes.includes(routeName ?? currentRoute) - ); - return messages.length > 0 ? messages : EMPTY_ARRAY; - }), - O.toUndefined - ) - ); diff --git a/ts/store/reducers/backendStatus/backendInfo.ts b/ts/store/reducers/backendStatus/backendInfo.ts new file mode 100644 index 00000000000..dac425f51de --- /dev/null +++ b/ts/store/reducers/backendStatus/backendInfo.ts @@ -0,0 +1,51 @@ +import { getType } from "typesafe-actions"; +import * as O from "fp-ts/lib/Option"; +import { pipe } from "fp-ts/lib/function"; +import { Action } from "../../actions/types"; +import { backendStatusLoadSuccess } from "../../actions/backendStatus"; +import { BackendStatus } from "../../../../definitions/content/BackendStatus"; +import { GlobalState } from "../types"; + +// systems could be consider dead when we have no updates for at least DEAD_COUNTER_THRESHOLD times +export const DEAD_COUNTER_THRESHOLD = 2; + +export type BackedInfoState = { + backendInfoMessage: O.Option; + areSystemsDead: boolean; + deadsCounter: number; +}; + +const initialBackendInfoState: BackedInfoState = { + backendInfoMessage: O.none, + areSystemsDead: false, + deadsCounter: 0 +}; + +export const backendInfoReducer = ( + state: BackedInfoState = initialBackendInfoState, + action: Action +): BackedInfoState => { + if (action.type === getType(backendStatusLoadSuccess)) { + const deadsCounter = + action.payload.is_alive === false + ? Math.min(state.deadsCounter + 1, DEAD_COUNTER_THRESHOLD) + : 0; + return { + ...state, + backendInfoMessage: O.some(action.payload.message), + areSystemsDead: deadsCounter >= DEAD_COUNTER_THRESHOLD, + deadsCounter + }; + } + return state; +}; + +export const deadsCounterSelector = (state: GlobalState) => + state.backendInfo.deadsCounter; + +// true if we have data and it says backend is off +export const isBackendServicesStatusOffSelector = (state: GlobalState) => + state.backendInfo.areSystemsDead; + +export const backendInfoMessageSelector = (state: GlobalState) => + pipe(state.backendInfo.backendInfoMessage, O.toUndefined); diff --git a/ts/store/reducers/backendStatus/remoteConfig.ts b/ts/store/reducers/backendStatus/remoteConfig.ts new file mode 100644 index 00000000000..ed41fbd9187 --- /dev/null +++ b/ts/store/reducers/backendStatus/remoteConfig.ts @@ -0,0 +1,393 @@ +import * as O from "fp-ts/lib/Option"; +import { getType } from "typesafe-actions"; +import { createSelector } from "reselect"; +import { pipe } from "fp-ts/lib/function"; +import { Platform } from "react-native"; +import { BackendStatus } from "../../../../definitions/content/BackendStatus"; +import { Action } from "../../actions/types"; +import { backendStatusLoadSuccess } from "../../actions/backendStatus"; +import { GlobalState } from "../types"; +import { getAppVersion, isVersionSupported } from "../../../utils/appVersion"; +import { + cdcEnabled, + cgnMerchantsV2Enabled, + fciEnabled, + premiumMessagesOptInEnabled, + scanAdditionalBarcodesEnabled +} from "../../../config"; +import { ToolEnum } from "../../../../definitions/content/AssistanceToolConfig"; +import { BancomatPayConfig } from "../../../../definitions/content/BancomatPayConfig"; +import { isPropertyWithMinAppVersionEnabled } from "../featureFlagWithMinAppVersionStatus"; +import { BarcodesScannerConfig } from "../../../../definitions/content/BarcodesScannerConfig"; +import { isIdPayTestEnabledSelector } from "../persistedPreferences"; +import { Banner } from "../../../../definitions/content/Banner"; + +export type RemoteConfigState = O.Option; + +const initialRemoteConfigState: RemoteConfigState = O.none; + +export default function remoteConfigReducer( + state: RemoteConfigState = initialRemoteConfigState, + action: Action +): RemoteConfigState { + if (action.type === getType(backendStatusLoadSuccess)) { + return O.some(action.payload.config); + } + return state; +} + +export const remoteConfigSelector = (state: GlobalState) => state.remoteConfig; + +export const isBackendStatusLoadedSelector = (state: GlobalState) => + O.isSome(remoteConfigSelector(state)); + +export const cgnMerchantVersionSelector = createSelector( + remoteConfigSelector, + (remoteConfig): boolean | undefined => + cgnMerchantsV2Enabled && + pipe( + remoteConfig, + O.map(config => config.cgn.merchants_v2), + O.toUndefined + ) +); + +export const assistanceToolConfigSelector = createSelector( + remoteConfigSelector, + (remoteConfig): ToolEnum | undefined => + pipe( + remoteConfig, + O.map(c => c.assistanceTool.tool), + O.toUndefined + ) +); + +/** + * return the remote config about paypal enabled/disabled + * if there is no data, false is the default value -> (paypal disabled) + */ +export const isPaypalEnabledSelector = createSelector( + remoteConfigSelector, + (remoteConfig): boolean => + pipe( + remoteConfig, + O.map(c => c.paypal.enabled), + O.toUndefined + ) ?? false +); + +/** + * return the remote config about BancomatPay + * if no data is available the default is considering all flags set to false + */ +export const bancomatPayConfigSelector = createSelector( + remoteConfigSelector, + (remoteConfig): BancomatPayConfig => + pipe( + remoteConfig, + O.map(c => c.bancomatPay), + O.getOrElseW(() => ({ + display: false, + onboarding: false, + payment: false + })) + ) +); + +/** + * return the remote config about CGN enabled/disabled + * if there is no data, false is the default value -> (CGN disabled) + */ +export const isCGNEnabledSelector = createSelector( + remoteConfigSelector, + (remoteConfig): boolean => + pipe( + remoteConfig, + O.map(c => c.cgn.enabled), + O.toUndefined + ) ?? false +); + +export const fimsRequiresAppUpdateSelector = (state: GlobalState) => + pipe( + state, + remoteConfigSelector, + remoteConfig => + !isPropertyWithMinAppVersionEnabled({ + remoteConfig, + mainLocalFlag: true, + configPropertyName: "fims" + }) + ); + +export const fimsDomainSelector = createSelector( + remoteConfigSelector, + (remoteConfig): string | undefined => + pipe( + remoteConfig, + O.map(c => c.fims.domain), + O.toUndefined + ) +); + +/** + * Return the remote config about the Premium Messages opt-in/out + * screens enabled/disable. If there is no data or the local Feature Flag is + * disabled, false is the default value -> (Opt-in/out screen disabled) + */ +export const isPremiumMessagesOptInOutEnabledSelector = createSelector( + remoteConfigSelector, + (remoteConfig): boolean => + (premiumMessagesOptInEnabled && + pipe( + remoteConfig, + O.map(c => c.premiumMessages.opt_in_out_enabled), + O.toUndefined + )) ?? + false +); + +/** + * return the remote config about CDC enabled/disabled + * if there is no data or the local Feature Flag is disabled, + * false is the default value -> (CDC disabled) + */ +export const isCdcEnabledSelector = createSelector( + remoteConfigSelector, + (remoteConfig): boolean => + cdcEnabled && + pipe( + remoteConfig, + O.map(c => c.cdc.enabled), + O.getOrElse(() => false) + ) +); + +/** + * Return the remote config about the barcodes scanner. + * If no data is available or the local feature flag is falsy + * the default is considering all flags set to false. + */ +export const barcodesScannerConfigSelector = createSelector( + remoteConfigSelector, + (remoteConfig): BarcodesScannerConfig => + pipe( + remoteConfig, + O.map(c => c.barcodesScanner), + // If the local feature flag is disabled all the + // configurations should be set as `false`. + O.filter(() => scanAdditionalBarcodesEnabled), + O.getOrElseW(() => ({ + dataMatrixPosteEnabled: false + })) + ) +); + +/** + * Return the remote config about PN enabled/disabled + * if there is no data, false is the default value -> (PN disabled) + */ +export const isPnEnabledSelector = (state: GlobalState) => + pipe( + state.remoteConfig, + O.map(c => c.pn.enabled), + O.getOrElse(() => false) + ); + +/** + * Return false if the app needs to be updated in order to use PN. + */ +export const isPnAppVersionSupportedSelector = (state: GlobalState) => + pipe( + state, + remoteConfigSelector, + O.map(c => + isVersionSupported( + Platform.OS === "ios" + ? c.pn.min_app_version.ios + : c.pn.min_app_version.android, + getAppVersion() + ) + ), + O.getOrElse(() => false) + ); + +/** + * Return the minimum app version required to use PN. + */ +export const pnMinAppVersionSelector = (state: GlobalState) => + pipe( + state.remoteConfig, + O.map(c => + Platform.OS === "ios" + ? c.pn.min_app_version.ios + : c.pn.min_app_version.android + ), + O.getOrElse(() => "-") + ); + +/** + * Return the url of the PN frontend. + */ +export const pnFrontendUrlSelector = (state: GlobalState) => + pipe( + state.remoteConfig, + O.map(c => c.pn.frontend_url), + O.getOrElse(() => "") + ); + +export const paymentsConfigSelector = createSelector( + remoteConfigSelector, + config => + pipe( + config, + O.map(c => c.payments) + ) +); + +export const preferredPspsByOriginSelector = createSelector( + paymentsConfigSelector, + config => + pipe( + config, + O.map(c => c.preferredPspsByOrigin), + O.toUndefined + ) +); + +/** + * Return the remote config about FCI enabled/disabled + * if there is no data or the local Feature Flag is disabled, + * false is the default value -> (FCI disabled) + */ +export const isFciEnabledSelector = createSelector( + remoteConfigSelector, + (remoteConfig): boolean => + fciEnabled && + pipe( + remoteConfig, + O.map(c => + isVersionSupported( + Platform.OS === "ios" + ? c.fci.min_app_version.ios + : c.fci.min_app_version.android, + getAppVersion() + ) + ), + O.getOrElse(() => false) + ) +); + +export const isIdPayEnabledSelector = createSelector( + remoteConfigSelector, + isIdPayTestEnabledSelector, + (remoteConfig, isIdPayTestEnabled): boolean => + isIdPayTestEnabled && + pipe( + remoteConfig, + O.map(c => + isVersionSupported( + Platform.OS === "ios" + ? c.idPay.min_app_version.ios + : c.idPay.min_app_version.android, + getAppVersion() + ) + ), + O.getOrElse(() => false) + ) +); + +/** + * Return the remote config about the new payment section enabled/disabled + * If the local feature flag is enabled, the remote config is ignored + */ +export const isNewPaymentSectionEnabledSelector = createSelector( + remoteConfigSelector, + (remoteConfig): boolean => + pipe( + remoteConfig, + O.map(c => + isVersionSupported( + Platform.OS === "ios" + ? c.newPaymentSection.min_app_version.ios + : c.newPaymentSection.min_app_version.android, + getAppVersion() + ) + ), + O.getOrElse(() => false) + ) +); +/* +This selector checks that both the new wallet section and the +new document scan section are included in the tab bar. +In this case, the navigation to the profile section in the tab bar +is replaced with the 'settings' section accessed by clicking +on the icon in the headers of the top-level screens. +It will be possible to delete this control and all the code it carries +it carries when isNewPaymentSectionEnabledSelector and +isNewScanSectionLocallyEnabled will be deleted. + +NOTE: Since there is a lot of logic attached to this selector, +this reassignment of its value has been done for the moment, +but as soon as the FF can be eliminated, all the logic on which +it depends and both selectors will also be eliminated. + */ +export const isSettingsVisibleAndHideProfileSelector = + isNewPaymentSectionEnabledSelector; + +/** + * Return the remote config about IT-WALLET enabled/disabled + * if there is no data or the local Feature Flag is disabled, + * false is the default value -> (IT-WALLET disabled) + */ +export const isItwEnabledSelector = createSelector( + remoteConfigSelector, + (remoteConfig): boolean => + pipe( + remoteConfig, + O.map( + c => + isVersionSupported( + Platform.OS === "ios" + ? c.itw.min_app_version.ios + : c.itw.min_app_version.android, + getAppVersion() + ) && c.itw.enabled + ), + O.getOrElse(() => false) + ) +); + +/** + * Return the remote feature flag about the payment feedback banner enabled/disabled + * that is shown after a successful payment. + */ +export const isPaymentsFeedbackBannerEnabledSelector = createSelector( + remoteConfigSelector, + (remoteConfig): boolean => + pipe( + remoteConfig, + O.map(c => + isVersionSupported( + Platform.OS === "ios" + ? c.newPaymentSection.feedbackBanner?.min_app_version.ios + : c.newPaymentSection.feedbackBanner?.min_app_version.android, + getAppVersion() + ) + ), + O.getOrElse(() => false) + ) +); + +/** + * Return the remote config about the payment feedback banner + */ +export const paymentsFeedbackBannerConfigSelector = createSelector( + remoteConfigSelector, + (remoteConfig): Banner | undefined => + pipe( + remoteConfig, + O.map(c => c.newPaymentSection.feedbackBanner), + O.toUndefined + ) +); diff --git a/ts/store/reducers/backendStatus/sectionStatus.ts b/ts/store/reducers/backendStatus/sectionStatus.ts new file mode 100644 index 00000000000..5b553352686 --- /dev/null +++ b/ts/store/reducers/backendStatus/sectionStatus.ts @@ -0,0 +1,91 @@ +import * as O from "fp-ts/lib/Option"; +import { getType } from "typesafe-actions"; +import { constFalse, pipe } from "fp-ts/lib/function"; +import { createSelector } from "reselect"; +import { BackendStatus } from "../../../../definitions/content/BackendStatus"; +import { Action } from "../../actions/types"; +import { backendStatusLoadSuccess } from "../../actions/backendStatus"; +import { GlobalState } from "../types"; +import { SectionStatus } from "../../../../definitions/content/SectionStatus"; +import { LocalizedMessageKeys } from "../../../i18n"; +import { Sections } from "../../../../definitions/content/Sections"; + +export type SectionStatusKey = keyof Sections; + +export type SectionStatusState = O.Option; + +const initialSectionStatusState: SectionStatusState = O.none; + +export default function sectionStatusReducer( + state: SectionStatusState = initialSectionStatusState, + action: Action +): SectionStatusState { + if (action.type === getType(backendStatusLoadSuccess)) { + return O.some(action.payload.sections); + } + return state; +} + +export const sectionStatusSelector = (state: GlobalState) => + state.sectionStatus; + +export const sectionStatusByKeySelector = ( + sectionStatusKey: SectionStatusKey +) => + createSelector(sectionStatusSelector, (sections): SectionStatus | undefined => + pipe( + sections, + O.map(s => s?.[sectionStatusKey]), + O.toUndefined + ) + ); + +export const sectionStatusUncachedSelector = ( + state: GlobalState, + sectionStatusKey: SectionStatusKey +) => + pipe( + state.sectionStatus, + O.chainNullableK(status => status?.[sectionStatusKey]) + ); + +export const isSectionVisibleSelector = ( + state: GlobalState, + sectionStatusKey: SectionStatusKey +) => + pipe( + sectionStatusUncachedSelector(state, sectionStatusKey), + O.map(section => section.is_visible), + O.getOrElse(constFalse) + ); +export const webUrlForSectionSelector = ( + state: GlobalState, + sectionStatusKey: SectionStatusKey, + locale: LocalizedMessageKeys +) => + pipe( + sectionStatusUncachedSelector(state, sectionStatusKey), + O.chainNullableK(section => section.web_url), + O.chainNullableK(statusMessage => statusMessage[locale]), + O.toUndefined + ); +export const messageForSectionSelector = ( + state: GlobalState, + sectionStatusKey: SectionStatusKey, + locale: LocalizedMessageKeys +) => + pipe( + sectionStatusUncachedSelector(state, sectionStatusKey), + O.chainNullableK(section => section.message), + O.chainNullableK(messageTranslations => messageTranslations[locale]), + O.toUndefined + ); +export const levelForSectionSelector = ( + state: GlobalState, + sectionStatusKey: SectionStatusKey +) => + pipe( + sectionStatusUncachedSelector(state, sectionStatusKey), + O.map(section => section.level), + O.toUndefined + ); diff --git a/ts/store/reducers/backendStatus/statusMessages.ts b/ts/store/reducers/backendStatus/statusMessages.ts new file mode 100644 index 00000000000..ea6de0410ab --- /dev/null +++ b/ts/store/reducers/backendStatus/statusMessages.ts @@ -0,0 +1,48 @@ +import * as O from "fp-ts/lib/Option"; +import { getType } from "typesafe-actions"; +import { createSelector } from "reselect"; +import { pipe } from "fp-ts/lib/function"; +import { BackendStatus } from "../../../../definitions/content/BackendStatus"; +import { Action } from "../../actions/types"; +import { backendStatusLoadSuccess } from "../../actions/backendStatus"; +import { GlobalState } from "../types"; +import { currentRouteSelector } from "../navigation"; +import { StatusMessage } from "../../../../definitions/content/StatusMessage"; + +export type StatusMessagesState = O.Option; + +const initialStatusMessagesState: StatusMessagesState = O.none; + +export default function statusMessagesReducer( + state: StatusMessagesState = initialStatusMessagesState, + action: Action +): StatusMessagesState { + if (action.type === getType(backendStatusLoadSuccess)) { + return O.fromNullable(action.payload.statusMessages); + } + return state; +} + +const statusMessagesSelector = (state: GlobalState) => + pipe(state, s => s.statusMessages, O.toUndefined); + +const EMPTY_ARRAY: ReadonlyArray = []; + +// Since the return of the selector comes from an array.filter function it is important to cache the result +// to avoid unintended rerender on components. +export const statusMessageByRouteSelector = (routeName?: string) => + createSelector( + [statusMessagesSelector, currentRouteSelector], + (statusMessages, currentRoute): ReadonlyArray | undefined => + pipe( + statusMessages, + O.fromNullable, + O.map(({ items }) => { + const messages = items.filter(message => + message.routes.includes(routeName ?? currentRoute) + ); + return messages.length > 0 ? messages : EMPTY_ARRAY; + }), + O.toUndefined + ) + ); diff --git a/ts/store/reducers/featureFlagWithMinAppVersionStatus.ts b/ts/store/reducers/featureFlagWithMinAppVersionStatus.ts index 4411c2c6d89..0fbd420a0b2 100644 --- a/ts/store/reducers/featureFlagWithMinAppVersionStatus.ts +++ b/ts/store/reducers/featureFlagWithMinAppVersionStatus.ts @@ -35,7 +35,7 @@ type ExtractSecondLevelKeyWithMinAppVersion< type CheckPropertyWithMinAppVersionParameters< T extends KeysWithMinAppVersion > = { - backendStatus: O.Option; + remoteConfig: O.Option; mainLocalFlag: boolean; configPropertyName: T; } & ( @@ -54,13 +54,13 @@ type CheckPropertyWithMinAppVersionParameters< * * Details: * The fuction take an object with this property: -* @property {Option\} backendStatus - Our backendStatus object +* @property {Option\} remoteConfig - Our remoteConfig object * @property {boolean} mainLocalFlag - The local config that represents the feature * @property {KeysWithMinAppVersion\} configPropertyName - A property that extends ObjectWithMinAppVersion in the Config object (from backendStatus) * * @example * isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: fastLoginConfig, configPropertyName: "fastLogin" }); @@ -72,7 +72,7 @@ type CheckPropertyWithMinAppVersionParameters< * * @example * isPropertyWithMinAppVersionEnabled({ - backendStatus: store, + remoteConfig: store, mainLocalFlag: fastLoginConfig, configPropertyName: "fastLogin", optionalLocalFlag: optInFastLoginConfig, @@ -83,7 +83,7 @@ type CheckPropertyWithMinAppVersionParameters< export const isPropertyWithMinAppVersionEnabled = < T extends KeysWithMinAppVersion >({ - backendStatus, + remoteConfig, mainLocalFlag, configPropertyName, optionalLocalFlag, @@ -94,7 +94,7 @@ export const isPropertyWithMinAppVersionEnabled = < pipe( O.fromNullable( getObjectWithMinAppVersion( - backendStatus, + remoteConfig, mainLocalFlag, configPropertyName, optionalLocalFlag, @@ -121,15 +121,14 @@ export const isPropertyWithMinAppVersionEnabled = < ); function getObjectWithMinAppVersion>( - backendStatus: O.Option, + remoteConfig: O.Option, mainLocalFlag: boolean, configPropertyName: T, optionalLocalFlag?: boolean, optionalConfig?: ExtractSecondLevelKeyWithMinAppVersion ): ObjectWithMinAppVersion { return pipe( - backendStatus, - O.chainNullableK(bs => bs.config), + remoteConfig, O.chainNullableK(cfg => cfg[configPropertyName]), O.fold( () => undefined, @@ -141,7 +140,7 @@ function getObjectWithMinAppVersion>( opt => optionalLocalFlag && isPropertyWithMinAppVersionEnabled({ - backendStatus, + remoteConfig, mainLocalFlag, configPropertyName }) diff --git a/ts/store/reducers/index.ts b/ts/store/reducers/index.ts index 698fb680bb2..5213d459fbf 100644 --- a/ts/store/reducers/index.ts +++ b/ts/store/reducers/index.ts @@ -41,7 +41,6 @@ import authenticationReducer, { AuthenticationState, INITIAL_STATE as authenticationInitialState } from "./authentication"; -import backendStatusReducer from "./backendStatus"; import backoffErrorReducer from "./backoffError"; import cieReducer from "./cie"; import contentReducer, { @@ -74,6 +73,10 @@ import { GlobalState } from "./types"; import userDataProcessingReducer from "./userDataProcessing"; import walletReducer from "./wallet"; import { WALLETS_INITIAL_STATE as walletsInitialState } from "./wallet/wallets"; +import remoteConfigReducer from "./backendStatus/remoteConfig"; +import statusMessagesReducer from "./backendStatus/statusMessages"; +import sectionStatusReducer from "./backendStatus/sectionStatus"; +import { backendInfoReducer } from "./backendStatus/backendInfo"; // A custom configuration to store the authentication into the Keychain export const authenticationPersistConfig: PersistConfig = { @@ -129,7 +132,10 @@ export const appReducer: Reducer = combineReducers< backoffError: backoffErrorReducer, wallet: walletReducer, versionInfo: versionInfoReducer, - backendStatus: backendStatusReducer, + remoteConfig: remoteConfigReducer, + statusMessages: statusMessagesReducer, + sectionStatus: sectionStatusReducer, + backendInfo: backendInfoReducer, preferences: preferencesReducer, search: searchReducer, cie: cieReducer, @@ -203,7 +209,10 @@ export function createRootReducer( _persist: state.authentication._persist }, // backend status must be kept - backendStatus: state.backendStatus, + backendInfo: state.backendInfo, + remoteConfig: state.remoteConfig, + statusMessages: state.statusMessages, + sectionStatus: state.sectionStatus, // keep servicesMetadata from content section content: { ...contentInitialContentState, diff --git a/ts/store/reducers/types.ts b/ts/store/reducers/types.ts index 76a3aa2bab6..6a9b2a56ce9 100644 --- a/ts/store/reducers/types.ts +++ b/ts/store/reducers/types.ts @@ -9,7 +9,6 @@ import { PersistedNotificationsState } from "../../features/pushNotifications/st import { AppState } from "./appState"; import { AssistanceToolsState } from "./assistanceTools"; import { PersistedAuthenticationState } from "./authentication"; -import { BackendStatusState } from "./backendStatus"; import { BackoffErrorState } from "./backoffError"; import { CieState } from "./cie"; import { ContentState } from "./content"; @@ -29,12 +28,19 @@ import { SearchState } from "./search"; import { UserDataProcessingState } from "./userDataProcessing"; import { WalletState } from "./wallet"; import { StartupState } from "./startup"; +import { RemoteConfigState } from "./backendStatus/remoteConfig"; +import { StatusMessagesState } from "./backendStatus/statusMessages"; +import { SectionStatusState } from "./backendStatus/sectionStatus"; +import { BackedInfoState } from "./backendStatus/backendInfo"; export type GlobalState = Readonly<{ appState: AppState; navigation: NavigationState; authentication: PersistedAuthenticationState; - backendStatus: BackendStatusState; + remoteConfig: RemoteConfigState; + statusMessages: StatusMessagesState; + sectionStatus: SectionStatusState; + backendInfo: BackedInfoState; versionInfo: VersionInfoState; entities: PersistedEntitiesState; backoffError: BackoffErrorState;