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', () => ({
27 jest.mock('@proton/components/components/upsell/useUpsellConfig.ts', () => ({
32 jest.mock('@proton/shared/lib/helpers/upsell.ts', () => ({
34 useNewUpsellModalVariant: () => true,
35 getUpsellRef: () => '',
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', () => {
77 Type: ADDRESS_TYPE.TYPE_ORIGINAL,
86 Type: ADDRESS_TYPE.TYPE_EXTERNAL,
94 Email: 'a1@proton.me',
95 Type: ADDRESS_TYPE.TYPE_ALIAS,
104 Type: ADDRESS_TYPE.TYPE_PREMIUM,
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]');
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} />
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');
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} />;
150 const handleSortEnd: typeof onSortEnd = (...args) => {
151 onSortEnd?.(...args);
153 return { onSortEnd: handleSortEnd, createNotification };
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({
163 text: 'An external address cannot be default',
165 expect(getFirstAddress(container)?.innerHTML).toBe('a@proton.me');
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({
175 text: 'A disabled address cannot be default',
177 expect(getFirstAddress(container)?.innerHTML).toBe('a@proton.me');