1 import { getModelState } from '@proton/account/test';
2 import { renderWithProviders } from '@proton/components/containers/contacts/tests/render';
3 import { plansDefaultResponse } from '@proton/components/hooks/helpers/test';
4 import { PLANS } from '@proton/payments';
5 import { changeRenewState } from '@proton/shared/lib/api/payments';
6 import type { Subscription, SubscriptionModel } from '@proton/shared/lib/interfaces';
7 import { Renew } from '@proton/shared/lib/interfaces';
8 import { FREE_PLAN } from '@proton/shared/lib/subscription/freePlans';
9 import { apiMock, applyHOCs, getSubscriptionState, withApi, withCache, withEventManager } from '@proton/testing';
11 import SubscriptionsSection from './SubscriptionsSection';
13 const ContextSubscriptionSection = applyHOCs(withEventManager(), withApi(), withCache())(SubscriptionsSection);
15 describe('SubscriptionsSection', () => {
16 let subscription: SubscriptionModel;
17 let upcoming: Subscription | null = null;
24 PeriodStart: 1696561158,
25 PeriodEnd: 1699239558,
26 CreateTime: 1696561161,
38 Title: 'Proton Unlimited',
42 MaxSpace: 536870912000,
58 UpcomingSubscription: null,
59 isManagedByMozilla: false,
64 InvoiceID: null as any,
66 PeriodStart: 1699239558,
67 PeriodEnd: 1730861958,
68 CreateTime: 1696561195,
80 Title: 'Proton Unlimited',
84 MaxSpace: 536870912000,
102 jest.clearAllMocks();
105 const defaultPlansState = {
106 ...getModelState({ plans: plansDefaultResponse.Plans, freePlan: FREE_PLAN }),
107 meta: { fetchedAt: Date.now(), fetchedEphemeral: true },
110 it('should return MozillaInfoPanel if isManagedByMozilla is true', () => {
111 subscription.isManagedByMozilla = true;
112 const { container } = renderWithProviders(<ContextSubscriptionSection />, {
114 subscription: getSubscriptionState(subscription),
115 plans: defaultPlansState,
118 expect(container).toHaveTextContent('Your subscription is managed by Mozilla');
121 it('should render current subscription', () => {
122 const { getByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
124 subscription: getSubscriptionState(subscription),
125 plans: defaultPlansState,
129 expect(getByTestId('planNameId')).toHaveTextContent('Proton Unlimited');
130 expect(getByTestId('subscriptionStatusId')).toHaveTextContent('Active');
131 expect(getByTestId('planEndTimeId')).toHaveTextContent('Nov 6, 2023');
134 it('should display Expiring badge if renew is disabled', () => {
135 subscription.Renew = Renew.Disabled;
136 const { getByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
138 subscription: getSubscriptionState(subscription),
139 plans: defaultPlansState,
143 expect(getByTestId('planNameId')).toHaveTextContent('Proton Unlimited');
144 expect(getByTestId('subscriptionStatusId')).toHaveTextContent('Expiring');
145 expect(getByTestId('planEndTimeId')).toHaveTextContent('Nov 6, 2023');
148 it('should render end date of upcoming subscription', () => {
149 subscription.UpcomingSubscription = upcoming;
151 const { getByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
153 subscription: getSubscriptionState(subscription),
154 plans: defaultPlansState,
158 expect(getByTestId('planNameId')).toHaveTextContent('Proton Unlimited');
159 expect(getByTestId('subscriptionStatusId')).toHaveTextContent('Active');
160 expect(getByTestId('planEndTimeId')).toHaveTextContent('Nov 6, 2024');
163 it('should show renewal notice if there is no upcoming subscription', () => {
164 const { getByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
166 subscription: getSubscriptionState(subscription),
167 plans: defaultPlansState,
170 expect(getByTestId('renewalNotice')).toHaveTextContent('Renews automatically at CHF 12.99, for 1 month');
173 it('should show renewal notice if there is upcoming subscription', () => {
174 subscription.UpcomingSubscription = upcoming;
175 const { getByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
177 subscription: getSubscriptionState(subscription),
178 plans: defaultPlansState,
181 expect(getByTestId('renewalNotice')).toHaveTextContent('Renews automatically at CHF 119.88, for 12 months');
184 it('should now show renewal notice if subscription is expiring', () => {
185 subscription.Renew = Renew.Disabled;
186 const { container } = renderWithProviders(<ContextSubscriptionSection />, {
188 subscription: getSubscriptionState(subscription),
189 plans: defaultPlansState,
192 expect(container).not.toHaveTextContent('Renews automatically');
195 it('should display Reactivate button when Renew is disabled', () => {
196 subscription.Renew = Renew.Disabled;
197 const { getByText } = renderWithProviders(<ContextSubscriptionSection />, {
199 subscription: getSubscriptionState(subscription),
200 plans: defaultPlansState,
203 expect(getByText('Reactivate')).toBeInTheDocument();
206 it('should display warning icon when renewal is disabled', () => {
207 subscription.Renew = Renew.Disabled;
208 const { queryByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
210 subscription: getSubscriptionState(subscription),
211 plans: defaultPlansState,
214 expect(queryByTestId('periodEndWarning')).toBeInTheDocument();
217 it('should not display date of upcoming subscription if renew is disabled', () => {
218 subscription.Renew = Renew.Disabled;
219 subscription.UpcomingSubscription = upcoming;
220 const { container } = renderWithProviders(<ContextSubscriptionSection />, {
222 subscription: getSubscriptionState(subscription),
223 plans: defaultPlansState,
226 expect(container).not.toHaveTextContent('Upcoming');
229 it('should call API when user presses reactivate button', () => {
230 subscription.Renew = Renew.Disabled;
231 const { getByText } = renderWithProviders(<ContextSubscriptionSection />, {
233 subscription: getSubscriptionState(subscription),
234 plans: defaultPlansState,
237 getByText('Reactivate').click();
238 expect(apiMock).toHaveBeenCalledWith(
241 RenewalState: Renew.Enabled,