* refactor: started with draft, done until new tabs for draft
* refactor: change the query and added the screen for draft
* added condition for fetching draft for channel delete or not
* refactor: added draft screen
* linter fixes
* Added draft post component
* added avatar and header display name for the draft post list
* added channel info component
* channel info completed
* proper naming
* added image file markdown acknowledgement support
* draft actions
* Fix the draft receiver in drafts
* separated send message handler
* Done with send drafts
* done with delete drafts
* change save to send draft
* handle lengthy message with show more button
* done with persistent message edit, send and delete drafts
* added alert for sending message
* added update at time for the drafts
* en.json extract fix
* Updated dependencies for useCallback
* refactor: added drafts list to animated list
* added swipeable component and delete conformation for drafts
* done with rendering of images in markdown for drafts
* en.json issue fixed
* fix en.json issue
* refactor: en.json fix
* addressed review comments
* updated image metadata handling code
* linter fixes
* added the empty draft screen
* linter fix
* style fix
* back button an android takes to the channel list page
* en.json fix
* draft actions theme compatible
* CSS fix for draft channel_info and avatar component
* removed the badge icon and change font style drafts
* fix send alert sender name for GMs
* updated snapshot
* added testId to the drafts components
* updated send draft test id
* clicking on draft takes to the channel
* Added toptip for draft tours
* intl extract
* Rebase to main and reverted local testing changes
* Added tooltip for drafts
* addressed review comments
* reset navigation when click on a draft in draft tabs
* fix the theme issue and navigation issue
* reverted back the draft click navigation changes
* observing draft when hitting back button
* removed the unwanted animiation
* updated regex for parsing markdown
* removed unnecessary checks and change folder name
* removed react memo and merge unwanted observes function
* removed unnecessary comments
* changed the name for observing and querying draft function
* removed memo from component level
* Text to FormattedText component
* Text to formatted text, change image name
* added confirmation modal for deleting draft from bottomsheet
* using common send_handler for both draft and post
* removed magic number for tooltip and bottomsheet
* renamed channel_info to draft_post_header
* text to formattedText for Edit drafts
* removed unnecessary changes
* minor fixes
* mounting draft only when there is draft
* map to reduce
* renamed SwipeableDraft to DraftSwipeAction
* name fixes
* isValidUrl to isParsableUrl and added test
* added test and addressed minor review comments
* added inline component for the duplicate code
* inlt fixes
* clearDraft is not optional
* optimised categories_list.tsx component
* Swipeable to ReanimatedSwipeable, TouchableWithoutFeedback to Pressable and folder name changes
* Added comment and disabled eslint rule for showing warning
* fixed component file name
* minor'
* Removed deprecated Animated createAnimatedComponent flatlist
* added test for missing protocol check
* import change for SwipeableMethod
* active tab for tablet view
* Updated the drafts icons
* Updated compass-icon version to v0.1.48
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
(cherry picked from commit 84eded1bde)
Co-authored-by: Rajat Dabade <rajatdabade1997@gmail.com>
282 lines
10 KiB
TypeScript
282 lines
10 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
/* eslint-disable max-lines */
|
|
|
|
import DatabaseManager from '@database/manager';
|
|
|
|
import {
|
|
updateDraftFile,
|
|
removeDraftFile,
|
|
updateDraftMessage,
|
|
addFilesToDraft,
|
|
removeDraft,
|
|
updateDraftPriority,
|
|
updateDraftMarkdownImageMetadata,
|
|
} from './draft';
|
|
|
|
import type ServerDataOperator from '@database/operator/server_data_operator';
|
|
import type DraftModel from '@typings/database/models/servers/draft';
|
|
|
|
let operator: ServerDataOperator;
|
|
const serverUrl = 'baseHandler.test.com';
|
|
const channelId = 'id1';
|
|
const teamId = 'tId1';
|
|
const channel: Channel = {
|
|
id: channelId,
|
|
team_id: teamId,
|
|
total_msg_count: 0,
|
|
} as Channel;
|
|
const fileInfo: FileInfo = {
|
|
id: 'fileid',
|
|
clientId: 'clientid',
|
|
localPath: 'path1',
|
|
} as FileInfo;
|
|
const draft: Draft = {
|
|
channel_id: channel.id,
|
|
message: 'test',
|
|
root_id: '',
|
|
update_at: Date.now(),
|
|
} as Draft;
|
|
|
|
beforeEach(async () => {
|
|
await DatabaseManager.init([serverUrl]);
|
|
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await DatabaseManager.destroyServerDatabase(serverUrl);
|
|
});
|
|
|
|
describe('updateDraftFile', () => {
|
|
it('handle not found database', async () => {
|
|
const {error} = await updateDraftFile('foo', channelId, '', fileInfo, false);
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('handle no draft', async () => {
|
|
const {error} = await updateDraftFile(serverUrl, channelId, '', fileInfo, false);
|
|
expect(error).toBeTruthy();
|
|
expect(error).toBe('no draft');
|
|
});
|
|
|
|
it('handle no file', async () => {
|
|
await operator.handleDraft({drafts: [draft], prepareRecordsOnly: false});
|
|
|
|
const {error} = await updateDraftFile(serverUrl, channelId, '', fileInfo, false);
|
|
expect(error).toBeTruthy();
|
|
expect(error).toBe('file not found');
|
|
});
|
|
|
|
it('update draft file', async () => {
|
|
await operator.handleDraft({drafts: [{...draft, files: [{...fileInfo, localPath: 'path0'}]}], prepareRecordsOnly: false});
|
|
|
|
const {draft: draftModel, error} = await updateDraftFile(serverUrl, channelId, '', fileInfo);
|
|
expect(error).toBeUndefined();
|
|
expect(draftModel).toBeDefined();
|
|
expect(draftModel?.files?.length).toBe(1);
|
|
expect(draftModel?.files![0].localPath).toBe('path1');
|
|
});
|
|
});
|
|
|
|
describe('removeDraftFile', () => {
|
|
it('handle not found database', async () => {
|
|
const {error} = await removeDraftFile('foo', channelId, '', '', false);
|
|
expect(error).toBeTruthy();
|
|
});
|
|
|
|
it('handle no draft', async () => {
|
|
const {error} = await removeDraftFile(serverUrl, channelId, '', 'clientid', false);
|
|
expect(error).toBeTruthy();
|
|
expect(error).toBe('no draft');
|
|
});
|
|
|
|
it('handle no file', async () => {
|
|
await operator.handleDraft({drafts: [draft], prepareRecordsOnly: false});
|
|
|
|
const {error} = await removeDraftFile(serverUrl, channelId, '', 'clientid', false);
|
|
expect(error).toBeTruthy();
|
|
expect(error).toBe('file not found');
|
|
});
|
|
|
|
it('remove draft file', async () => {
|
|
await operator.handleDraft({drafts: [{...draft, files: [fileInfo]}], prepareRecordsOnly: false});
|
|
|
|
const {draft: draftModel, error} = await removeDraftFile(serverUrl, channelId, '', 'clientid');
|
|
expect(error).toBeUndefined();
|
|
expect(draftModel).toBeDefined();
|
|
});
|
|
|
|
it('remove draft file, no message', async () => {
|
|
await operator.handleDraft({drafts: [{channel_id: channel.id, files: [fileInfo], root_id: '', update_at: Date.now()}], prepareRecordsOnly: false});
|
|
|
|
const {draft: draftModel, error} = await removeDraftFile(serverUrl, channelId, '', 'clientid', false);
|
|
expect(error).toBeUndefined();
|
|
expect(draftModel).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('updateDraftMessage', () => {
|
|
it('handle not found database', async () => {
|
|
const result = await updateDraftMessage('foo', channelId, '', 'newmessage', false) as {draft: unknown; error: unknown};
|
|
expect(result.error).toBeDefined();
|
|
expect(result.draft).toBeUndefined();
|
|
});
|
|
|
|
it('update draft message, blank message, no draft', async () => {
|
|
const result = await updateDraftMessage(serverUrl, channelId, '', '', false) as {draft: unknown; error: unknown};
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.draft).toBeUndefined();
|
|
});
|
|
|
|
it('update draft message, no draft', async () => {
|
|
const models = await updateDraftMessage(serverUrl, channelId, '', 'newmessage', false) as DraftModel[];
|
|
expect(models).toBeDefined();
|
|
expect(models?.length).toBe(1);
|
|
});
|
|
|
|
it('update draft message', async () => {
|
|
await operator.handleDraft({drafts: [{...draft, files: [fileInfo]}], prepareRecordsOnly: false});
|
|
|
|
const result = await updateDraftMessage(serverUrl, channelId, '', 'newmessage') as {draft: DraftModel; error: unknown};
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.draft).toBeDefined();
|
|
expect(result.draft.message).toBe('newmessage');
|
|
});
|
|
|
|
it('update draft message, same message', async () => {
|
|
await operator.handleDraft({drafts: [{...draft, files: [fileInfo]}], prepareRecordsOnly: false});
|
|
|
|
const result = await updateDraftMessage(serverUrl, channelId, '', 'test', false) as {draft: DraftModel; error: unknown};
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.draft).toBeDefined();
|
|
expect(result.draft.message).toBe('test');
|
|
});
|
|
|
|
it('update draft message, no file', async () => {
|
|
await operator.handleDraft({drafts: [{channel_id: channel.id, files: [], root_id: '', update_at: Date.now()}], prepareRecordsOnly: false});
|
|
|
|
const result = await updateDraftMessage(serverUrl, channelId, '', 'newmessage', false) as {draft: DraftModel; error: unknown};
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.draft).toBeDefined();
|
|
expect(result.draft.message).toBe('newmessage');
|
|
});
|
|
});
|
|
|
|
describe('addFilesToDraft', () => {
|
|
it('handle not found database', async () => {
|
|
const result = await addFilesToDraft('foo', channelId, '', [], false) as {draft: unknown; error: unknown};
|
|
expect(result.error).toBeDefined();
|
|
expect(result.draft).toBeUndefined();
|
|
});
|
|
|
|
it('add draft files, no draft', async () => {
|
|
const models = await addFilesToDraft(serverUrl, channelId, '', [fileInfo], false) as DraftModel[];
|
|
expect(models).toBeDefined();
|
|
expect(models?.length).toBe(1);
|
|
});
|
|
|
|
it('add draft files', async () => {
|
|
await operator.handleDraft({drafts: [draft], prepareRecordsOnly: false});
|
|
|
|
const result = await addFilesToDraft(serverUrl, channelId, '', [fileInfo]) as {draft: DraftModel; error: unknown};
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.draft).toBeDefined();
|
|
expect(result?.draft.files.length).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('removeDraft', () => {
|
|
it('handle not found database', async () => {
|
|
const result = await removeDraft('foo', channelId, '');
|
|
expect(result.error).toBeDefined();
|
|
expect(result.draft).toBeUndefined();
|
|
});
|
|
|
|
it('handle no draft', async () => {
|
|
const result = await removeDraft(serverUrl, channelId, '');
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.draft).toBeUndefined();
|
|
});
|
|
|
|
it('remove draft', async () => {
|
|
await operator.handleDraft({drafts: [draft], prepareRecordsOnly: false});
|
|
|
|
const result = await removeDraft(serverUrl, channelId);
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.draft).toBeDefined();
|
|
});
|
|
|
|
it('remove draft with root id', async () => {
|
|
await operator.handleDraft({drafts: [{...draft, root_id: 'postid'}], prepareRecordsOnly: false});
|
|
|
|
const result = await removeDraft(serverUrl, channelId, 'postid');
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.draft).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('updateDraftPriority', () => {
|
|
const postPriority: PostPriority = {
|
|
priority: 'urgent',
|
|
} as PostPriority;
|
|
|
|
it('handle not found database', async () => {
|
|
const result = await updateDraftPriority('foo', channelId, '', postPriority) as {draft: unknown; error: unknown};
|
|
expect(result.error).toBeDefined();
|
|
expect(result.draft).toBeUndefined();
|
|
});
|
|
|
|
it('handle no draft', async () => {
|
|
const models = await updateDraftPriority(serverUrl, channelId, '', postPriority) as DraftModel[];
|
|
expect(models).toBeDefined();
|
|
expect(models.length).toBe(1);
|
|
expect(models[0].metadata?.priority?.priority).toBe(postPriority.priority);
|
|
});
|
|
|
|
it('update draft priority', async () => {
|
|
await operator.handleDraft({drafts: [draft], prepareRecordsOnly: false});
|
|
|
|
const result = await updateDraftPriority(serverUrl, channelId, '', postPriority) as {draft: DraftModel; error: unknown};
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.draft).toBeDefined();
|
|
expect(result.draft.metadata?.priority?.priority).toBe(postPriority.priority);
|
|
});
|
|
});
|
|
|
|
describe('updateDraftMarkdownImageMetadata', () => {
|
|
const postImageData: PostImage = {
|
|
height: 1080,
|
|
width: 1920,
|
|
format: 'jpg',
|
|
frame_count: undefined,
|
|
};
|
|
|
|
it('handle not found database', async () => {
|
|
const result = await updateDraftMarkdownImageMetadata({
|
|
serverUrl: 'foo',
|
|
channelId,
|
|
rootId: '',
|
|
imageMetadata: {
|
|
image1: postImageData,
|
|
},
|
|
}) as {draft: unknown; error: unknown};
|
|
expect(result.error).toBeDefined();
|
|
expect(result.draft).toBeUndefined();
|
|
});
|
|
|
|
it('handle update image metadata', async () => {
|
|
await operator.handleDraft({drafts: [draft], prepareRecordsOnly: false});
|
|
const result = await updateDraftMarkdownImageMetadata({
|
|
serverUrl,
|
|
channelId,
|
|
rootId: '',
|
|
imageMetadata: {
|
|
image1: postImageData,
|
|
},
|
|
}) as {draft: DraftModel; error: unknown};
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.draft).toBeDefined();
|
|
expect(result.draft.metadata?.images?.image1).toEqual(postImageData);
|
|
});
|
|
});
|