Merge branch 'feat/rbf-wording' into 'main'
[ProtonMail-WebClient.git] / packages / drive-store / store / _devices / useDevicesListing.test.tsx
blob9f0534cb56d1d0709735652a8bac03fa7fc5991e
1 import { act, renderHook } from '@testing-library/react-hooks';
3 import { sendErrorReport } from '../../utils/errorHandling';
4 import { VolumesStateProvider } from '../_volumes/useVolumesState';
5 import type { Device } from './interface';
6 import { useDevicesListingProvider } from './useDevicesListing';
8 const SHARE_ID_0 = 'shareId0';
9 const SHARE_ID_1 = 'shareId1';
10 const DEVICE_0: Device = {
11     id: '1',
12     volumeId: '1',
13     shareId: SHARE_ID_0,
14     linkId: 'linkId0',
15     name: 'HOME-DESKTOP',
16     modificationTime: Date.now(),
17     haveLegacyName: true,
20 const DEVICE_1: Device = {
21     id: '2',
22     volumeId: '1',
23     shareId: SHARE_ID_1,
24     linkId: 'linkId1',
25     name: 'Macbook Pro',
26     modificationTime: Date.now(),
27     haveLegacyName: true,
30 const DEVICE_2: Device = {
31     id: '3',
32     volumeId: '1',
33     shareId: SHARE_ID_1,
34     linkId: 'linkId1',
35     name: '',
36     modificationTime: Date.now(),
37     haveLegacyName: false,
40 const mockDevicesPayload = [DEVICE_0, DEVICE_1];
42 jest.mock('../../utils/errorHandling');
43 const mockedSendErrorReport = jest.mocked(sendErrorReport);
45 const mockedCreateNotification = jest.fn();
46 jest.mock('@proton/components', () => {
47     return {
48         useNotifications: jest.fn(() => ({ createNotification: mockedCreateNotification })),
49     };
50 });
52 const mockedLoadDevices = jest.fn().mockResolvedValue(mockDevicesPayload);
53 jest.mock('./useDevicesApi', () => {
54     const useDeviceApi = () => {
55         return {
56             loadDevices: mockedLoadDevices,
57         };
58     };
60     return useDeviceApi;
61 });
63 const mockedGetLink = jest.fn();
64 jest.mock('../_links', () => {
65     const useLink = jest.fn(() => ({
66         getLink: mockedGetLink,
67     }));
68     return { useLink };
69 });
71 describe('useLinksState', () => {
72     let hook: {
73         current: ReturnType<typeof useDevicesListingProvider>;
74     };
76     beforeEach(() => {
77         const wrapper = ({ children }: { children: React.ReactNode }) => (
78             <VolumesStateProvider>{children}</VolumesStateProvider>
79         );
81         mockedCreateNotification.mockClear();
82         mockedGetLink.mockClear();
83         mockedSendErrorReport.mockClear();
85         const { result } = renderHook(() => useDevicesListingProvider(), { wrapper });
86         hook = result;
87     });
89     it('finds device by shareId', async () => {
90         await act(async () => {
91             await hook.current.loadDevices(new AbortController().signal);
92             const device = hook.current.getDeviceByShareId(SHARE_ID_0);
93             expect(device).toEqual(DEVICE_0);
94         });
95     });
97     it('lists loaded devices', async () => {
98         await act(async () => {
99             await hook.current.loadDevices(new AbortController().signal);
100             const cachedDevices = hook.current.cachedDevices;
102             const targetList = [DEVICE_0, DEVICE_1];
103             expect(cachedDevices).toEqual(targetList);
104         });
105     });
107     it('should call getLink to get root link', async () => {
108         mockedLoadDevices.mockResolvedValue([DEVICE_2]);
109         await act(async () => {
110             const name = 'rootName';
111             mockedGetLink.mockResolvedValue({ name });
112             await hook.current.loadDevices(new AbortController().signal);
113             const cachedDevices = hook.current.cachedDevices;
115             const targetList = [{ ...DEVICE_2, name }];
116             expect(cachedDevices).toEqual(targetList);
117             expect(mockedGetLink).toHaveBeenCalled();
118             expect(mockedCreateNotification).not.toHaveBeenCalled();
119             expect(mockedSendErrorReport).not.toHaveBeenCalled();
120         });
121     });
123     it('should notify the user if there is a failure loading a link', async () => {
124         mockedLoadDevices.mockResolvedValue([DEVICE_2]);
125         await act(async () => {
126             mockedGetLink.mockRejectedValue('error');
128             await hook.current.loadDevices(new AbortController().signal);
129             const cachedDevices = hook.current.cachedDevices;
131             const targetList: Device[] = [];
132             expect(cachedDevices).toEqual(targetList);
133             expect(mockedGetLink).toHaveBeenCalled();
134             expect(mockedCreateNotification).toHaveBeenCalled();
135             expect(mockedSendErrorReport).toHaveBeenCalled();
136         });
137     });