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 = {
16 modificationTime: Date.now(),
20 const DEVICE_1: Device = {
26 modificationTime: Date.now(),
30 const DEVICE_2: Device = {
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', () => {
48 useNotifications: jest.fn(() => ({ createNotification: mockedCreateNotification })),
52 const mockedLoadDevices = jest.fn().mockResolvedValue(mockDevicesPayload);
53 jest.mock('./useDevicesApi', () => {
54 const useDeviceApi = () => {
56 loadDevices: mockedLoadDevices,
63 const mockedGetLink = jest.fn();
64 jest.mock('../_links', () => {
65 const useLink = jest.fn(() => ({
66 getLink: mockedGetLink,
71 describe('useLinksState', () => {
73 current: ReturnType<typeof useDevicesListingProvider>;
77 const wrapper = ({ children }: { children: React.ReactNode }) => (
78 <VolumesStateProvider>{children}</VolumesStateProvider>
81 mockedCreateNotification.mockClear();
82 mockedGetLink.mockClear();
83 mockedSendErrorReport.mockClear();
85 const { result } = renderHook(() => useDevicesListingProvider(), { wrapper });
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);
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);
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();
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();