Skip to content

Commit

Permalink
Plans (State): Update useMaxPlanUpgradeCredits to utilise Plans data-…
Browse files Browse the repository at this point in the history
…store pricing (#92925)
  • Loading branch information
chriskmnds authored Sep 12, 2024
1 parent 57688b4 commit f67e141
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 85 deletions.
15 changes: 15 additions & 0 deletions client/blocks/importer/wordpress/upgrade-plan/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import nock from 'nock';
import React, { type ComponentPropsWithoutRef } from 'react';
import useCheckPlanAvailabilityForPurchase from 'calypso/my-sites/plans-features-main/hooks/use-check-plan-availability-for-purchase';
import { renderWithProvider } from 'calypso/test-helpers/testing-library';
import { useUpgradePlanHostingDetailsList } from '../hooks/use-get-upgrade-plan-hosting-details-list';
import { UpgradePlan, UnwrappedUpgradePlan } from '../index';
Expand All @@ -19,6 +20,11 @@ jest.mock( '../upgrade-plan-details', () => ( {
default: ( { children } ) => <div>{ children }</div>,
} ) );

jest.mock(
'calypso/my-sites/plans-features-main/hooks/use-check-plan-availability-for-purchase',
() => jest.fn()
);

jest.mock( '@automattic/calypso-analytics' );

jest.mock( '../hooks/use-get-upgrade-plan-hosting-details-list' );
Expand Down Expand Up @@ -165,8 +171,17 @@ describe( 'UpgradePlan', () => {
beforeAll( () => nock.disableNetConnect() );

beforeEach( () => {
jest.clearAllMocks();
mockUseUpgradePlanHostingDetailsList( false );
mockUsePricingMetaForGridPlans();
useCheckPlanAvailabilityForPurchase.mockImplementation( ( { planSlugs } ) =>
planSlugs.reduce( ( acc, planSlug ) => {
return {
...acc,
[ planSlug ]: true,
};
}, {} )
);
} );

it( 'should call onCtaClick when the user clicks on the Continue button', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ const PlanNoticeCreditUpgrade = ( {
args: {
amountInCurrency: formatCurrency(
planUpgradeCreditsApplicable,
currencyCode ?? ''
currencyCode ?? '',
{
isSmallestUnit: true,
}
),
},
components: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@ describe( '<PlanNotice /> Tests', () => {
mIsCurrentUserCurrentPlanOwner.mockImplementation( () => true );
mIsRequestingSitePlans.mockImplementation( () => true );
mGetCurrentUserCurrencyCode.mockImplementation( () => 'USD' );
mUsePlanUpgradeCreditsApplicable.mockImplementation( () => 1 );
mUsePlanUpgradeCreditsApplicable.mockImplementation( () => 100 );
mGetByPurchaseId.mockImplementation( () => ( { isInAppPurchase: false } ) as Purchase );
mIsProPlan.mockImplementation( () => false );
} );

test( 'A contact site owner <PlanNotice /> should be shown no matter what other conditions are met, when the current site owner is not logged in, and the site plan is paid', () => {
mGetDiscountByName.mockImplementation( () => discount );
mUsePlanUpgradeCreditsApplicable.mockImplementation( () => 1 );
mUsePlanUpgradeCreditsApplicable.mockImplementation( () => 100 );
mIsCurrentPlanPaid.mockImplementation( () => true );
mIsCurrentUserCurrentPlanOwner.mockImplementation( () => false );

Expand All @@ -132,7 +132,7 @@ describe( '<PlanNotice /> Tests', () => {
mIsCurrentUserCurrentPlanOwner.mockImplementation( () => true );
mIsCurrentPlanPaid.mockImplementation( () => true );
mGetDiscountByName.mockImplementation( () => discount );
mUsePlanUpgradeCreditsApplicable.mockImplementation( () => 1 );
mUsePlanUpgradeCreditsApplicable.mockImplementation( () => 100 );

renderWithProvider(
<PlanNotice
Expand All @@ -149,7 +149,7 @@ describe( '<PlanNotice /> Tests', () => {
mIsCurrentUserCurrentPlanOwner.mockImplementation( () => true );
mIsCurrentPlanPaid.mockImplementation( () => true );
mGetDiscountByName.mockImplementation( () => false );
mUsePlanUpgradeCreditsApplicable.mockImplementation( () => 100 );
mUsePlanUpgradeCreditsApplicable.mockImplementation( () => 10000 );

renderWithProvider(
<PlanNotice
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,75 +8,61 @@ import {
PLAN_ECOMMERCE,
PLAN_FREE,
} from '@automattic/calypso-products';
import { getPlanDiscountedRawPrice } from 'calypso/state/sites/plans/selectors';
import { getSitePlanRawPrice } from 'calypso/state/sites/plans/selectors/get-site-plan-raw-price';
import isPlanAvailableForPurchase from 'calypso/state/sites/plans/selectors/is-plan-available-for-purchase';
import { Plans } from '@automattic/data-stores';
import useCheckPlanAvailabilityForPurchase from 'calypso/my-sites/plans-features-main/hooks/use-check-plan-availability-for-purchase';
import { renderHookWithProvider } from 'calypso/test-helpers/testing-library';
import { useMaxPlanUpgradeCredits } from '../use-max-plan-upgrade-credits';
import type { PlanSlug } from '@automattic/calypso-products';

jest.mock( 'calypso/state/sites/plans/selectors/is-plan-available-for-purchase', () => ( {
__esModule: true,
default: jest.fn(),
} ) );
jest.mock(
'calypso/my-sites/plans-features-main/hooks/use-check-plan-availability-for-purchase',
() => jest.fn()
);

jest.mock( 'calypso/state/sites/plans/selectors', () => ( {
getPlanDiscountedRawPrice: jest.fn(),
} ) );
jest.mock( 'calypso/state/sites/plans/selectors/get-site-plan-raw-price', () => ( {
getSitePlanRawPrice: jest.fn(),
jest.mock( '@automattic/data-stores', () => ( {
...jest.requireActual( '@automattic/data-stores' ),
Plans: {
...jest.requireActual( '@automattic/data-stores' ).Plans,
usePricingMetaForGridPlans: jest.fn(),
},
} ) );

const mGetPlanDiscountedRawPrice = getPlanDiscountedRawPrice as jest.MockedFunction<
typeof getPlanDiscountedRawPrice
>;
const mGetSitePlanRawPrice = getSitePlanRawPrice as jest.MockedFunction<
typeof getSitePlanRawPrice
>;
const mIsPlanAvailableForPurchase = isPlanAvailableForPurchase as jest.MockedFunction<
typeof isPlanAvailableForPurchase
>;

const siteId = 9999999;
const plans: PlanSlug[] = [ PLAN_FREE, PLAN_PERSONAL, PLAN_PREMIUM, PLAN_BUSINESS, PLAN_ECOMMERCE ];

describe( 'useCalculateMaxPlanUpgradeCredit hook', () => {
beforeEach( () => {
jest.resetAllMocks();
mGetSitePlanRawPrice.mockImplementation( ( _state, _siteId, planSlug ) => {
switch ( planSlug ) {
case PLAN_FREE:
return 2000;
case PLAN_PERSONAL:
return 4000;
case PLAN_PREMIUM:
return 6000;
case PLAN_BUSINESS:
return 8000;
case PLAN_ECOMMERCE:
return 10000;
default:
return 0;
}
} );
mGetPlanDiscountedRawPrice.mockImplementation( ( _state, _siteId, planSlug ) => {
switch ( planSlug ) {
case PLAN_FREE:
return 2000 * 0.9;
case PLAN_PERSONAL:
return 4000 * 0.9;
case PLAN_PREMIUM:
return 6000 * 0.9;
case PLAN_BUSINESS:
return 8000 * 0.9;
case PLAN_ECOMMERCE:
return 10000 * 0.9;
default:
return 0;
}
} );

mIsPlanAvailableForPurchase.mockImplementation( () => true );
Plans.usePricingMetaForGridPlans.mockImplementation( () => ( {
[ PLAN_FREE ]: {
originalPrice: { full: 2000 },
discountedPrice: { full: 2000 * 0.9 },
},
[ PLAN_PERSONAL ]: {
originalPrice: { full: 4000 },
discountedPrice: { full: 4000 * 0.9 },
},
[ PLAN_PREMIUM ]: {
originalPrice: { full: 6000 },
discountedPrice: { full: 6000 * 0.9 },
},
[ PLAN_BUSINESS ]: {
originalPrice: { full: 8000 },
discountedPrice: { full: 8000 * 0.9 },
},
[ PLAN_ECOMMERCE ]: {
originalPrice: { full: 10000 },
discountedPrice: { full: 10000 * 0.9 },
},
} ) );
useCheckPlanAvailabilityForPurchase.mockImplementation( ( { planSlugs } ) =>
planSlugs.reduce( ( acc, planSlug ) => {
return {
...acc,
[ planSlug ]: true,
};
}, {} )
);
} );

test( 'Return the correct amount of credits given a plan list', () => {
Expand All @@ -87,8 +73,13 @@ describe( 'useCalculateMaxPlanUpgradeCredit hook', () => {
} );

test( 'Return the next correct credit amount when ecommerce plan is not available for purchase', () => {
mIsPlanAvailableForPurchase.mockImplementation(
( _state, _siteId, planName ) => ! ( planName === PLAN_ECOMMERCE )
useCheckPlanAvailabilityForPurchase.mockImplementation( ( { planSlugs } ) =>
planSlugs.reduce( ( acc, planSlug ) => {
return {
...acc,
[ planSlug ]: planSlug !== PLAN_ECOMMERCE,
};
}, {} )
);

const { result } = renderHookWithProvider( () =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { useSelector } from 'calypso/state';
import { getPlanDiscountedRawPrice } from 'calypso/state/sites/plans/selectors';
import { getSitePlanRawPrice } from 'calypso/state/sites/plans/selectors/get-site-plan-raw-price';
import isPlanAvailableForPurchase from 'calypso/state/sites/plans/selectors/is-plan-available-for-purchase';
import { Plans } from '@automattic/data-stores';
import useCheckPlanAvailabilityForPurchase from './use-check-plan-availability-for-purchase';
import type { PlanSlug } from '@automattic/calypso-products';

interface Props {
Expand All @@ -15,30 +13,37 @@ interface Props {
* @returns {number} The maximum amount of credits possible for a given set of plans
*/
export function useMaxPlanUpgradeCredits( { siteId, plans }: Props ): number {
const plansDetails = useSelector( ( state ) =>
plans.map( ( planName ) => ( {
isPlanAvailableForPurchase: isPlanAvailableForPurchase( state, siteId ?? 0, planName ),
planDiscountedRawPrice: getPlanDiscountedRawPrice( state, siteId ?? 0, planName ),
sitePlanRawPrice: getSitePlanRawPrice( state, siteId ?? 0, planName ),
} ) )
);
const planAvailabilityForPurchase = useCheckPlanAvailabilityForPurchase( {
planSlugs: plans,
siteId,
} );
const pricing = Plans.usePricingMetaForGridPlans( {
siteId,
planSlugs: plans,
storageAddOns: null,
coupon: undefined,
useCheckPlanAvailabilityForPurchase,
withProratedDiscounts: true,
} );

if ( ! siteId ) {
if ( ! siteId || ! pricing ) {
return 0;
}

const creditsPerPlan = plansDetails.map(
( { isPlanAvailableForPurchase, planDiscountedRawPrice, sitePlanRawPrice } ) => {
if ( ! isPlanAvailableForPurchase ) {
return 0;
}
if ( typeof planDiscountedRawPrice !== 'number' || typeof sitePlanRawPrice !== 'number' ) {
return 0;
}
const creditsPerPlan = plans.map( ( planSlug ) => {
const discountedPrice = pricing?.[ planSlug ]?.discountedPrice.full;
const originalPrice = pricing?.[ planSlug ]?.originalPrice.full;

return sitePlanRawPrice - planDiscountedRawPrice;
if (
! planAvailabilityForPurchase[ planSlug ] ||
typeof discountedPrice !== 'number' ||
typeof originalPrice !== 'number'
) {
return 0;
}
);

return originalPrice - discountedPrice;
} );

return Math.max( ...creditsPerPlan );
}

0 comments on commit f67e141

Please sign in to comment.