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 { useApi, useKTVerifier, useNotifications } from '@proton/components';
10 import OrderableTable from '@proton/components/components/orderableTable/OrderableTable';
11 import { orderAddress } from '@proton/shared/lib/api/addresses';
12 import { ADDRESS_TYPE } from '@proton/shared/lib/constants';
13 import type { Address, UserModel } from '@proton/shared/lib/interfaces';
14 import { mockUseFeature } from '@proton/testing/lib/mockUseFeature';
15 import useFlag from '@proton/unleash/useFlag';
17 import AddressesWithUser from './AddressesWithUser';
19 jest.mock('@proton/components/hooks/useEventManager', () => () => ({}));
20 jest.mock('@proton/components/components/upsell/useOneDollarPromo.tsx', () => ({
25 jest.mock('@proton/components/components/upsell/useUpsellConfig.ts', () => ({
30 jest.mock('@proton/shared/lib/helpers/upsell.ts', () => ({
32 useNewUpsellModalVariant: () => true,
33 getUpsellRef: () => '',
36 jest.mock('@proton/components/components/orderableTable/OrderableTable');
37 const ActualOrderableTable = jest.requireActual('@proton/components/components/orderableTable/OrderableTable').default;
38 const mockedOrderableTable = OrderableTable as jest.MockedFunction<typeof OrderableTable>;
40 jest.mock('@proton/account/addresses/hooks');
41 const mockedUseAddresses = useAddresses as jest.MockedFunction<typeof useAddresses>;
43 jest.mock('@proton/components/hooks/useApi');
44 const mockedUseApi = useApi as jest.MockedFunction<typeof useApi>;
46 jest.mock('@proton/components/hooks/useNotifications');
47 const mockedUseNotifications = useNotifications as jest.MockedFunction<typeof useNotifications>;
49 jest.mock('@proton/account/user/hooks');
50 const mockedUseUser = useUser as jest.MockedFunction<typeof useUser>;
52 jest.mock('@proton/account/addressKeys/hooks');
53 const mockedUseAddressesKeys = useAddressesKeys as jest.MockedFunction<typeof useAddressesKeys>;
55 jest.mock('@proton/components/containers/keyTransparency/useKTVerifier');
56 const mockedUseKTVerifier = useKTVerifier as jest.MockedFunction<typeof useKTVerifier>;
58 jest.mock('@proton/unleash/useFlag');
59 const mockedUseFlag = useFlag as jest.MockedFunction<any>;
61 jest.mock('@proton/account/organizationKey/hooks');
62 const mockedUseOrganizationKey = useOrganizationKey as jest.MockedFunction<typeof useOrganizationKey>;
64 jest.mock('@proton/redux-shared-store');
66 describe('addresses with user', () => {
75 Type: ADDRESS_TYPE.TYPE_ORIGINAL,
84 Type: ADDRESS_TYPE.TYPE_EXTERNAL,
92 Email: 'a1@proton.me',
93 Type: ADDRESS_TYPE.TYPE_ALIAS,
102 Type: ADDRESS_TYPE.TYPE_PREMIUM,
110 mockedUseAddresses.mockReturnValue([addresses, false]);
111 mockedOrderableTable.mockImplementation(ActualOrderableTable);
112 mockedUseNotifications.mockReturnValue({} as any);
113 mockedUseUser.mockReturnValue([{}] as any);
114 mockedUseAddressesKeys.mockReturnValue([{}] as any);
115 mockedUseKTVerifier.mockReturnValue({} as any);
116 mockedUseOrganizationKey.mockReturnValue([{}] as any);
117 mockedUseFlag.mockReturnValue(true);
118 mockUseFeature({ feature: { Value: true } as any });
120 const getFirstAddress = (container: HTMLElement) => {
121 return container.querySelector('[title]');
124 it('should be able to set an alias as default', async () => {
125 const mockApi = jest.fn();
126 mockedUseApi.mockReturnValue(mockApi);
128 const { getByTestId, getByText, container } = render(
129 <AddressesWithUser user={user} allowAddressDeletion={false} />
132 // Assumes that "Make default" is displayed on the address we're interested in
133 fireEvent.click(getByTestId('dropdownActions:dropdown'));
134 fireEvent.click(getByText('Set as default'));
135 expect(mockApi).toHaveBeenCalledWith(orderAddress(['3', '1', '2', '4']));
136 expect(getFirstAddress(container)?.innerHTML).toBe('a1@proton.me');
139 describe('set as default', () => {
140 const setup = () => {
141 const createNotification = jest.fn();
142 mockedUseNotifications.mockReturnValue({ createNotification } as any);
143 let onSortEnd: ComponentPropsWithoutRef<typeof OrderableTable>['onSortEnd'];
144 mockedOrderableTable.mockImplementation((props) => {
145 onSortEnd = props.onSortEnd;
146 return <ActualOrderableTable {...props} />;
148 const handleSortEnd: typeof onSortEnd = (...args) => {
149 onSortEnd?.(...args);
151 return { onSortEnd: handleSortEnd, createNotification };
154 it('should not be able to set an external address as default', () => {
155 const { onSortEnd, createNotification } = setup();
156 const { container } = render(<AddressesWithUser user={user} allowAddressDeletion={false} />);
158 onSortEnd({ newIndex: 0, oldIndex: 2 } as any, {} as any);
159 expect(createNotification).toHaveBeenCalledWith({
161 text: 'An external address cannot be default',
163 expect(getFirstAddress(container)?.innerHTML).toBe('a@proton.me');
166 it('should not be able to set a disabled address as default', () => {
167 const { onSortEnd, createNotification } = setup();
168 const { container } = render(<AddressesWithUser user={user} allowAddressDeletion={false} />);
170 onSortEnd({ newIndex: 0, oldIndex: 3 } as any, {} as any);
171 expect(createNotification).toHaveBeenCalledWith({
173 text: 'A disabled address cannot be default',
175 expect(getFirstAddress(container)?.innerHTML).toBe('a@proton.me');