Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / applications / drive / src / app / store / _revisions / useRevisions.test.ts
blobef21b2ed18079527b04b323ca85d7994d9309b74
1 import { renderHook } from '@testing-library/react-hooks';
3 import { VERIFICATION_STATUS } from '@proton/crypto';
4 import { getIsConnectionIssue } from '@proton/shared/lib/api/helpers/apiErrorHelper';
6 import { sendErrorReport } from '../../utils/errorHandling';
7 import { useDriveCrypto } from '../_crypto';
8 import { useDownload } from '../_downloads';
9 import { useLink } from '../_links';
10 import type { ParsedExtendedAttributes } from '../_links/extendedAttributes';
11 import { decryptExtendedAttributes } from '../_links/extendedAttributes';
12 import useRevisions from './useRevisions';
14 jest.mock('../_crypto');
15 jest.mock('../_downloads', () => ({
16     useDownload: jest.fn(),
17 }));
18 jest.mock('../_links', () => ({
19     useLink: jest.fn(),
20 }));
22 jest.mock('../_links/extendedAttributes');
23 jest.mock('../../utils/errorHandling');
24 jest.mock('@proton/shared/lib/api/helpers/apiErrorHelper');
26 const mockedGetVerificationKey = jest.fn();
27 const mockedGetLinkPrivateKey = jest.fn();
28 const mockedDecryptExtendedAttributes = jest.mocked(decryptExtendedAttributes);
29 const mockedSendErrorReport = jest.mocked(sendErrorReport);
30 const mockedGetIsConnectionIssue = jest.mocked(getIsConnectionIssue);
32 jest.mocked(useDriveCrypto).mockImplementation(() => ({
33     ...jest.requireMock('../_crypto').useDriveCrypto,
34     getVerificationKey: mockedGetVerificationKey,
35 }));
37 jest.mocked(useLink).mockImplementation(() => ({
38     ...jest.requireMock('../_links').useDriveCrypto,
39     getLinkPrivateKey: mockedGetLinkPrivateKey,
40 }));
42 const mockedCheckFirstBlockSignature = jest.fn();
43 jest.mocked(useDownload).mockImplementation(() => ({
44     ...jest.requireMock('../_downloads').useDownload,
45     checkFirstBlockSignature: mockedCheckFirstBlockSignature,
46 }));
48 jest.mocked(decryptExtendedAttributes);
50 const revisionXattrs: ParsedExtendedAttributes = {
51     Common: {
52         ModificationTime: 1681715947,
53     },
55 const revisionEncryptedXattrs = 'encryptedXattrs';
56 const revisionSignatureAddress = 'revisionSignatureAddress';
57 const shareId = 'shareId';
58 const linkId = 'linkId';
60 describe('useRevision', () => {
61     let abortSignal: AbortSignal;
63     beforeEach(() => {
64         abortSignal = new AbortController().signal;
65     });
67     it('getRevisionDecryptedXattrs', async () => {
68         mockedGetVerificationKey.mockResolvedValue(['key']);
69         mockedGetLinkPrivateKey.mockResolvedValue('privateKey');
70         mockedDecryptExtendedAttributes.mockResolvedValue({
71             xattrs: revisionXattrs,
72             verified: VERIFICATION_STATUS.SIGNED_AND_VALID,
73         });
74         const {
75             result: {
76                 current: { getRevisionDecryptedXattrs },
77             },
78         } = renderHook(() => useRevisions(shareId, linkId));
79         const result = await getRevisionDecryptedXattrs(abortSignal, revisionEncryptedXattrs, revisionSignatureAddress);
81         expect(mockedGetVerificationKey).toHaveBeenCalledWith(revisionSignatureAddress);
82         expect(mockedGetLinkPrivateKey).toHaveBeenCalledWith(abortSignal, shareId, linkId);
83         expect(mockedDecryptExtendedAttributes).toHaveBeenCalledWith(revisionEncryptedXattrs, 'privateKey', ['key']);
84         expect(result).toStrictEqual({
85             xattrs: revisionXattrs,
86             signatureIssues: {
87                 xattrs: VERIFICATION_STATUS.SIGNED_AND_VALID,
88             },
89         });
90     });
92     it('getRevisionDecryptedXattrs should sendErrorReport if a promise failed', async () => {
93         mockedDecryptExtendedAttributes.mockResolvedValue({
94             xattrs: revisionXattrs,
95             verified: VERIFICATION_STATUS.SIGNED_AND_VALID,
96         });
97         mockedGetVerificationKey.mockResolvedValue(['key']);
98         const error = new Error('getLinkPrivateKey error');
99         mockedGetLinkPrivateKey.mockRejectedValue(error);
100         const {
101             result: {
102                 current: { getRevisionDecryptedXattrs },
103             },
104         } = renderHook(() => useRevisions(shareId, linkId));
105         const result = await getRevisionDecryptedXattrs(abortSignal, revisionEncryptedXattrs, revisionSignatureAddress);
106         expect(result).toBeUndefined();
107         expect(mockedSendErrorReport).toHaveBeenCalledWith(error);
108     });
110     it('checkRevisionSignature result should be undefined if no issues', async () => {
111         const revisionId = 'revisionId';
112         mockedCheckFirstBlockSignature.mockResolvedValueOnce(undefined);
113         const {
114             result: {
115                 current: { checkRevisionSignature },
116             },
117         } = renderHook(() => useRevisions(shareId, linkId));
118         const result = await checkRevisionSignature(abortSignal, revisionId);
119         expect(mockedCheckFirstBlockSignature).toHaveBeenCalledWith(abortSignal, shareId, linkId, revisionId);
120         expect(result).toBeUndefined();
121     });
123     it('checkRevisionSignature should throw an error if there is connection issues', async () => {
124         const revisionId = 'revisionId';
125         const error = new Error('Network error');
126         mockedCheckFirstBlockSignature.mockRejectedValue(error);
127         mockedGetIsConnectionIssue.mockReturnValue(true);
128         const {
129             result: {
130                 current: { checkRevisionSignature },
131             },
132         } = renderHook(() => useRevisions(shareId, linkId));
133         const errorResult = checkRevisionSignature(abortSignal, revisionId);
134         await expect(errorResult).rejects.toThrowError(error);
135         expect(mockedGetIsConnectionIssue).toHaveBeenCalledWith(error);
136     });
138     it('checkRevisionSignature should sendErrorReport and return signatureIssues', async () => {
139         const revisionId = 'revisionId';
140         const error = new Error('checkFirstBlockSignature error');
141         mockedCheckFirstBlockSignature.mockRejectedValue(error);
142         mockedGetIsConnectionIssue.mockReturnValue(false);
143         const {
144             result: {
145                 current: { checkRevisionSignature },
146             },
147         } = renderHook(() => useRevisions(shareId, linkId));
148         const result = await checkRevisionSignature(abortSignal, revisionId);
149         expect(mockedSendErrorReport).toHaveBeenCalledWith(error);
150         expect(result).toStrictEqual({
151             contentKeyPacket: VERIFICATION_STATUS.NOT_SIGNED,
152             blocks: VERIFICATION_STATUS.NOT_SIGNED,
153             thumbnail: VERIFICATION_STATUS.NOT_SIGNED,
154         });
155     });