client/components/mma/cancel/Cancellation.stories.tsx (179 lines of code) (raw):

import type { Meta, StoryObj } from '@storybook/react'; import { http, HttpResponse } from 'msw'; import { ReactRouterDecorator } from '@/.storybook/ReactRouterDecorator'; import { toMembersDataApiResponse } from '@/client/fixtures/mdapiResponse'; import { PRODUCT_TYPES } from '@/shared/productTypes'; import { contributionCancelled, contributionPaidByCard, contributionPaidByPayPal, guardianAdLite, guardianAdLiteCancelled, guardianAdLiteInTrialPeriod, guardianWeeklyPaidByCard, supporterPlus, supporterPlusAnnual, supporterPlusCancelled, supporterPlusMonthlyAllAccessDigital, } from '../../../fixtures/productBuilder/testProducts'; import { CancellationContainer } from './CancellationContainer'; import { CancellationJourneyFunnel } from './CancellationJourneyFunnel'; import { CancellationReasonReview } from './CancellationReasonReview'; import { CancellationReasonSelection } from './CancellationReasonSelection'; import { CancelAlternativeConfirmed } from './cancellationSaves/CancelAlternativeConfirmed'; import { CancelAlternativeOffer } from './cancellationSaves/CancelAlternativeOffer'; import { CancelAlternativeReview } from './cancellationSaves/CancelAlternativeReview'; import { contributionsCancellationReasons } from './contributions/ContributionsCancellationReasons'; import { gwCancellationReasons } from './gw/GwCancellationReasons'; import { ConfirmCancellation } from './stages/ConfirmCancellation'; import { ExecuteCancellation } from './stages/ExecuteCancellation'; import { otherCancellationReason, supporterplusCancellationReasons, } from './supporterplus/SupporterplusCancellationReasons'; const contributions = PRODUCT_TYPES.contributions; contributions.cancellation!.reasons = contributionsCancellationReasons.concat( otherCancellationReason, ); const guardianweekly = PRODUCT_TYPES.guardianweekly; guardianweekly.cancellation!.reasons = gwCancellationReasons.concat( otherCancellationReason, ); const supporterplus = PRODUCT_TYPES.supporterplus; supporterplus.cancellation!.reasons = supporterplusCancellationReasons.concat( otherCancellationReason, ); export default { title: 'Pages/Cancellation', component: CancellationContainer, decorators: [ReactRouterDecorator], parameters: { layout: 'fullscreen', reactRouter: { state: { productDetail: contributionPaidByPayPal() }, }, }, } as Meta<typeof CancellationContainer>; export const SelectReason: StoryObj<typeof CancellationReasonSelection> = { render: () => <CancellationReasonSelection />, parameters: { reactRouter: { container: ( <CancellationContainer productType={PRODUCT_TYPES.contributions} /> ), }, }, }; export const ContactCustomerService: StoryObj< typeof CancellationReasonSelection > = { render: () => <CancellationJourneyFunnel />, parameters: { reactRouter: { state: { productDetail: guardianWeeklyPaidByCard() }, container: <CancellationContainer productType={guardianweekly} />, }, }, }; export const Review: StoryObj<typeof CancellationContainer> = { render: () => { return <CancellationReasonReview />; }, parameters: { msw: [ http.post('/api/case', () => { return HttpResponse.json({ id: 'caseId' }); }), ], reactRouter: { state: { productDetail: contributionPaidByPayPal(), selectedReasonId: 'mma_editorial', cancellationPolicy: 'Today', }, container: ( <CancellationContainer productType={PRODUCT_TYPES.contributions} /> ), }, }, }; export const ReviewWithReduceAmount: StoryObj<typeof CancellationContainer> = { render: () => { return <CancellationReasonReview />; }, parameters: { msw: [ http.post('/api/case', () => { return HttpResponse.json({ id: 'caseId' }); }), ], reactRouter: { state: { productDetail: contributionPaidByPayPal(), selectedReasonId: 'mma_financial_circumstances', }, container: ( <CancellationContainer productType={PRODUCT_TYPES.contributions} /> ), }, }, }; export const ReviewGuardianAdLiteInTrialPeriod: StoryObj< typeof CancellationContainer > = { render: () => { return <ConfirmCancellation />; }, parameters: { reactRouter: { state: { productDetail: guardianAdLiteInTrialPeriod(), }, container: ( <CancellationContainer productType={PRODUCT_TYPES.guardianadlite} /> ), }, }, }; export const ReviewGuardianAdLite: StoryObj<typeof CancellationContainer> = { render: () => { return <ConfirmCancellation />; }, parameters: { reactRouter: { state: { productDetail: guardianAdLite(), }, container: ( <CancellationContainer productType={PRODUCT_TYPES.guardianadlite} /> ), }, }, }; export const ConfirmationGuardianAdLite: StoryObj<typeof ExecuteCancellation> = { render: () => { // @ts-expect-error set identity details email in the window window.guardian = { identityDetails: { email: 'test' } }; return <ExecuteCancellation />; }, parameters: { msw: [ http.patch('/api/case/**', () => { return HttpResponse.json({ id: 'caseId' }); }), http.get('/api/me/mma/**', () => { return HttpResponse.json( toMembersDataApiResponse(guardianAdLiteCancelled()), ); }), http.post('/api/cancel/**', () => { return new HttpResponse(null, { status: 201, }); }), ], reactRouter: { state: { productDetail: guardianAdLite(), selectedReasonId: '1', caseId: 'caseId', }, container: ( <CancellationContainer productType={PRODUCT_TYPES.guardianadlite} /> ), }, }, }; export const OfferMonthly: StoryObj<typeof CancellationContainer> = { render: () => { return <CancelAlternativeOffer />; }, parameters: { msw: [ http.post('/api/case', () => { return HttpResponse.json({ id: 'caseId' }); }), ], reactRouter: { state: { productDetail: supporterPlusMonthlyAllAccessDigital(), discountedPrice: 0, discountPercentage: 100, upToPeriods: 2, upToPeriodsType: 'months', firstDiscountedPaymentDate: '2024-05-30', nextNonDiscountedPaymentDate: '2024-07-30', nonDiscountedPayments: [{ date: '2024-07-30', amount: 14.99 }], }, container: <CancellationContainer productType={supporterplus} />, }, }, }; export const OfferYearly: StoryObj<typeof CancellationContainer> = { render: () => { return <CancelAlternativeOffer />; }, parameters: { msw: [ http.post('/api/case', () => { return HttpResponse.json({ id: 'caseId' }); }), ], reactRouter: { state: { productDetail: supporterPlusAnnual(), discountedPrice: 90, discountPercentage: 25, upToPeriods: 12, upToPeriodsType: 'months', firstDiscountedPaymentDate: '2024-05-30', nextNonDiscountedPaymentDate: '2025-05-30', nonDiscountedPayments: [{ date: '2025-05-30', amount: 120 }], }, container: <CancellationContainer productType={supporterplus} />, }, }, }; export const OfferReviewMonthly: StoryObj<typeof CancellationContainer> = { render: () => { return <CancelAlternativeReview />; }, parameters: { reactRouter: { state: { productDetail: supporterPlusMonthlyAllAccessDigital(), discountedPrice: 0, discountPercentage: 100, upToPeriods: 2, upToPeriodsType: 'months', firstDiscountedPaymentDate: '2024-05-30', nextNonDiscountedPaymentDate: '2024-07-30', nonDiscountedPayments: [{ date: '2024-07-30', amount: 14.99 }], }, container: <CancellationContainer productType={supporterplus} />, }, msw: [ http.post('/api/discounts/apply-discount', () => { return new HttpResponse(null, { status: 201, }); }), ], }, }; export const OfferReviewYearly: StoryObj<typeof CancellationContainer> = { render: () => { return <CancelAlternativeReview />; }, parameters: { reactRouter: { state: { productDetail: supporterPlusAnnual(), discountedPrice: 90, discountPercentage: 25, upToPeriods: 12, upToPeriodsType: 'months', firstDiscountedPaymentDate: '2024-05-30', nextNonDiscountedPaymentDate: '2025-05-30', nonDiscountedPayments: [{ date: '2025-05-30', amount: 120 }], }, container: <CancellationContainer productType={supporterplus} />, }, msw: [ http.post('/api/discounts/apply-discount', () => { return new HttpResponse(null, { status: 201, }); }), ], }, }; export const OfferConfirmedMonthly: StoryObj<typeof CancellationContainer> = { render: () => { return <CancelAlternativeConfirmed />; }, parameters: { reactRouter: { state: { upToPeriods: 2, upToPeriodsType: 'months', nextNonDiscountedPaymentDate: '2024-07-30', nonDiscountedPayments: [{ date: '2024-07-30', amount: 14.99 }], }, container: <CancellationContainer productType={supporterplus} />, }, }, }; export const OfferConfirmedYearly: StoryObj<typeof CancellationContainer> = { render: () => { return <CancelAlternativeConfirmed />; }, parameters: { reactRouter: { state: { productDetail: supporterPlusAnnual(), upToPeriods: 12, upToPeriodsType: 'months', discountPercentage: 25, discountedPrice: 90, firstDiscountedPaymentDate: '2024-05-30', nextNonDiscountedPaymentDate: '2025-05-30', nonDiscountedPayments: [{ date: '2025-05-30', amount: 120 }], }, container: <CancellationContainer productType={supporterplus} />, }, }, }; export const Pause: StoryObj<typeof CancellationContainer> = { render: () => { return <CancelAlternativeOffer />; }, parameters: { msw: [ http.post('/api/case', () => { return HttpResponse.json({ id: 'caseId' }); }), ], reactRouter: { state: { discountedPrice: 0, discountPercentage: 100, upToPeriods: 2, upToPeriodsType: 'months', firstDiscountedPaymentDate: '2024-05-30', nextNonDiscountedPaymentDate: '2024-07-30', nonDiscountedPayments: [{ date: '2024-07-30', amount: 14.99 }], }, container: <CancellationContainer productType={contributions} />, }, }, }; export const PauseReview: StoryObj<typeof CancellationContainer> = { render: () => { return <CancelAlternativeReview />; }, parameters: { reactRouter: { state: { discountedPrice: 0, discountPercentage: 100, upToPeriods: 2, upToPeriodsType: 'months', firstDiscountedPaymentDate: '2024-05-30', nextNonDiscountedPaymentDate: '2024-07-30', nonDiscountedPayments: [{ date: '2024-07-30', amount: 14.99 }], }, container: <CancellationContainer productType={contributions} />, }, msw: [ http.post('/api/discounts/apply-discount', () => { return new HttpResponse(null, { status: 201, }); }), ], }, }; export const PauseConfirmed: StoryObj<typeof CancellationContainer> = { render: () => { return <CancelAlternativeConfirmed />; }, parameters: { reactRouter: { state: { upToPeriods: 2, upToPeriodsType: 'months', nextNonDiscountedPaymentDate: '2024-07-30', nonDiscountedPayments: [{ date: '2024-07-30', amount: 14.99 }], }, container: <CancellationContainer productType={contributions} />, }, }, }; export const SupportplusCancelConfirm: StoryObj<typeof CancellationContainer> = { render: () => { return <ConfirmCancellation />; }, parameters: { reactRouter: { state: { productDetail: supporterPlusMonthlyAllAccessDigital(), eligibleForFreePeriodOffer: true, discountedPrice: 0, upToPeriods: 2, upToPeriodsType: 'months', firstDiscountedPaymentDate: '2024-05-30', nextNonDiscountedPaymentDate: '2024-07-30', nonDiscountedPayments: [ { date: '2024-07-30', amount: 14.99 }, ], }, container: ( <CancellationContainer productType={PRODUCT_TYPES.supporterplus} /> ), }, }, }; export const ConfirmationContribution: StoryObj<typeof ExecuteCancellation> = { render: () => { // @ts-expect-error set identity details email in the window window.guardian = { identityDetails: { email: 'test' } }; return <ExecuteCancellation />; }, parameters: { msw: [ http.patch('/api/case/**', () => { return HttpResponse.json({ id: 'caseId' }); }), http.get('/api/me/mma/**', () => { return HttpResponse.json( toMembersDataApiResponse(contributionCancelled()), ); }), http.post('/api/cancel/**', () => { return new HttpResponse(null, { status: 201, }); }), ], reactRouter: { state: { productDetail: contributionPaidByCard(), selectedReasonId: '1', caseId: 'caseId', }, container: ( <CancellationContainer productType={PRODUCT_TYPES.contributions} /> ), }, }, }; export const ConfirmationContributionWithPause: StoryObj< typeof ExecuteCancellation > = { render: () => { // @ts-expect-error set identity details email in the window window.guardian = { identityDetails: { email: 'test' } }; return <ExecuteCancellation />; }, parameters: { msw: [ http.patch('/api/case/**', () => { return HttpResponse.json({ id: 'caseId' }); }), http.get('/api/me/mma/**', () => { return HttpResponse.json( toMembersDataApiResponse(contributionCancelled()), ); }), http.post('/api/cancel/**', () => { return new HttpResponse(null, { status: 201, }); }), ], reactRouter: { state: { productDetail: contributionPaidByCard(), eligibleForPause: true, selectedReasonId: '1', caseId: 'caseId', }, container: ( <CancellationContainer productType={PRODUCT_TYPES.contributions} /> ), }, }, }; export const ConfirmationSupporterPlusWithOffer: StoryObj< typeof ExecuteCancellation > = { render: () => { // @ts-expect-error set identity details email in the window window.guardian = { identityDetails: { email: 'test' } }; return <ExecuteCancellation />; }, parameters: { msw: [ http.patch('/api/case/**', () => { return HttpResponse.json({ id: 'caseId' }); }), http.get('/api/me/mma/**', () => { return HttpResponse.json( toMembersDataApiResponse(supporterPlusCancelled()), ); }), http.post('/api/cancel/**', () => { return new HttpResponse(null, { status: 201, }); }), ], reactRouter: { state: { productDetail: supporterPlus(), eligibleForOffer: true, selectedReasonId: '1', caseId: 'caseId', }, container: ( <CancellationContainer productType={PRODUCT_TYPES.supporterplus} /> ), }, }, };