|
|
@@ -1,19 +1,29 @@
|
|
|
+import { expect } from 'chai'
|
|
|
import { fireEvent, render, screen } from '@testing-library/react'
|
|
|
-import { ActiveSubsciption } from '../../../../../../../frontend/js/features/subscription/components/dashboard/states/active'
|
|
|
+import * as eventTracking from '../../../../../../../frontend/js/infrastructure/event-tracking'
|
|
|
+import { ActiveSubsciption } 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,
|
|
|
+ groupActiveSubscription,
|
|
|
+ groupActiveSubscriptionWithPendingLicenseChange,
|
|
|
pendingSubscriptionChange,
|
|
|
+ trialSubscription,
|
|
|
} from '../../../fixtures/subscriptions'
|
|
|
+import sinon from 'sinon'
|
|
|
|
|
|
describe('<ActiveSubscription />', function () {
|
|
|
+ let sendMBSpy: sinon.SinonSpy
|
|
|
+
|
|
|
beforeEach(function () {
|
|
|
window.metaAttributesCache = new Map()
|
|
|
+ sendMBSpy = sinon.spy(eventTracking, 'sendMB')
|
|
|
})
|
|
|
|
|
|
afterEach(function () {
|
|
|
window.metaAttributesCache = new Map()
|
|
|
+ sendMBSpy.restore()
|
|
|
})
|
|
|
|
|
|
function expectedInActiveSubscription(subscription: Subscription) {
|
|
|
@@ -25,13 +35,14 @@ describe('<ActiveSubscription />', function () {
|
|
|
|
|
|
// sentence broken up by bolding
|
|
|
screen.getByText('The next payment of', { exact: false })
|
|
|
- screen.getByText(annualActiveSubscription.recurly.displayPrice, {
|
|
|
+ screen.getByText(subscription.recurly.displayPrice, {
|
|
|
exact: false,
|
|
|
})
|
|
|
screen.getByText('will be collected on', { exact: false })
|
|
|
- screen.getByText(annualActiveSubscription.recurly.nextPaymentDueAt, {
|
|
|
+ const dates = screen.getAllByText(subscription.recurly.nextPaymentDueAt, {
|
|
|
exact: false,
|
|
|
})
|
|
|
+ expect(dates.length).to.equal(2)
|
|
|
|
|
|
// sentence broken up by link
|
|
|
screen.getByText(
|
|
|
@@ -89,4 +100,145 @@ describe('<ActiveSubscription />', function () {
|
|
|
exact: false,
|
|
|
})
|
|
|
})
|
|
|
+
|
|
|
+ it('does not show "Change plan" option for group plans', function () {
|
|
|
+ render(
|
|
|
+ <SubscriptionDashboardProvider>
|
|
|
+ <ActiveSubsciption subscription={groupActiveSubscription} />
|
|
|
+ </SubscriptionDashboardProvider>
|
|
|
+ )
|
|
|
+
|
|
|
+ const changePlan = screen.queryByRole('button', { name: 'Change plan' })
|
|
|
+ expect(changePlan).to.be.null
|
|
|
+ })
|
|
|
+
|
|
|
+ it('does not show "Change plan" option when past due', function () {
|
|
|
+ // account is likely in expired state, but be sure to not show option if state is still active
|
|
|
+ const activePastDueSubscription = Object.assign(
|
|
|
+ {},
|
|
|
+ annualActiveSubscription
|
|
|
+ )
|
|
|
+
|
|
|
+ activePastDueSubscription.recurly.account.has_past_due_invoice._ = 'true'
|
|
|
+
|
|
|
+ render(
|
|
|
+ <SubscriptionDashboardProvider>
|
|
|
+ <ActiveSubsciption subscription={activePastDueSubscription} />
|
|
|
+ </SubscriptionDashboardProvider>
|
|
|
+ )
|
|
|
+
|
|
|
+ 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(
|
|
|
+ <SubscriptionDashboardProvider>
|
|
|
+ <ActiveSubsciption
|
|
|
+ subscription={groupActiveSubscriptionWithPendingLicenseChange}
|
|
|
+ />
|
|
|
+ </SubscriptionDashboardProvider>
|
|
|
+ )
|
|
|
+
|
|
|
+ screen.getByText('Your subscription is changing to include', {
|
|
|
+ exact: false,
|
|
|
+ })
|
|
|
+
|
|
|
+ if (
|
|
|
+ !groupActiveSubscriptionWithPendingLicenseChange.recurly
|
|
|
+ .pendingAdditionalLicenses
|
|
|
+ ) {
|
|
|
+ throw Error('not expected test data')
|
|
|
+ }
|
|
|
+ screen.getByText(
|
|
|
+ groupActiveSubscriptionWithPendingLicenseChange.recurly
|
|
|
+ .pendingAdditionalLicenses
|
|
|
+ )
|
|
|
+
|
|
|
+ screen.getByText('additional license(s) for a total of', { exact: false })
|
|
|
+
|
|
|
+ if (
|
|
|
+ !groupActiveSubscriptionWithPendingLicenseChange.recurly
|
|
|
+ .pendingTotalLicenses
|
|
|
+ ) {
|
|
|
+ throw Error('not expected test data')
|
|
|
+ }
|
|
|
+ screen.getByText(
|
|
|
+ groupActiveSubscriptionWithPendingLicenseChange.recurly
|
|
|
+ .pendingTotalLicenses
|
|
|
+ )
|
|
|
+ })
|
|
|
+
|
|
|
+ it('shows the pending license change message when plan change is not pending', function () {
|
|
|
+ const subscription = Object.assign({}, groupActiveSubscription)
|
|
|
+ subscription.recurly.additionalLicenses = 4
|
|
|
+ subscription.recurly.totalLicenses =
|
|
|
+ subscription.recurly.totalLicenses +
|
|
|
+ subscription.recurly.additionalLicenses
|
|
|
+
|
|
|
+ render(
|
|
|
+ <SubscriptionDashboardProvider>
|
|
|
+ <ActiveSubsciption subscription={subscription} />
|
|
|
+ </SubscriptionDashboardProvider>
|
|
|
+ )
|
|
|
+
|
|
|
+ screen.getByText('Your subscription includes', {
|
|
|
+ exact: false,
|
|
|
+ })
|
|
|
+
|
|
|
+ if (!subscription.recurly.additionalLicenses) {
|
|
|
+ throw Error('not expected test data')
|
|
|
+ }
|
|
|
+ screen.getByText(subscription.recurly.additionalLicenses)
|
|
|
+
|
|
|
+ screen.getByText('additional license(s) for a total of', { exact: false })
|
|
|
+
|
|
|
+ screen.getByText(subscription.recurly.totalLicenses)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('shows when trial ends and first payment collected', function () {
|
|
|
+ render(
|
|
|
+ <SubscriptionDashboardProvider>
|
|
|
+ <ActiveSubsciption subscription={trialSubscription} />
|
|
|
+ </SubscriptionDashboardProvider>
|
|
|
+ )
|
|
|
+ screen.getByText('You’re on a free trial which ends on', { exact: false })
|
|
|
+ if (!trialSubscription.recurly.trialEndsAtFormatted) {
|
|
|
+ throw new Error('not expected test data')
|
|
|
+ }
|
|
|
+ const endDate = screen.getAllByText(
|
|
|
+ trialSubscription.recurly.trialEndsAtFormatted
|
|
|
+ )
|
|
|
+ expect(endDate.length).to.equal(2)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('shows cancel UI and sends event', function () {
|
|
|
+ render(
|
|
|
+ <SubscriptionDashboardProvider>
|
|
|
+ <ActiveSubsciption subscription={annualActiveSubscription} />
|
|
|
+ </SubscriptionDashboardProvider>
|
|
|
+ )
|
|
|
+ // before button clicked
|
|
|
+ screen.getByText(
|
|
|
+ 'Your subscription will remain active until the end of your billing period',
|
|
|
+ { exact: false }
|
|
|
+ )
|
|
|
+ const dates = screen.getAllByText(
|
|
|
+ annualActiveSubscription.recurly.nextPaymentDueAt,
|
|
|
+ {
|
|
|
+ exact: false,
|
|
|
+ }
|
|
|
+ )
|
|
|
+ expect(dates.length).to.equal(2)
|
|
|
+
|
|
|
+ const button = screen.getByRole('button', {
|
|
|
+ name: 'Cancel Your Subscription',
|
|
|
+ })
|
|
|
+ fireEvent.click(button)
|
|
|
+ expect(sendMBSpy).to.be.calledOnceWith(
|
|
|
+ 'subscription-page-cancel-button-click'
|
|
|
+ )
|
|
|
+
|
|
|
+ screen.getByText('We’d love you to stay')
|
|
|
+ })
|
|
|
})
|