diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e0af3c151f26b..f5eb28741c28e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,7 @@ jobs: runs-on: ubuntu-latest env: CI: true + NODE_OPTIONS: --max_old_space_size=8192 strategy: fail-fast: false matrix: diff --git a/src/components/AddPaymentCard/PaymentCardForm.tsx b/src/components/AddPaymentCard/PaymentCardForm.tsx index fddbcd2f0838b..b58ddc34ce740 100644 --- a/src/components/AddPaymentCard/PaymentCardForm.tsx +++ b/src/components/AddPaymentCard/PaymentCardForm.tsx @@ -9,11 +9,10 @@ import CurrencySelector from '@components/CurrencySelector'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; +import RenderHTML from '@components/RenderHTML'; import type {AnimatedTextInputRef} from '@components/RNTextInput'; import StateSelector from '@components/StateSelector'; -import Text from '@components/Text'; import TextInput from '@components/TextInput'; -import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -46,13 +45,7 @@ type PaymentCardFormProps = { function IAcceptTheLabel() { const {translate} = useLocalize(); - return ( - - {`${translate('common.iAcceptThe')}`} - {`${translate('common.addCardTermsOfService')}`} {`${translate('common.and')}`} - {` ${translate('common.privacyPolicy')} `} - - ); + return ; } const REQUIRED_FIELDS = [ diff --git a/src/languages/de.ts b/src/languages/de.ts index 059522e4abf1e..128a91d55634d 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -442,6 +442,9 @@ const translations = { zipPostCode: 'Postleitzahl', whatThis: 'Was ist das?', iAcceptThe: 'Ich akzeptiere die', + acceptTermsAndPrivacy: `Ich akzeptiere die Expensify-Nutzungsbedingungen und Datenschutzrichtlinie`, + acceptTermsAndConditions: `Ich akzeptiere die Allgemeine Geschäftsbedingungen`, + acceptTermsOfService: `Ich akzeptiere die Expensify-Nutzungsbedingungen`, remove: 'Entfernen', admin: 'Admin', owner: 'Eigentümer', diff --git a/src/languages/en.ts b/src/languages/en.ts index 3af2a27ea5aea..8f669f2ef665a 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -435,6 +435,9 @@ const translations = { zipPostCode: 'Zip / Postcode', whatThis: "What's this?", iAcceptThe: 'I accept the ', + acceptTermsAndPrivacy: `I accept the Expensify Terms of Service and Privacy Policy`, + acceptTermsAndConditions: `I accept the terms and conditions`, + acceptTermsOfService: `I accept the Expensify Terms of Service`, remove: 'Remove', admin: 'Admin', owner: 'Owner', diff --git a/src/languages/es.ts b/src/languages/es.ts index e1b07d7eddd4e..321bd5b6b6b81 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -423,6 +423,9 @@ const translations = { zipPostCode: 'Código postal', whatThis: '¿Qué es esto?', iAcceptThe: 'Acepto los ', + acceptTermsAndPrivacy: `Acepto los Términos de Servicio y la Política de Privacidad de Expensify`, + acceptTermsAndConditions: `Acepto los Términos y Condiciones`, + acceptTermsOfService: `Acepto los Términos de Servicio`, remove: 'Eliminar', admin: 'Administrador', owner: 'Dueño', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index f1184038cdb62..8aab905a6add9 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -442,6 +442,9 @@ const translations = { zipPostCode: 'Code postal', whatThis: "Qu'est-ce que c'est ?", iAcceptThe: "J'accepte le", + acceptTermsAndPrivacy: `J'accepte le Conditions d'utilisation d'Expensify et Politique de confidentialité`, + acceptTermsAndConditions: `J'accepte le termes et conditions`, + acceptTermsOfService: `J'accepte le Conditions d'utilisation d'Expensify`, remove: 'Supprimer', admin: 'Admin', owner: 'Propriétaire', diff --git a/src/languages/it.ts b/src/languages/it.ts index 605d4a8e187a6..647c123bb526c 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -442,6 +442,9 @@ const translations = { zipPostCode: 'CAP / Codice postale', whatThis: "Cos'è questo?", iAcceptThe: 'Accetto il', + acceptTermsAndPrivacy: `Accetto il Termini di servizio di Expensify e Informativa sulla privacy`, + acceptTermsAndConditions: `Accetto il termini e condizioni`, + acceptTermsOfService: `Accetto il Termini di servizio di Expensify`, remove: 'Rimuovi', admin: 'Admin', owner: 'Proprietario', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 0a5d16f038e42..736f975771be0 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -442,6 +442,9 @@ const translations = { zipPostCode: '郵便番号', whatThis: 'これは何ですか?', iAcceptThe: '承諾します', + acceptTermsAndPrivacy: `承諾します Expensify 利用規約 および プライバシーポリシー`, + acceptTermsAndConditions: `承諾します 利用規約`, + acceptTermsOfService: `承諾します Expensify 利用規約`, remove: '削除', admin: '管理者', owner: 'オーナー', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 0f222b55cc5d4..6780356e4bb96 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -442,6 +442,9 @@ const translations = { zipPostCode: 'Postcode', whatThis: 'Wat is dit?', iAcceptThe: 'Ik accepteer de', + acceptTermsAndPrivacy: `Ik accepteer de Expensify Gebruiksvoorwaarden en Privacybeleid`, + acceptTermsAndConditions: `Ik accepteer de algemene voorwaarden`, + acceptTermsOfService: `Ik accepteer de Expensify Gebruiksvoorwaarden`, remove: 'Verwijderen', admin: 'Admin', owner: 'Eigenaar', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index fb35f509ef546..43c4ee7f5b397 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -442,6 +442,9 @@ const translations = { zipPostCode: 'Kod pocztowy', whatThis: 'Co to jest?', iAcceptThe: 'Akceptuję', + acceptTermsAndPrivacy: `Akceptuję Warunki korzystania z usługi Expensify i Polityka prywatności`, + acceptTermsAndConditions: `Akceptuję warunki i zasady`, + acceptTermsOfService: `Akceptuję Warunki korzystania z usługi Expensify`, remove: 'Usuń', admin: 'Admin', owner: 'Właściciel', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 0f69d7e5af0bd..6443a88a25f0f 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -442,6 +442,9 @@ const translations = { zipPostCode: 'CEP / Código Postal', whatThis: 'O que é isso?', iAcceptThe: 'Eu aceito o', + acceptTermsAndPrivacy: `Eu aceito o Termos de Serviço da Expensify e Política de Privacidade`, + acceptTermsAndConditions: `Eu aceito o termos e condições`, + acceptTermsOfService: `Eu aceito o Termos de Serviço da Expensify`, remove: 'Remover', admin: 'Administração', owner: 'Proprietário', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index b91f542fb7cef..337daa5577a0e 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -442,6 +442,9 @@ const translations = { zipPostCode: '邮政编码', whatThis: '这是什么?', iAcceptThe: '我接受', + acceptTermsAndPrivacy: `我接受 Expensify 服务条款隐私政策`, + acceptTermsAndConditions: `我接受 条款和条件`, + acceptTermsOfService: `我接受 Expensify 服务条款`, remove: '移除', admin: '管理员', owner: '所有者', diff --git a/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx b/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx index 10cab1989ff40..22a693bf41344 100644 --- a/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx +++ b/src/pages/ReimbursementAccount/USD/CompleteVerification/subSteps/ConfirmAgreements.tsx @@ -3,14 +3,13 @@ import CheckboxWithLabel from '@components/CheckboxWithLabel'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; +import RenderHTML from '@components/RenderHTML'; import Text from '@components/Text'; -import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import type {SubStepProps} from '@hooks/useSubStep/types'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as ValidationUtils from '@libs/ValidationUtils'; -import CONST from '@src/CONST'; +import {getFieldRequiredErrors, isRequiredFulfilled} from '@libs/ValidationUtils'; import ONYXKEYS from '@src/ONYXKEYS'; import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; @@ -35,16 +34,11 @@ function CertifyTrueAndAccurateLabel() { function TermsAndConditionsLabel() { const {translate} = useLocalize(); - return ( - - {translate('common.iAcceptThe')} - {`${translate('completeVerificationStep.termsAndConditions')}`} - - ); + return ; } function ConfirmAgreements({onNext}: ConfirmAgreementsProps) { - const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT); + const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT, {canBeMissing: true}); const {translate} = useLocalize(); const styles = useThemeStyles(); const defaultValues = { @@ -54,17 +48,17 @@ function ConfirmAgreements({onNext}: ConfirmAgreementsProps) { }; const validate = useCallback( (values: FormOnyxValues): FormInputErrors => { - const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); + const errors = getFieldRequiredErrors(values, STEP_FIELDS); - if (!ValidationUtils.isRequiredFulfilled(values.acceptTermsAndConditions)) { + if (!isRequiredFulfilled(values.acceptTermsAndConditions)) { errors.acceptTermsAndConditions = translate('common.error.acceptTerms'); } - if (!ValidationUtils.isRequiredFulfilled(values.certifyTrueInformation)) { + if (!isRequiredFulfilled(values.certifyTrueInformation)) { errors.certifyTrueInformation = translate('completeVerificationStep.certifyTrueAndAccurateError'); } - if (!ValidationUtils.isRequiredFulfilled(values.isAuthorizedToUseBankAccount)) { + if (!isRequiredFulfilled(values.isAuthorizedToUseBankAccount)) { errors.isAuthorizedToUseBankAccount = translate('completeVerificationStep.isAuthorizedToUseBankAccountError'); } diff --git a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx index 858e6c012842e..ce0efc26048af 100644 --- a/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx +++ b/src/pages/settings/Wallet/InternationalDepositAccount/substeps/Confirmation.tsx @@ -5,9 +5,9 @@ import InputWrapper from '@components/Form/InputWrapper'; import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import FormHelpMessage from '@components/FormHelpMessage'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; +import RenderHTML from '@components/RenderHTML'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; -import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -34,12 +34,7 @@ type MenuItemProps = { function TermsAndConditionsLabel() { const {translate} = useLocalize(); - return ( - - {translate('common.iAcceptThe')} - {`${translate('common.addCardTermsOfService')}`} - - ); + return ; } function Confirmation({onNext, onMove, formValues, fieldsMap}: CustomSubStepProps) { diff --git a/tests/unit/PaymentCardFormTest.tsx b/tests/unit/PaymentCardFormTest.tsx index c61dde67e725e..bbd4755b4de0f 100644 --- a/tests/unit/PaymentCardFormTest.tsx +++ b/tests/unit/PaymentCardFormTest.tsx @@ -5,6 +5,7 @@ import {fireEvent, render, screen} from '@testing-library/react-native'; import React from 'react'; import Onyx from 'react-native-onyx'; import ComposeProviders from '@components/ComposeProviders'; +import HTMLEngineProvider from '@components/HTMLEngineProvider'; import {LocaleContextProvider} from '@components/LocaleContextProvider'; import OnyxListItemProvider from '@components/OnyxListItemProvider'; import {CurrentReportIDContextProvider} from '@hooks/useCurrentReportID'; @@ -12,6 +13,16 @@ import AddPaymentCard from '@pages/settings/Subscription/PaymentCard'; import ONYXKEYS from '@src/ONYXKEYS'; import SCREENS from '@src/SCREENS'; +jest.mock('@components/RenderHTML', () => { + const ReactMock = require('react') as typeof React; + const {Text} = require('react-native') as {Text: React.ComponentType<{children?: React.ReactNode}>}; + + return ({html}: {html: string}) => { + const plainText = html.replace(/<[^>]*>/g, ''); + return ReactMock.createElement(Text, null, plainText); + }; +}); + jest.mock('@react-native-community/geolocation', () => ({ setRNConfiguration: jest.fn(), })); @@ -39,7 +50,7 @@ describe('Subscription/AddPaymentCard', () => { const renderAddPaymentCardPage = (initialRouteName: typeof SCREENS.SETTINGS.SUBSCRIPTION.ADD_PAYMENT_CARD) => { return render( - +