diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 56ae1a2adf4d..7ba40ac75120 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -2470,8 +2470,10 @@ const ROUTES = { }, WORKSPACE_UPGRADE: { route: 'workspaces/:policyID?/upgrade/:featureName?', - getRoute: (policyID?: string, featureName?: string, backTo?: string) => - getUrlWithBackToParam(policyID ? (`workspaces/${policyID}/upgrade/${encodeURIComponent(featureName ?? '')}` as const) : (`workspaces/upgrade` as const), backTo), + getRoute: (policyID?: string, featureName?: string, backTo?: string, upgradePlanType?: string) => { + const baseRoute = policyID ? (`workspaces/${policyID}/upgrade/${encodeURIComponent(featureName ?? '')}` as const) : (`workspaces/upgrade` as const); + return getUrlWithBackToParam(upgradePlanType ? (`${baseRoute}?upgradePlanType=${upgradePlanType}` as const) : baseRoute, backTo); + }, }, WORKSPACE_DOWNGRADE: { route: 'workspaces/:policyID?/downgrade/', diff --git a/src/languages/de.ts b/src/languages/de.ts index 62f032f28bf5..59dd2e09a48a 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -6994,6 +6994,12 @@ Fordern Sie Spesendetails wie Belege und Beschreibungen an, legen Sie Limits und }, commonFeatures: { title: 'Upgrade auf den Control-Tarif', + collect: { + title: 'Upgrade auf den Collect-Tarif', + startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => + `Der Collect-Tarif beginnt bei ${formattedPrice} ${hasTeam2025Pricing ? `pro Mitglied und Monat.` : `pro aktivem Mitglied und Monat.`}. Erfahre mehr über unsere Tarife und Preise.`, + note: 'Schalte wichtige Funktionen für dein Unternehmen frei, darunter:', + }, note: 'Schalte unsere leistungsstärksten Funktionen frei, darunter:', benefits: { startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => diff --git a/src/languages/en.ts b/src/languages/en.ts index 99495c52e9d7..73a1aad39a6d 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -7183,6 +7183,12 @@ const translations = { }, commonFeatures: { title: 'Upgrade to the Control plan', + collect: { + title: 'Upgrade to the Collect plan', + startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => + `The Collect plan starts at ${formattedPrice} ${hasTeam2025Pricing ? `per member per month.` : `per active member per month.`} Learn more about our plans and pricing.`, + note: 'Unlock essential features to run your business, including:', + }, note: 'Unlock our most powerful features, including:', benefits: { startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => diff --git a/src/languages/es.ts b/src/languages/es.ts index dd886dd631c1..18be0c27b655 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -6977,6 +6977,12 @@ ${amount} para ${merchant} - ${date}`, }, commonFeatures: { title: 'Mejorar al plan Controlar', + collect: { + title: 'Mejorar al plan Recopilar', + startsAtFull: (learnMoreMethodsRoute, formattedPrice, hasTeam2025Pricing) => + `El plan Recopilar comienza desde ${formattedPrice} ${hasTeam2025Pricing ? `por miembro al mes.` : `por miembro activo al mes.`} Más información sobre nuestros planes y precios.`, + note: 'Desbloquea las funciones esenciales para tu negocio, incluyendo:', + }, note: 'Desbloquea nuestras funciones más potentes, incluyendo:', benefits: { startsAtFull: (learnMoreMethodsRoute, formattedPrice, hasTeam2025Pricing) => diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 3fe50df37d3f..54d928aef65c 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -7019,6 +7019,12 @@ Rendez obligatoires des informations de dépense comme les reçus et les descrip }, commonFeatures: { title: 'Passer au forfait Contrôle', + collect: { + title: 'Passer au forfait Collect', + startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => + `Le plan Collect commence à ${formattedPrice} ${hasTeam2025Pricing ? `par membre et par mois.` : `par membre actif et par mois.`} En savoir plus sur nos plans et nos tarifs.`, + note: 'Débloquez les fonctionnalités essentielles pour votre entreprise, notamment :', + }, note: 'Débloquez nos fonctionnalités les plus puissantes, notamment :', benefits: { startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => diff --git a/src/languages/it.ts b/src/languages/it.ts index 23160e7232e6..9492635af08a 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -6977,6 +6977,12 @@ Richiedi dettagli sulle spese come ricevute e descrizioni, imposta limiti e valo }, commonFeatures: { title: 'Passa al piano Control', + collect: { + title: 'Passa al piano Collect', + startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => + `Il piano Collect parte da ${formattedPrice} ${hasTeam2025Pricing ? `per utente al mese.` : `per membro attivo al mese.`} Scopri di più sui nostri piani e prezzi.`, + note: 'Sblocca le funzioni essenziali per la tua attività, tra cui:', + }, note: 'Sblocca le nostre funzioni più potenti, tra cui:', benefits: { startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 0c24a52ba93f..89795fcd605a 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -6903,6 +6903,12 @@ ${reportName} }, commonFeatures: { title: 'Controlプランにアップグレード', + collect: { + title: 'Collectプランにアップグレード', + startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => + `Collect プランは ${formattedPrice} ${hasTeam2025Pricing ? `メンバー1人あたり月額` : `アクティブメンバー1人あたり月額`} からご利用いただけます。プランと料金の詳細は こちら をご覧ください。`, + note: '以下を含む、ビジネスに欠かせない機能をアンロックしましょう:', + }, note: '以下を含む、最も強力な機能をアンロックしましょう:', benefits: { startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => diff --git a/src/languages/nl.ts b/src/languages/nl.ts index bf53a8817f55..a69686930e75 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -6956,6 +6956,12 @@ Vereis onkostendetails zoals bonnen en beschrijvingen, stel limieten en standaar }, commonFeatures: { title: 'Upgrade naar het Control-abonnement', + collect: { + title: 'Upgrade naar het Collect-abonnement', + startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => + `Het Collect-abonnement begint bij ${formattedPrice} ${hasTeam2025Pricing ? `per lid per maand.` : `per actieve deelnemer per maand.`} Meer informatie over onze abonnementen en prijzen.`, + note: 'Ontgrendel essentiële functies voor je bedrijf, waaronder:', + }, note: 'Ontgrendel onze krachtigste functies, waaronder:', benefits: { startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 8f47ceff3e59..d353a9a9aca2 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -6950,6 +6950,12 @@ Wymagaj szczegółów wydatków, takich jak paragony i opisy, ustawiaj limity i }, commonFeatures: { title: 'Ulepsz do planu Control', + collect: { + title: 'Ulepsz do planu Collect', + startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => + `Plan Collect zaczyna się od ${formattedPrice} ${hasTeam2025Pricing ? `za użytkownika miesięcznie.` : `na aktywnego członka miesięcznie.`} Dowiedz się więcej o naszych planach i cenach.`, + note: 'Odblokuj kluczowe funkcje dla swojej firmy, w tym:', + }, note: 'Odblokuj nasze najpotężniejsze funkcje, w tym:', benefits: { startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 9dde33da7528..4ad3cfce0bfe 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -6954,6 +6954,12 @@ Exija dados de despesas como recibos e descrições, defina limites e padrões e }, commonFeatures: { title: 'Faça upgrade para o plano Control', + collect: { + title: 'Faça upgrade para o plano Collect', + startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => + `O plano Collect começa em ${formattedPrice} ${hasTeam2025Pricing ? `por membro por mês.` : `por membro ativo por mês.`} Saiba mais sobre nossos planos e preços.`, + note: 'Desbloqueie os recursos essenciais para o seu negócio, incluindo:', + }, note: 'Desbloqueie nossos recursos mais avançados, incluindo:', benefits: { startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 7773e3384e5e..d5bfb573152c 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -6780,6 +6780,12 @@ ${reportName} }, commonFeatures: { title: '升级到 Control 方案', + collect: { + title: '升级到 Collect 方案', + startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => + `Collect 方案起价为 ${formattedPrice} ${hasTeam2025Pricing ? `每位成员每月。` : `每位活跃成员每月。`},了解更多我们的方案和定价。`, + note: '解锁助力您业务发展的核心功能,包括:', + }, note: '解锁我们最强大的功能,包括:', benefits: { startsAtFull: (learnMoreMethodsRoute: string, formattedPrice: string, hasTeam2025Pricing: boolean) => diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 7a8a9331de99..043baf1d6e60 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -429,6 +429,7 @@ type SettingsNavigatorParamList = { // eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md backTo?: Routes; categoryId?: string; + upgradePlanType?: ValueOf; }; [SCREENS.WORKSPACE.DOWNGRADE]: { policyID?: string; diff --git a/src/pages/workspace/DynamicWorkspaceOverviewPlanTypePage.tsx b/src/pages/workspace/DynamicWorkspaceOverviewPlanTypePage.tsx index 2b787ebe6aba..a75d855a2edb 100644 --- a/src/pages/workspace/DynamicWorkspaceOverviewPlanTypePage.tsx +++ b/src/pages/workspace/DynamicWorkspaceOverviewPlanTypePage.tsx @@ -98,12 +98,12 @@ function DynamicWorkspaceOverviewPlanTypePage({policy}: WithPolicyProps) { // still pick Team/Corporate. Route any selection from a Submit policy to the // upgrade screen — the polished Submit-specific upgrade UX ships in #87263. if (policyID && policy?.type === CONST.POLICY.TYPE.SUBMIT && (currentPlan === CONST.POLICY.TYPE.TEAM || currentPlan === CONST.POLICY.TYPE.CORPORATE)) { - Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID)); + Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, undefined, undefined, currentPlan)); return; } if (policyID && policy?.type === CONST.POLICY.TYPE.TEAM && currentPlan === CONST.POLICY.TYPE.CORPORATE) { - Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID)); + Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, undefined, undefined, currentPlan)); return; } diff --git a/src/pages/workspace/upgrade/GenericFeaturesView.tsx b/src/pages/workspace/upgrade/GenericFeaturesView.tsx index c9ba7363a891..64ac018c9417 100644 --- a/src/pages/workspace/upgrade/GenericFeaturesView.tsx +++ b/src/pages/workspace/upgrade/GenericFeaturesView.tsx @@ -1,5 +1,6 @@ import React from 'react'; import {View} from 'react-native'; +import type {ValueOf} from 'type-fest'; import Button from '@components/Button'; import Icon from '@components/Icon'; import {loadIllustration} from '@components/Icon/IllustrationLoader'; @@ -13,6 +14,7 @@ import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; +import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {Route} from '@src/ROUTES'; @@ -23,9 +25,11 @@ type GenericFeaturesViewProps = { formattedPrice: string; policyID?: string; backTo?: Route; + /** Target plan the user chose to upgrade to. When Collect (TEAM), render Collect copy instead of the default Control copy */ + upgradePlanType?: ValueOf; }; -function GenericFeaturesView({onUpgrade, buttonDisabled, loading, formattedPrice, backTo, policyID}: GenericFeaturesViewProps) { +function GenericFeaturesView({onUpgrade, buttonDisabled, loading, formattedPrice, backTo, policyID, upgradePlanType}: GenericFeaturesViewProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const {environmentURL} = useEnvironment(); @@ -34,12 +38,26 @@ function GenericFeaturesView({onUpgrade, buttonDisabled, loading, formattedPrice const {isExtraSmallScreenWidth} = useResponsiveLayout(); const hasTeam2025Pricing = useHasTeam2025Pricing(); - const benefits = [ - translate('workspace.upgrade.commonFeatures.benefits.benefit1'), - translate('workspace.upgrade.commonFeatures.benefits.benefit2'), - translate('workspace.upgrade.commonFeatures.benefits.benefit3'), - translate('workspace.upgrade.commonFeatures.benefits.benefit4'), - ]; + const isCollectUpgrade = upgradePlanType === CONST.POLICY.TYPE.TEAM; + const title = isCollectUpgrade ? translate('workspace.upgrade.commonFeatures.collect.title') : translate('workspace.upgrade.commonFeatures.title'); + const startsAtFull = isCollectUpgrade + ? translate('workspace.upgrade.commonFeatures.collect.startsAtFull', learnMoreMethodsRoute, formattedPrice, hasTeam2025Pricing) + : translate('workspace.upgrade.commonFeatures.benefits.startsAtFull', learnMoreMethodsRoute, formattedPrice, hasTeam2025Pricing); + const note = isCollectUpgrade ? translate('workspace.upgrade.commonFeatures.collect.note') : translate('workspace.upgrade.commonFeatures.note'); + + const benefits = isCollectUpgrade + ? [ + translate('subscription.yourPlan.collect.benefit1'), + translate('subscription.yourPlan.collect.benefit2'), + translate('subscription.yourPlan.collect.benefit3'), + translate('subscription.yourPlan.collect.benefit4'), + ] + : [ + translate('workspace.upgrade.commonFeatures.benefits.benefit1'), + translate('workspace.upgrade.commonFeatures.benefits.benefit2'), + translate('workspace.upgrade.commonFeatures.benefits.benefit3'), + translate('workspace.upgrade.commonFeatures.benefits.benefit4'), + ]; return ( @@ -51,8 +69,8 @@ function GenericFeaturesView({onUpgrade, buttonDisabled, loading, formattedPrice /> - {translate('workspace.upgrade.commonFeatures.title')} - {translate('workspace.upgrade.commonFeatures.note')} + {title} + {note} {benefits.map((benefit) => ( ))} - + {!policyID && ( diff --git a/src/pages/workspace/upgrade/UpgradeIntro.tsx b/src/pages/workspace/upgrade/UpgradeIntro.tsx index fb249e0e1a6c..2d077c4970de 100644 --- a/src/pages/workspace/upgrade/UpgradeIntro.tsx +++ b/src/pages/workspace/upgrade/UpgradeIntro.tsx @@ -38,9 +38,11 @@ type Props = { isDistanceRateUpgrade?: boolean; policyID?: string; backTo?: Route; + /** Target plan the user chose to upgrade to (drives Collect vs Control copy/pricing in the generic view) */ + upgradePlanType?: ValueOf; }; -function UpgradeIntro({feature, onUpgrade, buttonDisabled, loading, isCategorizing, isDistanceRateUpgrade, isReporting, policyID, backTo}: Props) { +function UpgradeIntro({feature, onUpgrade, buttonDisabled, loading, isCategorizing, isDistanceRateUpgrade, isReporting, policyID, backTo, upgradePlanType}: Props) { const styles = useThemeStyles(); const {isExtraSmallScreenWidth} = useResponsiveLayout(); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); @@ -58,12 +60,14 @@ function UpgradeIntro({feature, onUpgrade, buttonDisabled, loading, isCategorizi const formattedPrice = useMemo(() => { const upgradeCurrency = Object.hasOwn(CONST.SUBSCRIPTION_PRICES, preferredCurrency) ? preferredCurrency : CONST.PAYMENT_CARD_CURRENCY.USD; // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const shouldUseTeamPricing = isCategorizing || isDistanceRateUpgrade || isReporting || isSubmitFeature; + const matchesTeamPricingHeuristics = isCategorizing || isDistanceRateUpgrade || isReporting || isSubmitFeature || upgradePlanType === CONST.POLICY.TYPE.TEAM; + // An explicit upgradePlanType (chosen in the Plan RHP) is authoritative over the feature-based heuristics, so pricing matches the plan title shown in GenericFeaturesView. + const shouldUseTeamPricing = upgradePlanType === CONST.POLICY.TYPE.CORPORATE ? false : matchesTeamPricingHeuristics; return `${convertToShortDisplayString( CONST.SUBSCRIPTION_PRICES[upgradeCurrency][shouldUseTeamPricing ? CONST.POLICY.TYPE.TEAM : CONST.POLICY.TYPE.CORPORATE][CONST.SUBSCRIPTION.TYPE.ANNUAL], upgradeCurrency, )} `; - }, [preferredCurrency, isCategorizing, isDistanceRateUpgrade, isReporting, isSubmitFeature]); + }, [preferredCurrency, isCategorizing, isDistanceRateUpgrade, isReporting, isSubmitFeature, upgradePlanType]); const allIconNames = Object.values(CONST.UPGRADE_FEATURE_INTRO_MAPPING) .map((feat) => feat?.icon) @@ -117,6 +121,7 @@ function UpgradeIntro({feature, onUpgrade, buttonDisabled, loading, isCategorizi loading={loading} policyID={policyID} backTo={backTo} + upgradePlanType={upgradePlanType} /> ); } diff --git a/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx b/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx index 03024b295094..fdbf973f9d9c 100644 --- a/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx +++ b/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx @@ -80,6 +80,9 @@ function WorkspaceUpgradePage({route}: WorkspaceUpgradePageProps) { const isSubmit2026BetaEnabled = isBetaEnabled(CONST.BETAS.SUBMIT_2026); const canAccessSubmitWorkspaceFeatures = canAccessSubmitWorkspaceFeaturesUtils(policy, isSubmit2026BetaEnabled); const featureNameAlias = route.params?.featureName && getFeatureNameAlias(route.params.featureName); + // upgradePlanType comes from the URL, so only honor the plans we explicitly support upgrading to. + const rawUpgradePlanType = route.params?.upgradePlanType; + const upgradePlanType = rawUpgradePlanType === CONST.POLICY.TYPE.TEAM || rawUpgradePlanType === CONST.POLICY.TYPE.CORPORATE ? rawUpgradePlanType : undefined; const [upgradingFromSubmit, setUpgradingFromSubmit] = useState(undefined); useEffect(() => { @@ -173,7 +176,7 @@ function WorkspaceUpgradePage({route}: WorkspaceUpgradePageProps) { } if (canAccessSubmitWorkspaceFeatures) { - const targetType = (feature && 'requiredPlan' in feature ? feature.requiredPlan : undefined) ?? CONST.POLICY.TYPE.TEAM; + const targetType = upgradePlanType ?? (feature && 'requiredPlan' in feature ? feature.requiredPlan : undefined) ?? CONST.POLICY.TYPE.TEAM; upgradeSubmit(policy, targetType, email, accountID, priorFirstDayFreeTrial, priorLastDayFreeTrial); return; } @@ -372,6 +375,7 @@ function WorkspaceUpgradePage({route}: WorkspaceUpgradePageProps) { buttonDisabled={isOffline || !canPerformUpgrade} loading={policy?.isPendingUpgrade} backTo={route.params.backTo} + upgradePlanType={upgradePlanType} /> )} diff --git a/tests/ui/WorkspaceUpgradeTest.tsx b/tests/ui/WorkspaceUpgradeTest.tsx index f0b943dcad99..0aa60d79af9a 100644 --- a/tests/ui/WorkspaceUpgradeTest.tsx +++ b/tests/ui/WorkspaceUpgradeTest.tsx @@ -162,6 +162,58 @@ describe('WorkspaceUpgrade', () => { await waitForBatchedUpdates(); }); + it('should render the Collect plan title and Team pricing when upgradePlanType is team', async () => { + const policy: Policy = LHNTestUtils.getFakePolicy(); + + // Given that a policy is initialized in Onyx + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + }); + + // When the upgrade page is opened with upgradePlanType set to the Collect (Team) plan + const {unmount} = renderPage(SCREENS.WORKSPACE.UPGRADE, {policyID: policy.id, upgradePlanType: CONST.POLICY.TYPE.TEAM}); + await waitForBatchedUpdatesWithAct(); + + // Then the Collect title is shown + expect(await screen.findByText(TestHelper.translateLocal('workspace.upgrade.commonFeatures.collect.title'))).toBeTruthy(); + + // And the Team (Collect) annual price is shown + const teamPrice = convertToShortDisplayString( + CONST.SUBSCRIPTION_PRICES[CONST.PAYMENT_CARD_CURRENCY.USD][CONST.POLICY.TYPE.TEAM][CONST.SUBSCRIPTION.TYPE.ANNUAL], + CONST.PAYMENT_CARD_CURRENCY.USD, + ); + expect(await screen.findByText(teamPrice, {exact: false})).toBeTruthy(); + + unmount(); + await waitForBatchedUpdatesWithAct(); + }); + + it('should render the Control plan title and Corporate pricing when upgradePlanType is corporate', async () => { + const policy: Policy = LHNTestUtils.getFakePolicy(); + + // Given that a policy is initialized in Onyx + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + }); + + // When the upgrade page is opened with upgradePlanType set to the Control (Corporate) plan + const {unmount} = renderPage(SCREENS.WORKSPACE.UPGRADE, {policyID: policy.id, upgradePlanType: CONST.POLICY.TYPE.CORPORATE}); + await waitForBatchedUpdatesWithAct(); + + // Then the Control title is shown + expect(await screen.findByText(TestHelper.translateLocal('workspace.upgrade.commonFeatures.title'))).toBeTruthy(); + + // And the Corporate (Control) annual price is shown + const corporatePrice = convertToShortDisplayString( + CONST.SUBSCRIPTION_PRICES[CONST.PAYMENT_CARD_CURRENCY.USD][CONST.POLICY.TYPE.CORPORATE][CONST.SUBSCRIPTION.TYPE.ANNUAL], + CONST.PAYMENT_CARD_CURRENCY.USD, + ); + expect(await screen.findByText(corporatePrice, {exact: false})).toBeTruthy(); + + unmount(); + await waitForBatchedUpdatesWithAct(); + }); + it("should show the upgrade corporate plan price is in the user's local currency", async () => { // Team policy which the user can upgrade to corporate const policy = LHNTestUtils.getFakePolicy();