Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / applications / drive / src / app / components / modals / SignupFlowModal / SignupFlowModal.test.tsx
blob5a2a2d662695f6c983b7aa957f6ae2468f25a1cf
1 import React from 'react';
3 import { fireEvent, render, screen, waitFor } from '@testing-library/react';
4 import { verifyAllWhenMocksCalled, when } from 'jest-when';
6 import useApi from '@proton/components/hooks/useApi';
7 import localStorageWithExpiry from '@proton/shared/lib/api/helpers/localStorageWithExpiry';
8 import { DRIVE_SIGNIN, DRIVE_SIGNUP } from '@proton/shared/lib/drive/urls';
9 import { API_CUSTOM_ERROR_CODES } from '@proton/shared/lib/errors';
10 import { replaceUrl } from '@proton/shared/lib/helpers/browser';
12 import usePublicToken from '../../../hooks/drive/usePublicToken';
13 import { PUBLIC_SHARE_REDIRECT_PASSWORD_STORAGE_KEY } from '../../../utils/url/password';
14 import { SignupFlowModal } from './SignupFlowModal';
16 jest.mock('@proton/components/hooks/useApi');
17 const mockedUseApi = jest.mocked(useApi);
19 jest.mock('@proton/shared/lib/helpers/browser');
20 const mockedReplaceUrl = jest.mocked(replaceUrl);
22 jest.mock('../../../hooks/drive/usePublicToken');
23 const mockUrlPassword = 'mockUrlPassword';
24 const mockToken = 'mockToken';
26 jest.mocked(usePublicToken).mockReturnValue({
27     token: mockToken,
28     urlPassword: mockUrlPassword,
29 });
31 const ResizeObserverMock = jest.fn(() => ({
32     disconnect: jest.fn(),
33     observe: jest.fn(),
34     unobserve: jest.fn(),
35 }));
37 const locationMock = {
38     pathname: '/urls/mockpath',
39     hash: '#mockhash',
40     search: '',
43 describe('SignupFlowModal', () => {
44     let assignMock = jest.fn();
45     const originalWindowLocation = window.location;
46     const originalResizeObserver = window.ResizeObserver;
48     beforeAll(() => {
49         Object.defineProperty(window, 'ResizeObserver', {
50             value: ResizeObserverMock,
51             writable: true,
52         });
53         Object.defineProperty(window, 'location', {
54             value: locationMock,
55             writable: true,
56         });
57     });
59     afterEach(() => {
60         localStorageWithExpiry.deleteData(PUBLIC_SHARE_REDIRECT_PASSWORD_STORAGE_KEY);
61         assignMock.mockClear();
62     });
64     afterAll(() => {
65         verifyAllWhenMocksCalled();
66         Object.defineProperty(window, 'ResizeObserver', {
67             value: originalResizeObserver,
68             writable: true,
69         });
70         Object.defineProperty(window, 'location', {
71             writable: true,
72             value: originalWindowLocation,
73         });
74     });
76     it('should open the modal and delete the password from localStorage on mount', () => {
77         render(<SignupFlowModal open onClose={() => {}} onExit={() => {}} />);
78         expect(localStorageWithExpiry.getData(PUBLIC_SHARE_REDIRECT_PASSWORD_STORAGE_KEY)).toEqual(null);
79         expect(screen.getByTestId('public-share-signup-modal-email')).toBeInTheDocument();
80     });
82     it('should handle email input change and validation', () => {
83         render(<SignupFlowModal open onClose={() => {}} onExit={() => {}} />);
84         const emailInput = screen.getByTestId<HTMLInputElement>('public-share-signup-modal-email');
86         fireEvent.change(emailInput, { target: { value: 'invalid-email' } });
87         expect(emailInput.value).toBe('invalid-email');
88         expect(screen.getByText('Email is not valid')).toBeInTheDocument();
89     });
91     it('should handle form submission and API responses correctly', async () => {
92         const mockApi = jest.fn();
93         mockedUseApi.mockReturnValue(mockApi);
94         mockApi.mockResolvedValue({ Code: 1000 });
95         const expectedReplaceUrl = DRIVE_SIGNUP.concat(
96             '?username=test@example.com%40returnUrl=%2Furls%2Fmockpath%23mockhash&returnUrlContext=public'
97         );
98         when(mockedReplaceUrl).expectCalledWith(expectedReplaceUrl);
100         render(<SignupFlowModal open onClose={() => {}} onExit={() => {}} />);
101         const emailInput = screen.getByTestId('public-share-signup-modal-email');
102         const submitButton = screen.getByText('Continue');
104         fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
105         fireEvent.click(submitButton);
107         await waitFor(() => {
108             expect(localStorageWithExpiry.getData(PUBLIC_SHARE_REDIRECT_PASSWORD_STORAGE_KEY)).toEqual(mockUrlPassword);
109         });
110     });
112     it('should redirect to SIGN_IN if email is already used', async () => {
113         const mockApi = jest.fn();
114         mockedUseApi.mockReturnValue(mockApi);
115         mockApi.mockRejectedValue({ data: { Code: API_CUSTOM_ERROR_CODES.ALREADY_USED, Error: 'test message' } });
116         const expectedReplaceUrl = DRIVE_SIGNIN.concat(
117             '?email=used@example.com%40returnUrl=%2Furls%2Fmockpath%23mockhash&returnUrlContext=public'
118         );
119         when(mockedReplaceUrl).expectCalledWith(expectedReplaceUrl);
121         render(<SignupFlowModal open onClose={() => {}} onExit={() => {}} />);
122         const emailInput = screen.getByTestId('public-share-signup-modal-email');
123         const submitButton = screen.getByText('Continue');
125         fireEvent.change(emailInput, { target: { value: 'used@example.com' } });
126         fireEvent.click(submitButton);
128         await waitFor(() => {
129             expect(localStorageWithExpiry.getData(PUBLIC_SHARE_REDIRECT_PASSWORD_STORAGE_KEY)).toEqual(mockUrlPassword);
130         });
131     });
133     it('should display an error message for other API errors', async () => {
134         const mockApi = jest.fn();
135         mockedUseApi.mockReturnValue(mockApi);
137         mockApi.mockRejectedValue({ data: { Code: '123456', Error: 'Some error occurred' } });
139         render(<SignupFlowModal open onClose={() => {}} onExit={() => {}} />);
140         const emailInput = screen.getByTestId('public-share-signup-modal-email');
141         const submitButton = screen.getByText('Continue');
143         fireEvent.change(emailInput, { target: { value: 'error@example.com' } });
144         fireEvent.click(submitButton);
146         await waitFor(() => {
147             expect(localStorageWithExpiry.getData(PUBLIC_SHARE_REDIRECT_PASSWORD_STORAGE_KEY)).toEqual(null);
148             expect(screen.getByText('Some error occurred')).toBeInTheDocument();
149         });
150     });