Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / components / containers / payments / SubscriptionsSection.test.tsx
blob95994cbd8614405f6e63c18691864562b611de1e
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;
19     beforeEach(() => {
20         subscription = {
21             ID: '123',
22             InvoiceID: '1234',
23             Cycle: 1,
24             PeriodStart: 1696561158,
25             PeriodEnd: 1699239558,
26             CreateTime: 1696561161,
27             CouponCode: null,
28             Currency: 'CHF',
29             Amount: 1299,
30             Discount: 0,
31             RenewAmount: 1299,
32             RenewDiscount: 0,
33             Plans: [
34                 {
35                     ID: '1',
36                     Type: 1,
37                     Name: PLANS.BUNDLE,
38                     Title: 'Proton Unlimited',
39                     MaxDomains: 3,
40                     MaxAddresses: 15,
41                     MaxCalendars: 25,
42                     MaxSpace: 536870912000,
43                     MaxMembers: 1,
44                     MaxVPN: 10,
45                     MaxTier: 2,
46                     Services: 15,
47                     Features: 1,
48                     State: 1,
49                     Cycle: 1,
50                     Currency: 'CHF',
51                     Amount: 1299,
52                     Offer: 'default',
53                     Quantity: 1,
54                 },
55             ],
56             Renew: 1,
57             External: 0,
58             UpcomingSubscription: null,
59             isManagedByMozilla: false,
60         };
62         upcoming = {
63             ID: '124',
64             InvoiceID: null as any,
65             Cycle: 12,
66             PeriodStart: 1699239558,
67             PeriodEnd: 1730861958,
68             CreateTime: 1696561195,
69             CouponCode: null,
70             Currency: 'CHF',
71             Amount: 11988,
72             Discount: 0,
73             RenewAmount: 11988,
74             RenewDiscount: 0,
75             Plans: [
76                 {
77                     ID: '1',
78                     Type: 1,
79                     Name: PLANS.BUNDLE,
80                     Title: 'Proton Unlimited',
81                     MaxDomains: 3,
82                     MaxAddresses: 15,
83                     MaxCalendars: 25,
84                     MaxSpace: 536870912000,
85                     MaxMembers: 1,
86                     MaxVPN: 10,
87                     MaxTier: 2,
88                     Services: 15,
89                     Features: 1,
90                     State: 1,
91                     Cycle: 12,
92                     Currency: 'CHF',
93                     Amount: 11988,
94                     Quantity: 1,
95                     Offer: 'default',
96                 },
97             ],
98             Renew: 1,
99             External: 0,
100         };
102         jest.clearAllMocks();
103     });
105     const defaultPlansState = {
106         ...getModelState({ plans: plansDefaultResponse.Plans, freePlan: FREE_PLAN }),
107         meta: { fetchedAt: Date.now(), fetchedEphemeral: true },
108     };
110     it('should return MozillaInfoPanel if isManagedByMozilla is true', () => {
111         subscription.isManagedByMozilla = true;
112         const { container } = renderWithProviders(<ContextSubscriptionSection />, {
113             preloadedState: {
114                 subscription: getSubscriptionState(subscription),
115                 plans: defaultPlansState,
116             },
117         });
118         expect(container).toHaveTextContent('Your subscription is managed by Mozilla');
119     });
121     it('should render current subscription', () => {
122         const { getByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
123             preloadedState: {
124                 subscription: getSubscriptionState(subscription),
125                 plans: defaultPlansState,
126             },
127         });
129         expect(getByTestId('planNameId')).toHaveTextContent('Proton Unlimited');
130         expect(getByTestId('subscriptionStatusId')).toHaveTextContent('Active');
131         expect(getByTestId('planEndTimeId')).toHaveTextContent('Nov 6, 2023');
132     });
134     it('should display Expiring badge if renew is disabled', () => {
135         subscription.Renew = Renew.Disabled;
136         const { getByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
137             preloadedState: {
138                 subscription: getSubscriptionState(subscription),
139                 plans: defaultPlansState,
140             },
141         });
143         expect(getByTestId('planNameId')).toHaveTextContent('Proton Unlimited');
144         expect(getByTestId('subscriptionStatusId')).toHaveTextContent('Expiring');
145         expect(getByTestId('planEndTimeId')).toHaveTextContent('Nov 6, 2023');
146     });
148     it('should render end date of upcoming subscription', () => {
149         subscription.UpcomingSubscription = upcoming;
151         const { getByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
152             preloadedState: {
153                 subscription: getSubscriptionState(subscription),
154                 plans: defaultPlansState,
155             },
156         });
158         expect(getByTestId('planNameId')).toHaveTextContent('Proton Unlimited');
159         expect(getByTestId('subscriptionStatusId')).toHaveTextContent('Active');
160         expect(getByTestId('planEndTimeId')).toHaveTextContent('Nov 6, 2024');
161     });
163     it('should show renewal notice if there is no upcoming subscription', () => {
164         const { getByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
165             preloadedState: {
166                 subscription: getSubscriptionState(subscription),
167                 plans: defaultPlansState,
168             },
169         });
170         expect(getByTestId('renewalNotice')).toHaveTextContent('Renews automatically at CHF 12.99, for 1 month');
171     });
173     it('should show renewal notice if there is upcoming subscription', () => {
174         subscription.UpcomingSubscription = upcoming;
175         const { getByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
176             preloadedState: {
177                 subscription: getSubscriptionState(subscription),
178                 plans: defaultPlansState,
179             },
180         });
181         expect(getByTestId('renewalNotice')).toHaveTextContent('Renews automatically at CHF 119.88, for 12 months');
182     });
184     it('should now show renewal notice if subscription is expiring', () => {
185         subscription.Renew = Renew.Disabled;
186         const { container } = renderWithProviders(<ContextSubscriptionSection />, {
187             preloadedState: {
188                 subscription: getSubscriptionState(subscription),
189                 plans: defaultPlansState,
190             },
191         });
192         expect(container).not.toHaveTextContent('Renews automatically');
193     });
195     it('should display Reactivate button when Renew is disabled', () => {
196         subscription.Renew = Renew.Disabled;
197         const { getByText } = renderWithProviders(<ContextSubscriptionSection />, {
198             preloadedState: {
199                 subscription: getSubscriptionState(subscription),
200                 plans: defaultPlansState,
201             },
202         });
203         expect(getByText('Reactivate')).toBeInTheDocument();
204     });
206     it('should display warning icon when renewal is disabled', () => {
207         subscription.Renew = Renew.Disabled;
208         const { queryByTestId } = renderWithProviders(<ContextSubscriptionSection />, {
209             preloadedState: {
210                 subscription: getSubscriptionState(subscription),
211                 plans: defaultPlansState,
212             },
213         });
214         expect(queryByTestId('periodEndWarning')).toBeInTheDocument();
215     });
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 />, {
221             preloadedState: {
222                 subscription: getSubscriptionState(subscription),
223                 plans: defaultPlansState,
224             },
225         });
226         expect(container).not.toHaveTextContent('Upcoming');
227     });
229     it('should call API when user presses reactivate button', () => {
230         subscription.Renew = Renew.Disabled;
231         const { getByText } = renderWithProviders(<ContextSubscriptionSection />, {
232             preloadedState: {
233                 subscription: getSubscriptionState(subscription),
234                 plans: defaultPlansState,
235             },
236         });
237         getByText('Reactivate').click();
238         expect(apiMock).toHaveBeenCalledWith(
239             changeRenewState(
240                 {
241                     RenewalState: Renew.Enabled,
242                 },
243                 'v5'
244             )
245         );
246     });