From d4057a7bcc5cf5cea219ae789b83c4e5fae2fc20 Mon Sep 17 00:00:00 2001 From: Jessica Lawshe Date: Tue, 7 Feb 2023 09:38:20 -0600 Subject: [PATCH] Merge pull request #11602 from overleaf/jel-react-personal-subscription-dash-pt-6 [web] Continue migration of change plan UI to React GitOrigin-RevId: 4f6176ac101ba3c57134cf5c86329e205f17ab23 --- .../js/features/subscription/data/currency.ts | 15 +++ .../subscription/util/recurly-pricing.tsx | 56 +++++++++ .../institution-memberships.test.tsx | 49 +++----- .../managed-group-subscriptions.test.tsx | 36 +++--- .../dashboard/personal-subscription.test.tsx | 114 ++++++------------ .../dashboard/states/active/active.test.tsx | 90 +++++--------- .../active/change-plan/change-plan.test.tsx | 79 ++++++------ .../dashboard/subscription-dashboard.test.tsx | 19 ++- .../render-with-subscription-dash-context.tsx | 38 ++++++ .../util/recurly-pricing.test.tsx | 47 ++++++++ 10 files changed, 307 insertions(+), 236 deletions(-) create mode 100644 services/web/frontend/js/features/subscription/data/currency.ts create mode 100644 services/web/frontend/js/features/subscription/util/recurly-pricing.tsx create mode 100644 services/web/test/frontend/features/subscription/helpers/render-with-subscription-dash-context.tsx create mode 100644 services/web/test/frontend/features/subscription/util/recurly-pricing.test.tsx diff --git a/services/web/frontend/js/features/subscription/data/currency.ts b/services/web/frontend/js/features/subscription/data/currency.ts new file mode 100644 index 0000000000..ad82a701ce --- /dev/null +++ b/services/web/frontend/js/features/subscription/data/currency.ts @@ -0,0 +1,15 @@ +export const currencies = { + USD: '$', + EUR: '€', + GBP: '£', + SEK: 'kr', + CAD: '$', + NOK: 'kr', + DKK: 'kr', + AUD: '$', + NZD: '$', + CHF: 'Fr', + SGD: '$', +} + +export type CurrencyCode = keyof typeof currencies diff --git a/services/web/frontend/js/features/subscription/util/recurly-pricing.tsx b/services/web/frontend/js/features/subscription/util/recurly-pricing.tsx new file mode 100644 index 0000000000..640584cc24 --- /dev/null +++ b/services/web/frontend/js/features/subscription/util/recurly-pricing.tsx @@ -0,0 +1,56 @@ +import { SubscriptionPricingState } from '@recurly/recurly-js' +import getMeta from '../../../utils/meta' +import { currencies, CurrencyCode } from '../data/currency' + +export function formatPriceForDisplayData(price: string, taxRate: number) { + const currencyCode: CurrencyCode = getMeta('ol-recommendedCurrency') + const currencySymbol = currencies[currencyCode] + + const totalPriceExTax = parseFloat(price) + let taxAmount = totalPriceExTax * taxRate + if (isNaN(taxAmount)) { + taxAmount = 0 + } + const totalWithTax = totalPriceExTax + taxAmount + + return { + totalForDisplay: `${currencySymbol}${ + totalWithTax % 1 !== 0 ? totalWithTax.toFixed(2) : totalWithTax + }`, + totalAsNumber: totalWithTax, + subtotal: `${currencySymbol}${totalPriceExTax.toFixed(2)}`, + tax: `${currencySymbol}${taxAmount.toFixed(2)}`, + includesTax: taxAmount !== 0, + } +} + +export function loadDisplayPriceWithTaxPromise( + planCode: string, + currency: CurrencyCode, + taxRate: number +) { + if (!recurly) return + + return new Promise | undefined>( + resolve => { + recurly.Pricing.Subscription() + .plan(planCode, { quantity: 1 }) + .currency(currency) + .catch(function (error) { + console.error(error) + }) + .done(response => { + if (response) { + const price = + response as unknown as SubscriptionPricingState['price'] + // type expects response to be {price: {next: ...}} + // but the real response is {next: ...} + const data = formatPriceForDisplayData(price.next.total, taxRate) + resolve(data) + } else { + resolve(undefined) + } + }) + } + ) +} diff --git a/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx index 8ab71902bb..39b532ccde 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/institution-memberships.test.tsx @@ -1,7 +1,10 @@ import { expect } from 'chai' -import { render, screen } from '@testing-library/react' +import { screen } from '@testing-library/react' import InstitutionMemberships from '../../../../../../frontend/js/features/subscription/components/dashboard/institution-memberships' -import { SubscriptionDashboardProvider } from '../../../../../../frontend/js/features/subscription/context/subscription-dashboard-context' +import { + cleanUpContext, + renderWithSubscriptionDashContext, +} from '../../helpers/render-with-subscription-dash-context' const memberships = [ { @@ -27,25 +30,16 @@ const memberships = [ ] describe('', function () { - beforeEach(function () { - window.metaAttributesCache = new Map() - }) - afterEach(function () { - window.metaAttributesCache = new Map() + cleanUpContext() }) it('renders all insitutions with license', function () { - window.metaAttributesCache.set( - 'ol-currentInstitutionsWithLicence', - memberships - ) - - render( - - - - ) + renderWithSubscriptionDashContext(, { + metaTags: [ + { name: 'ol-currentInstitutionsWithLicence', value: memberships }, + ], + }) const elements = screen.getAllByText('You are on our', { exact: false, @@ -60,27 +54,18 @@ describe('', function () { }) it('renders error message when failed to check commons licenses', function () { - render( - - - - ) + renderWithSubscriptionDashContext() screen.getByText( 'Sorry, something went wrong. Subscription information related to institutional affiliations may not be displayed. Please try again later.' ) }) it('renders the "Get the most out of your" subscription text when a user has a subscription', function () { - window.metaAttributesCache.set( - 'ol-currentInstitutionsWithLicence', - memberships - ) - - render( - - - - ) + renderWithSubscriptionDashContext(, { + metaTags: [ + { name: 'ol-currentInstitutionsWithLicence', value: memberships }, + ], + }) screen.getByText('Get the most out of your', { exact: false, }) diff --git a/services/web/test/frontend/features/subscription/components/dashboard/managed-group-subscriptions.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/managed-group-subscriptions.test.tsx index 0c4686fb29..55771854cc 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/managed-group-subscriptions.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/managed-group-subscriptions.test.tsx @@ -1,12 +1,15 @@ import { expect } from 'chai' -import { render, screen } from '@testing-library/react' +import { screen } from '@testing-library/react' import { groupActiveSubscription, groupActiveSubscriptionWithPendingLicenseChange, } from '../../fixtures/subscriptions' import ManagedGroupSubscriptions from '../../../../../../frontend/js/features/subscription/components/dashboard/managed-group-subscriptions' import { ManagedGroupSubscription } from '../../../../../../types/subscription/dashboard/subscription' -import { SubscriptionDashboardProvider } from '../../../../../../frontend/js/features/subscription/context/subscription-dashboard-context' +import { + cleanUpContext, + renderWithSubscriptionDashContext, +} from '../../helpers/render-with-subscription-dash-context' const managedGroupSubscriptions: ManagedGroupSubscription[] = [ { @@ -30,24 +33,19 @@ const managedGroupSubscriptions: ManagedGroupSubscription[] = [ ] describe('', function () { - beforeEach(function () { - window.metaAttributesCache = new Map() - }) - afterEach(function () { - window.metaAttributesCache = new Map() + cleanUpContext() }) it('renders all managed group subscriptions', function () { - window.metaAttributesCache.set( - 'ol-managedGroupSubscriptions', - managedGroupSubscriptions - ) - render( - - - - ) + renderWithSubscriptionDashContext(, { + metaTags: [ + { + name: 'ol-managedGroupSubscriptions', + value: managedGroupSubscriptions, + }, + ], + }) const elements = screen.getAllByText('You are a', { exact: false, @@ -91,11 +89,7 @@ describe('', function () { }) it('renders nothing when there are no group memberships', function () { - render( - - - - ) + renderWithSubscriptionDashContext() const elements = screen.queryAllByText('You are a', { exact: false, }) diff --git a/services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx index 1487e4043a..7fc31a9aad 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx @@ -1,32 +1,25 @@ import { expect } from 'chai' -import { render, screen } from '@testing-library/react' +import { screen } from '@testing-library/react' import PersonalSubscription from '../../../../../../frontend/js/features/subscription/components/dashboard/personal-subscription' -import { SubscriptionDashboardProvider } from '../../../../../../frontend/js/features/subscription/context/subscription-dashboard-context' import { annualActiveSubscription, canceledSubscription, pastDueExpiredSubscription, } from '../../fixtures/subscriptions' +import { + cleanUpContext, + renderWithSubscriptionDashContext, +} from '../../helpers/render-with-subscription-dash-context' describe('', function () { - beforeEach(function () { - window.metaAttributesCache = new Map() - // @ts-ignore - window.recurly = {} - }) - afterEach(function () { - window.metaAttributesCache = new Map() - // @ts-ignore - delete window.recurly + cleanUpContext() }) describe('no subscription', function () { it('returns empty container', function () { - const { container } = render( - - - + const { container } = renderWithSubscriptionDashContext( + ) expect(container.firstChild).to.be.null }) @@ -34,26 +27,19 @@ describe('', function () { describe('subscription states ', function () { it('renders the active dash', function () { - window.metaAttributesCache.set( - 'ol-subscription', - annualActiveSubscription - ) - render( - - - - ) + renderWithSubscriptionDashContext(, { + metaTags: [ + { name: 'ol-subscription', value: annualActiveSubscription }, + ], + }) screen.getByText('You are currently subscribed to the', { exact: false }) }) it('renders the canceled dash', function () { - window.metaAttributesCache.set('ol-subscription', canceledSubscription) - render( - - - - ) + renderWithSubscriptionDashContext(, { + metaTags: [{ name: 'ol-subscription', value: canceledSubscription }], + }) screen.getByText( 'Your subscription has been canceled and will terminate on', { exact: false } @@ -74,15 +60,11 @@ describe('', function () { }) it('renders the expired dash', function () { - window.metaAttributesCache.set( - 'ol-subscription', - pastDueExpiredSubscription - ) - render( - - - - ) + renderWithSubscriptionDashContext(, { + metaTags: [ + { name: 'ol-subscription', value: pastDueExpiredSubscription }, + ], + }) screen.getByText('Your subscription has expired.') }) @@ -92,12 +74,9 @@ describe('', function () { JSON.parse(JSON.stringify(annualActiveSubscription)) ) withStateDeleted.recurly.state = undefined - window.metaAttributesCache.set('ol-subscription', withStateDeleted) - render( - - - - ) + renderWithSubscriptionDashContext(, { + metaTags: [{ name: 'ol-subscription', value: withStateDeleted }], + }) screen.getByText( 'There is a problem with your subscription. Please contact us for more information.' ) @@ -106,15 +85,11 @@ describe('', function () { describe('past due subscription', function () { it('renders error alert', function () { - window.metaAttributesCache.set( - 'ol-subscription', - pastDueExpiredSubscription - ) - render( - - - - ) + renderWithSubscriptionDashContext(, { + metaTags: [ + { name: 'ol-subscription', value: pastDueExpiredSubscription }, + ], + }) screen.getByRole('alert') screen.getByText( 'Your account currently has a past due invoice. You will not be able to change your plan until this is resolved.', @@ -132,17 +107,12 @@ describe('', function () { 'Sorry, there was an error talking to our payment provider. Please try again in a few moments. If you are using any ad or script blocking extensions in your browser, you may need to temporarily disable them.' it('shows an alert and hides "Change plan" option when Recurly did not load', function () { - // @ts-ignore - delete window.recurly - window.metaAttributesCache.set( - 'ol-subscription', - annualActiveSubscription - ) - render( - - - - ) + renderWithSubscriptionDashContext(, { + metaTags: [ + { name: 'ol-subscription', value: annualActiveSubscription }, + ], + recurlyNotLoaded: true, + }) screen.getByRole('alert') screen.getByText(recurlyFailedToLoadText) @@ -151,15 +121,11 @@ describe('', function () { }) it('should not show an alert and should show "Change plan" option when Recurly did load', function () { - window.metaAttributesCache.set( - 'ol-subscription', - annualActiveSubscription - ) - render( - - - - ) + renderWithSubscriptionDashContext(, { + metaTags: [ + { name: 'ol-subscription', value: annualActiveSubscription }, + ], + }) expect(screen.queryByRole('alert')).to.be.null diff --git a/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx index fcb67b99d4..20734a4ed7 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx @@ -1,8 +1,7 @@ import { expect } from 'chai' -import { fireEvent, render, screen } from '@testing-library/react' +import { fireEvent, screen } from '@testing-library/react' import * as eventTracking from '../../../../../../../../frontend/js/infrastructure/event-tracking' import { ActiveSubscription } from '../../../../../../../../frontend/js/features/subscription/components/dashboard/states/active/active' -import { SubscriptionDashboardProvider } from '../../../../../../../../frontend/js/features/subscription/context/subscription-dashboard-context' import { Subscription } from '../../../../../../../../types/subscription/dashboard/subscription' import { annualActiveSubscription, @@ -13,22 +12,20 @@ import { } from '../../../../fixtures/subscriptions' import sinon from 'sinon' import { plans } from '../../../../fixtures/plans' +import { + cleanUpContext, + renderWithSubscriptionDashContext, +} from '../../../../helpers/render-with-subscription-dash-context' describe('', function () { let sendMBSpy: sinon.SinonSpy beforeEach(function () { - window.metaAttributesCache = new Map() - window.metaAttributesCache.set('ol-plans', plans) - // @ts-ignore - window.recurly = {} sendMBSpy = sinon.spy(eventTracking, 'sendMB') }) afterEach(function () { - window.metaAttributesCache = new Map() - // @ts-ignore - delete window.recurly + cleanUpContext() sendMBSpy.restore() }) @@ -64,21 +61,26 @@ describe('', function () { screen.getByRole('link', { name: 'View Your Invoices' }) } - it('renders the dash annual active subscription', function () { - render( - - - + function renderActiveSubscription(subscription: Subscription) { + const renderOptions = { + metaTags: [ + { name: 'ol-plans', value: plans }, + { name: 'ol-subscription', value: subscription }, + ], + } + renderWithSubscriptionDashContext( + , + renderOptions ) + } + + it('renders the dash annual active subscription', function () { + renderActiveSubscription(annualActiveSubscription) expectedInActiveSubscription(annualActiveSubscription) }) it('shows change plan UI when button clicked', function () { - render( - - - - ) + renderActiveSubscription(annualActiveSubscription) const button = screen.getByRole('button', { name: 'Change plan' }) fireEvent.click(button) @@ -93,11 +95,7 @@ describe('', function () { }) it('notes when user is changing plan at end of current plan term', function () { - render( - - - - ) + renderActiveSubscription(pendingSubscriptionChange) expectedInActiveSubscription(pendingSubscriptionChange) @@ -126,24 +124,14 @@ describe('', function () { activePastDueSubscription.recurly.account.has_past_due_invoice._ = 'true' - render( - - - - ) + renderActiveSubscription(activePastDueSubscription) const changePlan = screen.queryByRole('button', { name: 'Change plan' }) expect(changePlan).to.be.null }) it('shows the pending license change message when plan change is pending', function () { - render( - - - - ) + renderActiveSubscription(groupActiveSubscriptionWithPendingLicenseChange) screen.getByText('Your subscription is changing to include', { exact: false, @@ -175,11 +163,7 @@ describe('', function () { subscription.recurly.totalLicenses + subscription.recurly.additionalLicenses - render( - - - - ) + renderActiveSubscription(subscription) screen.getByText('Your subscription includes', { exact: false, @@ -193,11 +177,7 @@ describe('', function () { }) it('shows when trial ends and first payment collected', function () { - render( - - - - ) + renderActiveSubscription(trialSubscription) screen.getByText('You’re on a free trial which ends on', { exact: false }) const endDate = screen.getAllByText( @@ -207,11 +187,7 @@ describe('', function () { }) it('shows cancel UI and sends event', function () { - render( - - - - ) + renderActiveSubscription(annualActiveSubscription) // before button clicked screen.getByText( 'Your subscription will remain active until the end of your billing period', @@ -238,22 +214,14 @@ describe('', function () { describe('group plans', function () { it('does not show "Change plan" option for group plans', function () { - render( - - - - ) + renderActiveSubscription(groupActiveSubscription) const changePlan = screen.queryByRole('button', { name: 'Change plan' }) expect(changePlan).to.be.null }) it('shows contact support message for group plan change requests', function () { - render( - - - - ) + renderActiveSubscription(groupActiveSubscription) screen.getByRole('link', { name: 'contact support' }) screen.getByText('if you wish to change your group subscription.', { exact: false, diff --git a/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx index f3acca284d..f988490e0b 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx @@ -1,6 +1,5 @@ import { expect } from 'chai' -import { fireEvent, render, screen } from '@testing-library/react' -import { SubscriptionDashboardProvider } from '../../../../../../../../../frontend/js/features/subscription/context/subscription-dashboard-context' +import { fireEvent, screen } from '@testing-library/react' import { ChangePlan } from '../../../../../../../../../frontend/js/features/subscription/components/dashboard/states/active/change-plan/change-plan' import { plans } from '../../../../../fixtures/plans' import { @@ -8,38 +7,38 @@ import { pendingSubscriptionChange, } from '../../../../../fixtures/subscriptions' import { ActiveSubscription } from '../../../../../../../../../frontend/js/features/subscription/components/dashboard/states/active/active' +import { + cleanUpContext, + renderWithSubscriptionDashContext, +} from '../../../../../helpers/render-with-subscription-dash-context' describe('', function () { - beforeEach(function () { - window.metaAttributesCache = new Map() - window.metaAttributesCache.set('ol-plans', plans) - // @ts-ignore - window.recurly = {} - }) + const plansMetaTag = { name: 'ol-plans', value: plans } + const renderOptions = { metaTags: [plansMetaTag] } afterEach(function () { - window.metaAttributesCache = new Map() - // @ts-ignore - delete window.recurly + cleanUpContext() }) it('does not render the UI when showChangePersonalPlan is false', function () { window.metaAttributesCache.delete('ol-plans') - const { container } = render( - - - + const { container } = renderWithSubscriptionDashContext( + , + renderOptions ) expect(container.firstChild).to.be.null }) it('renders the individual plans table', function () { - window.metaAttributesCache.set('ol-subscription', annualActiveSubscription) - render( - - - + renderWithSubscriptionDashContext( + , + { + metaTags: [ + { name: 'ol-subscription', value: annualActiveSubscription }, + plansMetaTag, + ], + } ) const button = screen.getByRole('button', { name: 'Change plan' }) @@ -59,11 +58,14 @@ describe('', function () { }) it('renders the change to group plan UI', function () { - window.metaAttributesCache.set('ol-subscription', annualActiveSubscription) - render( - - - + renderWithSubscriptionDashContext( + , + { + metaTags: [ + { name: 'ol-subscription', value: annualActiveSubscription }, + plansMetaTag, + ], + } ) const button = screen.getByRole('button', { name: 'Change plan' }) @@ -73,11 +75,14 @@ describe('', function () { }) it('renders "Your new plan" and "Keep current plan" when there is a pending plan change', function () { - window.metaAttributesCache.set('ol-subscription', pendingSubscriptionChange) - render( - - - + renderWithSubscriptionDashContext( + , + { + metaTags: [ + { name: 'ol-subscription', value: pendingSubscriptionChange }, + plansMetaTag, + ], + } ) const button = screen.getByRole('button', { name: 'Change plan' }) @@ -88,12 +93,14 @@ describe('', function () { }) it('does not render when Recurly did not load', function () { - // @ts-ignore - delete window.recurly - const { container } = render( - - - + const { container } = renderWithSubscriptionDashContext( + , + { + metaTags: [ + { name: 'ol-subscription', value: annualActiveSubscription }, + plansMetaTag, + ], + } ) expect(container).not.to.be.null }) diff --git a/services/web/test/frontend/features/subscription/components/dashboard/subscription-dashboard.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/subscription-dashboard.test.tsx index 6f329e2822..796956dcff 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/subscription-dashboard.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/subscription-dashboard.test.tsx @@ -1,24 +1,19 @@ import { expect } from 'chai' -import { render, screen } from '@testing-library/react' +import { screen } from '@testing-library/react' import SubscriptionDashboard from '../../../../../../frontend/js/features/subscription/components/dashboard/subscription-dashboard' -import { SubscriptionDashboardProvider } from '../../../../../../frontend/js/features/subscription/context/subscription-dashboard-context' +import { + cleanUpContext, + renderWithSubscriptionDashContext, +} from '../../helpers/render-with-subscription-dash-context' describe('', function () { - beforeEach(function () { - window.metaAttributesCache = new Map() - }) - afterEach(function () { - window.metaAttributesCache = new Map() + cleanUpContext() }) describe('Free Plan', function () { it('does not render the "Get the most out of your" subscription text', function () { - render( - - - - ) + renderWithSubscriptionDashContext() const text = screen.queryByText('Get the most out of your', { exact: false, }) diff --git a/services/web/test/frontend/features/subscription/helpers/render-with-subscription-dash-context.tsx b/services/web/test/frontend/features/subscription/helpers/render-with-subscription-dash-context.tsx new file mode 100644 index 0000000000..62a6ea27d7 --- /dev/null +++ b/services/web/test/frontend/features/subscription/helpers/render-with-subscription-dash-context.tsx @@ -0,0 +1,38 @@ +import { render } from '@testing-library/react' +import { SubscriptionDashboardProvider } from '../../../../../frontend/js/features/subscription/context/subscription-dashboard-context' + +export function renderWithSubscriptionDashContext( + component: React.ReactElement, + options?: { + metaTags?: { name: string; value: string | object | Array }[] + recurlyNotLoaded?: boolean + } +) { + const SubscriptionDashboardProviderWrapper = ({ + children, + }: { + children: React.ReactNode + }) => ( + {children} + ) + + window.metaAttributesCache = new Map() + options?.metaTags?.forEach(tag => + window.metaAttributesCache.set(tag.name, tag.value) + ) + + if (!options?.recurlyNotLoaded) { + // @ts-ignore + window.recurly = {} + } + + return render(component, { + wrapper: SubscriptionDashboardProviderWrapper, + }) +} + +export function cleanUpContext() { + // @ts-ignore + delete window.recurly + window.metaAttributesCache = new Map() +} diff --git a/services/web/test/frontend/features/subscription/util/recurly-pricing.test.tsx b/services/web/test/frontend/features/subscription/util/recurly-pricing.test.tsx new file mode 100644 index 0000000000..a9a62aabcb --- /dev/null +++ b/services/web/test/frontend/features/subscription/util/recurly-pricing.test.tsx @@ -0,0 +1,47 @@ +import { expect } from 'chai' +import { formatPriceForDisplayData } from '../../../../../frontend/js/features/subscription/util/recurly-pricing' + +describe('formatPriceForDisplayData', function () { + beforeEach(function () { + window.metaAttributesCache = new Map() + }) + afterEach(function () { + window.metaAttributesCache = new Map() + }) + it('should handle no tax rate', function () { + window.metaAttributesCache.set('ol-recommendedCurrency', 'USD') + const data = formatPriceForDisplayData('1000', 0) + expect(data).to.deep.equal({ + totalForDisplay: '$1000', + totalAsNumber: 1000, + subtotal: '$1000.00', + tax: '$0.00', + includesTax: false, + }) + window.metaAttributesCache = new Map() + }) + + it('should handle a tax rate', function () { + window.metaAttributesCache.set('ol-recommendedCurrency', 'EUR') + const data = formatPriceForDisplayData('380', 0.2) + expect(data).to.deep.equal({ + totalForDisplay: '€456', + totalAsNumber: 456, + subtotal: '€380.00', + tax: '€76.00', + includesTax: true, + }) + }) + + it('should handle total with cents', function () { + window.metaAttributesCache.set('ol-recommendedCurrency', 'EUR') + const data = formatPriceForDisplayData('8', 0.2) + expect(data).to.deep.equal({ + totalForDisplay: '€9.60', + totalAsNumber: 9.6, + subtotal: '€8.00', + tax: '€1.60', + includesTax: true, + }) + }) +})