Use same lock values as mobile clients
[ProtonMail-WebClient.git] / packages / docs-core / lib / UseCase / CreateComment.spec.ts
blob87dc4721aa0ce12d65991ab9511418c7e48ace42
1 import { Result } from '../Domain/Result/Result'
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'
10 jest.mock('../Util/GenerateUuid', () => ({
11   GenerateUUID: jest.fn(),
12 }))
14 const mockEncryptComment = {
15   execute: jest.fn(),
16 } as unknown as jest.Mocked<EncryptComment>
18 const mockCommentsApi = {
19   addCommentToThread: jest.fn(),
20 } as unknown as jest.Mocked<DocsApi>
22 const mockCommentsState = {
23   findThreadById: jest.fn(),
24   addComment: jest.fn(),
25   deleteComment: jest.fn(),
26   replacePlaceholderComment: jest.fn(),
27 } as unknown as jest.Mocked<LocalCommentsState>
29 describe('CreateComment', () => {
30   let createComment: CreateComment
32   const dto = {
33     text: 'Test comment',
34     threadID: 'thread-id',
35     lookup: { volumeId: 'volume-id', linkId: 'link-id' } as NodeMeta,
36     userDisplayName: 'User',
37     keys: {
38       userOwnAddress: 'foo@bar.com',
39     } as DocumentKeys,
40     commentsState: mockCommentsState,
41   }
43   beforeEach(() => {
44     createComment = new CreateComment(
45       mockCommentsApi as unknown as DocsApi,
46       mockEncryptComment as unknown as EncryptComment,
47     )
48     ;(GenerateUUID as jest.Mock).mockReturnValue('uuid')
49   })
51   it('should call encryptComment, api.addCommentToThread, and decryptComment in order', async () => {
52     mockCommentsState.findThreadById.mockReturnValue({ markID: 'mark-id' } as never)
53     mockEncryptComment.execute.mockResolvedValue(Result.ok('encrypted-comment'))
54     mockCommentsApi.addCommentToThread.mockResolvedValue(
55       Result.ok({ Comment: { text: 'encrypted-response-comment', AuthorEmail: 'foo@bar.com' } as never, Code: 1000 }),
56     )
58     await createComment.execute(dto)
60     expect(mockCommentsState.findThreadById).toHaveBeenCalledWith('thread-id')
61     expect(mockCommentsState.addComment).toHaveBeenCalledWith(expect.any(Comment), 'thread-id')
62     expect(mockEncryptComment.execute).toHaveBeenCalledWith('Test comment', 'mark-id', {
63       userOwnAddress: 'foo@bar.com',
64     })
65     expect(mockCommentsApi.addCommentToThread).toHaveBeenCalledWith({
66       volumeId: 'volume-id',
67       linkId: 'link-id',
68       threadId: 'thread-id',
69       encryptedContent: 'encrypted-comment',
70       parentCommentId: null,
71       authorEmail: 'foo@bar.com',
72     })
73     expect(mockCommentsState.replacePlaceholderComment).toHaveBeenCalled()
74   })
76   it('should delete comment if encryption fails', async () => {
77     mockCommentsState.findThreadById.mockReturnValue({ markID: 'mark-id' } as never)
78     mockEncryptComment.execute.mockResolvedValue(Result.fail('encryption error'))
80     const result = await createComment.execute(dto)
82     expect(result.isFailed()).toBe(true)
83     expect(mockCommentsState.deleteComment).toHaveBeenCalledWith({ commentID: 'uuid', threadID: 'thread-id' })
84   })
86   it('should delete comment if api call fails', async () => {
87     mockCommentsState.findThreadById.mockReturnValue({ markID: 'mark-id' } as never)
88     mockEncryptComment.execute.mockResolvedValue(Result.ok('encrypted-comment'))
89     mockCommentsApi.addCommentToThread.mockResolvedValue(Result.fail('api error'))
91     const result = await createComment.execute(dto)
93     expect(result.isFailed()).toBe(true)
94     expect(mockCommentsState.deleteComment).toHaveBeenCalledWith({ commentID: 'uuid', threadID: 'thread-id' })
95   })