Merge branch 'DRVDOC-1260' into 'main'
[ProtonMail-WebClient.git] / packages / components / containers / addresses / AddressesWithUser.test.tsx
blob40282d1d78cd5c1d2d19213f6fd4be5dbac06055
1 import type { ComponentPropsWithoutRef } from 'react';
3 import { fireEvent, render } from '@testing-library/react';
5 import { useAddressesKeys } from '@proton/account/addressKeys/hooks';
6 import { useAddresses } from '@proton/account/addresses/hooks';
7 import { useOrganizationKey } from '@proton/account/organizationKey/hooks';
8 import { useUser } from '@proton/account/user/hooks';
9 import OrderableTable from '@proton/components/components/orderableTable/OrderableTable';
10 import useApi from '@proton/components/hooks/useApi';
11 import useNotifications from '@proton/components/hooks/useNotifications';
12 import { orderAddress } from '@proton/shared/lib/api/addresses';
13 import { ADDRESS_TYPE } from '@proton/shared/lib/constants';
14 import type { Address, UserModel } from '@proton/shared/lib/interfaces';
15 import { mockUseFeature } from '@proton/testing/lib/mockUseFeature';
16 import useFlag from '@proton/unleash/useFlag';
18 import useKTVerifier from '../keyTransparency/useKTVerifier';
19 import AddressesWithUser from './AddressesWithUser';
21 jest.mock('@proton/components/hooks/useEventManager', () => () => ({}));
22 jest.mock('@proton/components/components/upsell/useOneDollarPromo.tsx', () => ({
23     __esModule: true,
24     default: () => null,
25 }));
27 jest.mock('@proton/components/components/upsell/useUpsellConfig.ts', () => ({
28     __esModule: true,
29     default: () => null,
30 }));
32 jest.mock('@proton/shared/lib/helpers/upsell.ts', () => ({
33     __esModule: true,
34     useNewUpsellModalVariant: () => true,
35     getUpsellRef: () => '',
36 }));
38 jest.mock('@proton/components/components/orderableTable/OrderableTable');
39 const ActualOrderableTable = jest.requireActual('@proton/components/components/orderableTable/OrderableTable').default;
40 const mockedOrderableTable = OrderableTable as jest.MockedFunction<typeof OrderableTable>;
42 jest.mock('@proton/account/addresses/hooks');
43 const mockedUseAddresses = useAddresses as jest.MockedFunction<typeof useAddresses>;
45 jest.mock('@proton/components/hooks/useApi');
46 const mockedUseApi = useApi as jest.MockedFunction<typeof useApi>;
48 jest.mock('@proton/components/hooks/useNotifications');
49 const mockedUseNotifications = useNotifications as jest.MockedFunction<typeof useNotifications>;
51 jest.mock('@proton/account/user/hooks');
52 const mockedUseUser = useUser as jest.MockedFunction<typeof useUser>;
54 jest.mock('@proton/account/addressKeys/hooks');
55 const mockedUseAddressesKeys = useAddressesKeys as jest.MockedFunction<typeof useAddressesKeys>;
57 jest.mock('@proton/components/containers/keyTransparency/useKTVerifier');
58 const mockedUseKTVerifier = useKTVerifier as jest.MockedFunction<typeof useKTVerifier>;
60 jest.mock('@proton/unleash/useFlag');
61 const mockedUseFlag = useFlag as jest.MockedFunction<any>;
63 jest.mock('@proton/account/organizationKey/hooks');
64 const mockedUseOrganizationKey = useOrganizationKey as jest.MockedFunction<typeof useOrganizationKey>;
66 jest.mock('@proton/redux-shared-store');
68 describe('addresses with user', () => {
69     const user = {
70         ID: 'abc',
71     } as UserModel;
73     const addresses = [
74         {
75             ID: '1',
76             Email: 'a@proton.me',
77             Type: ADDRESS_TYPE.TYPE_ORIGINAL,
78             Status: 1,
79             Receive: 1,
80             Send: 1,
81             HasKeys: 1,
82         },
83         {
84             ID: '2',
85             Email: 'a@foo.bar',
86             Type: ADDRESS_TYPE.TYPE_EXTERNAL,
87             Status: 1,
88             Receive: 0,
89             Send: 0,
90             HasKeys: 1,
91         },
92         {
93             ID: '3',
94             Email: 'a1@proton.me',
95             Type: ADDRESS_TYPE.TYPE_ALIAS,
96             Status: 1,
97             Receive: 1,
98             Send: 1,
99             HasKeys: 1,
100         },
101         {
102             ID: '4',
103             Email: 'a2@pm.me',
104             Type: ADDRESS_TYPE.TYPE_PREMIUM,
105             Status: 0,
106             Receive: 0,
107             Send: 0,
108             HasKeys: 1,
109         },
110     ] as Address[];
112     mockedUseAddresses.mockReturnValue([addresses, false]);
113     mockedOrderableTable.mockImplementation(ActualOrderableTable);
114     mockedUseNotifications.mockReturnValue({} as any);
115     mockedUseUser.mockReturnValue([{}] as any);
116     mockedUseAddressesKeys.mockReturnValue([{}] as any);
117     mockedUseKTVerifier.mockReturnValue({} as any);
118     mockedUseOrganizationKey.mockReturnValue([{}] as any);
119     mockedUseFlag.mockReturnValue(true);
120     mockUseFeature({ feature: { Value: true } as any });
122     const getFirstAddress = (container: HTMLElement) => {
123         return container.querySelector('[title]');
124     };
126     it('should be able to set an alias as default', async () => {
127         const mockApi = jest.fn();
128         mockedUseApi.mockReturnValue(mockApi);
130         const { getByTestId, getByText, container } = render(
131             <AddressesWithUser user={user} allowAddressDeletion={false} />
132         );
134         // Assumes that "Make default" is displayed on the address we're interested in
135         fireEvent.click(getByTestId('dropdownActions:dropdown'));
136         fireEvent.click(getByText('Set as default'));
137         expect(mockApi).toHaveBeenCalledWith(orderAddress(['3', '1', '2', '4']));
138         expect(getFirstAddress(container)?.innerHTML).toBe('a1@proton.me');
139     });
141     describe('set as default', () => {
142         const setup = () => {
143             const createNotification = jest.fn();
144             mockedUseNotifications.mockReturnValue({ createNotification } as any);
145             let onSortEnd: ComponentPropsWithoutRef<typeof OrderableTable>['onSortEnd'];
146             mockedOrderableTable.mockImplementation((props) => {
147                 onSortEnd = props.onSortEnd;
148                 return <ActualOrderableTable {...props} />;
149             });
150             const handleSortEnd: typeof onSortEnd = (...args) => {
151                 onSortEnd?.(...args);
152             };
153             return { onSortEnd: handleSortEnd, createNotification };
154         };
156         it('should not be able to set an external address as default', () => {
157             const { onSortEnd, createNotification } = setup();
158             const { container } = render(<AddressesWithUser user={user} allowAddressDeletion={false} />);
160             onSortEnd({ newIndex: 0, oldIndex: 2 } as any, {} as any);
161             expect(createNotification).toHaveBeenCalledWith({
162                 type: 'error',
163                 text: 'An external address cannot be default',
164             });
165             expect(getFirstAddress(container)?.innerHTML).toBe('a@proton.me');
166         });
168         it('should not be able to set a disabled address as default', () => {
169             const { onSortEnd, createNotification } = setup();
170             const { container } = render(<AddressesWithUser user={user} allowAddressDeletion={false} />);
172             onSortEnd({ newIndex: 0, oldIndex: 3 } as any, {} as any);
173             expect(createNotification).toHaveBeenCalledWith({
174                 type: 'error',
175                 text: 'A disabled address cannot be default',
176             });
177             expect(getFirstAddress(container)?.innerHTML).toBe('a@proton.me');
178         });
179     });