Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / docs-core / lib / UseCase / CreateComment.spec.ts
blobffd76e38ec1fd5442abbd896fcf89f234b75fad9
1 import { ApiResult, DocumentRole, Result } from '@proton/docs-shared'
2 import type { DocumentKeys, NodeMeta } from '@proton/drive-store'
3 import { Comment } from '../Models'
4 import { GenerateUUID } from '../Util/GenerateUuid'
5 import type { EncryptComment } from './EncryptComment'
6 import type { LocalCommentsState } from '../Services/Comments/LocalCommentsState'
7 import { CreateComment } from './CreateComment'
8 import type { DocsApi } from '../Api/DocsApi'
9 import { DocsApiErrorCode } from '@proton/shared/lib/api/docs'
10 import type { DocumentEntitlements } from '../Types/DocumentEntitlements'
12 jest.mock('../Util/GenerateUuid', () => ({
13   GenerateUUID: jest.fn(),
14 }))
16 const mockEncryptComment = {
17   execute: jest.fn(),
18 } as unknown as jest.Mocked<EncryptComment>
20 const mockCommentsApi = {
21   addCommentToThread: jest.fn(),
22 } as unknown as jest.Mocked<DocsApi>
24 const mockCommentsState = {
25   findThreadById: jest.fn(),
26   addComment: jest.fn(),
27   deleteComment: jest.fn(),
28   replacePlaceholderComment: jest.fn(),
29 } as unknown as jest.Mocked<LocalCommentsState>
31 describe('CreateComment', () => {
32   let createComment: CreateComment
34   const entitlements = {
35     keys: {
36       userOwnAddress: 'foo@bar.com',
37     } as DocumentKeys,
38     role: new DocumentRole('Editor'),
39     nodeMeta: { volumeId: 'volume-id', linkId: 'link-id' } as NodeMeta,
40   } as unknown as DocumentEntitlements
42   const dto: Parameters<CreateComment['execute']>[0] = {
43     text: 'Test comment',
44     threadID: 'thread-id',
45     entitlements,
46     commentsState: mockCommentsState,
47     type: 1,
48     decryptedDocumentName: 'Test',
49   }
51   beforeEach(() => {
52     createComment = new CreateComment(
53       mockCommentsApi as unknown as DocsApi,
54       mockEncryptComment as unknown as EncryptComment,
55     )
56     ;(GenerateUUID as jest.Mock).mockReturnValue('uuid')
57   })
59   it('should call encryptComment, api.addCommentToThread, and decryptComment in order', async () => {
60     mockCommentsState.findThreadById.mockReturnValue({ markID: 'mark-id' } as never)
61     mockEncryptComment.execute.mockResolvedValue(Result.ok('encrypted-comment'))
62     mockCommentsApi.addCommentToThread.mockResolvedValue(
63       ApiResult.ok({
64         Comment: { text: 'encrypted-response-comment', AuthorEmail: 'foo@bar.com' } as never,
65         Code: 1000,
66       }),
67     )
69     await createComment.execute(dto)
71     expect(mockCommentsState.findThreadById).toHaveBeenCalledWith('thread-id')
72     expect(mockCommentsState.addComment).toHaveBeenCalledWith(expect.any(Comment), 'thread-id')
73     expect(mockEncryptComment.execute).toHaveBeenCalledWith('Test comment', 'mark-id', {
74       userOwnAddress: 'foo@bar.com',
75     })
76     expect(mockCommentsApi.addCommentToThread).toHaveBeenCalledWith(
77       {
78         threadId: 'thread-id',
79         encryptedContent: 'encrypted-comment',
80         parentCommentId: null,
81         decryptedDocumentName: 'Test',
82         type: 1,
83       },
84       entitlements,
85     )
86     expect(mockCommentsState.replacePlaceholderComment).toHaveBeenCalled()
87   })
89   it('should delete comment if encryption fails', async () => {
90     mockCommentsState.findThreadById.mockReturnValue({ markID: 'mark-id' } as never)
91     mockEncryptComment.execute.mockResolvedValue(Result.fail('encryption error'))
93     const result = await createComment.execute(dto)
95     expect(result.isFailed()).toBe(true)
96     expect(mockCommentsState.deleteComment).toHaveBeenCalledWith({ commentID: 'uuid', threadID: 'thread-id' })
97   })
99   it('should delete comment if api call fails', async () => {
100     mockCommentsState.findThreadById.mockReturnValue({ markID: 'mark-id' } as never)
101     mockEncryptComment.execute.mockResolvedValue(Result.ok('encrypted-comment'))
102     mockCommentsApi.addCommentToThread.mockResolvedValue(
103       ApiResult.fail({ code: DocsApiErrorCode.Unknown, message: 'api error' }),
104     )
106     const result = await createComment.execute(dto)
108     expect(result.isFailed()).toBe(true)
109     expect(mockCommentsState.deleteComment).toHaveBeenCalledWith({ commentID: 'uuid', threadID: 'thread-id' })
110   })