diff --git a/app/database/admin/data_operator/comparators/index.ts b/app/database/admin/data_operator/comparators/index.ts index 7d536a2f6..a498343a6 100644 --- a/app/database/admin/data_operator/comparators/index.ts +++ b/app/database/admin/data_operator/comparators/index.ts @@ -11,7 +11,10 @@ import { RawCustomEmoji, RawDraft, RawGlobal, + RawGroup, RawGroupMembership, + RawGroupsInTeam, + RawGroupsInChannel, RawPost, RawPreference, RawRole, @@ -23,7 +26,10 @@ import { } from '@typings/database/database'; import Draft from '@typings/database/draft'; import Global from '@typings/database/global'; +import Group from '@typings/database/group'; import GroupMembership from '@typings/database/group_membership'; +import GroupsInChannel from '@typings/database/groups_in_channel'; +import GroupsInTeam from '@typings/database/groups_in_team'; import Post from '@typings/database/post'; import Preference from '@typings/database/preference'; import Servers from '@typings/database/servers'; @@ -102,3 +108,15 @@ export const isRecordGroupMembershipEqualToRaw = (record: GroupMembership, raw: export const isRecordChannelMembershipEqualToRaw = (record: ChannelMembership, raw: RawChannelMembership) => { return raw.user_id === record.userId && raw.channel_id === record.channelId; }; + +export const isRecordGroupEqualToRaw = (record: Group, raw: RawGroup) => { + return raw.name === record.name && raw.display_name === record.displayName; +}; + +export const isRecordGroupsInTeamEqualToRaw = (record: GroupsInTeam, raw: RawGroupsInTeam) => { + return raw.team_id === record.teamId && raw.group_id === record.groupId; +}; + +export const isRecordGroupsInChannelEqualToRaw = (record: GroupsInChannel, raw: RawGroupsInChannel) => { + return raw.channel_id === record.channelId && raw.group_id === record.groupId; +}; diff --git a/app/database/admin/data_operator/handlers/index.ts b/app/database/admin/data_operator/handlers/index.ts index 185ddec9c..96d24ff35 100644 --- a/app/database/admin/data_operator/handlers/index.ts +++ b/app/database/admin/data_operator/handlers/index.ts @@ -11,7 +11,10 @@ import { isRecordCustomEmojiEqualToRaw, isRecordDraftEqualToRaw, isRecordGlobalEqualToRaw, + isRecordGroupEqualToRaw, isRecordGroupMembershipEqualToRaw, + isRecordGroupsInChannelEqualToRaw, + isRecordGroupsInTeamEqualToRaw, isRecordPostEqualToRaw, isRecordPreferenceEqualToRaw, isRecordRoleEqualToRaw, @@ -26,7 +29,6 @@ import CustomEmoji from '@typings/database/custom_emoji'; import { BatchOperationsArgs, DatabaseInstance, - ProcessInputsArgs, HandleEntityRecordsArgs, HandleFilesArgs, HandleIsolatedEntityArgs, @@ -37,12 +39,16 @@ import { PostImage, PrepareForDatabaseArgs, PrepareRecordsArgs, + ProcessInputsArgs, RawChannelMembership, RawCustomEmoji, RawDraft, RawEmbed, RawFile, + RawGroup, RawGroupMembership, + RawGroupsInChannel, + RawGroupsInTeam, RawPost, RawPostMetadata, RawPostsInThread, @@ -70,6 +76,9 @@ import { operateFileRecord, operateGlobalRecord, operateGroupMembershipRecord, + operateGroupRecord, + operateGroupsInChannelRecord, + operateGroupsInTeamRecord, operatePostInThreadRecord, operatePostMetadataRecord, operatePostRecord, @@ -98,6 +107,9 @@ const { CUSTOM_EMOJI, DRAFT, FILE, + GROUP, + GROUPS_IN_CHANNEL, + GROUPS_IN_TEAM, GROUP_MEMBERSHIP, POST, POSTS_IN_CHANNEL, @@ -109,6 +121,8 @@ const { USER, } = MM_TABLES.SERVER; +// TODO : We assume that we are receiving clean&correct data from the server. Hence, we can never have two posts in an array with the same post_id. This should be confirmed. + class DataOperator { /** * serverDatabase : In a multi-server configuration, this connection will be used by WebSockets and other parties to update databases other than the active one. @@ -802,6 +816,72 @@ class DataOperator { }); }; + /** + * handleGroup: Handler responsible for the Create/Update operations occurring on the GROUP entity from the 'Server' schema + * @param {RawGroup[]} groups + * @throws DataOperatorException + * @returns {Promise} + */ + handleGroup = async (groups: RawGroup[]) => { + if (!groups.length) { + throw new DataOperatorException( + 'An empty "groups" array has been passed to the handleGroup method', + ); + } + + await this.handleEntityRecords({ + comparator: isRecordGroupEqualToRaw, + fieldName: 'name', + operator: operateGroupRecord, + rawValues: groups, + tableName: GROUP, + }); + }; + + /** + * handleGroupsInTeam: Handler responsible for the Create/Update operations occurring on the GROUPS_IN_TEAM entity from the 'Server' schema + * @param {RawGroupsInTeam[]} groupsInTeam + * @throws DataOperatorException + * @returns {Promise} + */ + handleGroupsInTeam = async (groupsInTeam: RawGroupsInTeam[]) => { + if (!groupsInTeam.length) { + throw new DataOperatorException( + 'An empty "groups" array has been passed to the handleGroupsInTeam method', + ); + } + + await this.handleEntityRecords({ + comparator: isRecordGroupsInTeamEqualToRaw, + fieldName: 'group_id', + operator: operateGroupsInTeamRecord, + rawValues: groupsInTeam, + tableName: GROUPS_IN_TEAM, + }); + }; + + /** + * handleGroupsInChannel: Handler responsible for the Create/Update operations occurring on the GROUPS_IN_CHANNEL entity from the 'Server' schema + * @param {RawGroupsInChannel[]} groupsInChannel + * @throws DataOperatorException + * @returns {Promise} + */ + handleGroupsInChannel = async (groupsInChannel: RawGroupsInChannel[]) => { + if (!groupsInChannel.length) { + throw new DataOperatorException( + 'An empty "groups" array has been passed to the handleGroupsInTeam method', + ); + } + + await this.handleEntityRecords({ + comparator: isRecordGroupsInChannelEqualToRaw, + fieldName: 'group_id', + operator: operateGroupsInChannelRecord, + rawValues: groupsInChannel, + tableName: GROUPS_IN_CHANNEL, + }); + }; + /** * handleEntityRecords : Utility that processes some entities' data against values already present in the database so as to avoid duplicity. * @param {HandleEntityRecordsArgs} handleEntityRecords diff --git a/app/database/admin/data_operator/handlers/test.ts b/app/database/admin/data_operator/handlers/test.ts index fdef21069..b36746d3e 100644 --- a/app/database/admin/data_operator/handlers/test.ts +++ b/app/database/admin/data_operator/handlers/test.ts @@ -842,4 +842,78 @@ describe('*** DataOperator: Handlers tests ***', () => { expect(spyOnExecuteInDatabase).toHaveBeenCalledTimes(1); }); + + it('=> HandleGroup: should write to GROUP entity', async () => { + expect.assertions(1); + + const spyOnExecuteInDatabase = jest.spyOn(DataOperator as any, 'executeInDatabase'); + + await createConnection(true); + + await DataOperator.handleGroup([ + { + id: 'id_groupdfjdlfkjdkfdsf', + name: 'mobile_team', + display_name: 'mobile team', + description: '', + source: '', + remote_id: '', + create_at: 0, + update_at: 0, + delete_at: 0, + has_syncables: true, + }, + ]); + + expect(spyOnExecuteInDatabase).toHaveBeenCalledTimes(1); + }); + + it('=> HandleGroupsInTeam: should write to GROUPS_IN_TEAM entity', async () => { + expect.assertions(1); + + const spyOnExecuteInDatabase = jest.spyOn(DataOperator as any, 'executeInDatabase'); + + await createConnection(true); + + await DataOperator.handleGroupsInTeam([ + { + team_id: 'team_899', + team_display_name: '', + team_type: '', + group_id: 'group_id89', + auto_add: true, + create_at: 0, + delete_at: 0, + update_at: 0, + }, + ]); + + expect(spyOnExecuteInDatabase).toHaveBeenCalledTimes(1); + }); + + it('=> HandleGroupsInChannel: should write to GROUPS_IN_CHANNEL entity', async () => { + expect.assertions(1); + + const spyOnExecuteInDatabase = jest.spyOn(DataOperator as any, 'executeInDatabase'); + + await createConnection(true); + + await DataOperator.handleGroupsInChannel([ + { + auto_add: true, + channel_display_name: '', + channel_id: 'channelid', + channel_type: '', + create_at: 0, + delete_at: 0, + group_id: 'groupId', + team_display_name: '', + team_id: '', + team_type: '', + update_at: 0, + }, + ]); + + expect(spyOnExecuteInDatabase).toHaveBeenCalledTimes(1); + }); }); diff --git a/app/database/admin/data_operator/operators/index.ts b/app/database/admin/data_operator/operators/index.ts index 4943b4d1d..4c3ac2973 100644 --- a/app/database/admin/data_operator/operators/index.ts +++ b/app/database/admin/data_operator/operators/index.ts @@ -17,7 +17,10 @@ import { RawDraft, RawFile, RawGlobal, + RawGroup, RawGroupMembership, + RawGroupsInChannel, + RawGroupsInTeam, RawPost, RawPostMetadata, RawPostsInChannel, @@ -35,7 +38,10 @@ import Draft from '@typings/database/draft'; import {OperationType} from '@typings/database/enums'; import File from '@typings/database/file'; import Global from '@typings/database/global'; +import Group from '@typings/database/group'; import GroupMembership from '@typings/database/group_membership'; +import GroupsInChannel from '@typings/database/groups_in_channel'; +import GroupsInTeam from '@typings/database/groups_in_team'; import Post from '@typings/database/post'; import PostMetadata from '@typings/database/post_metadata'; import PostsInChannel from '@typings/database/posts_in_channel'; @@ -54,6 +60,9 @@ const { CUSTOM_EMOJI, DRAFT, FILE, + GROUP, + GROUPS_IN_TEAM, + GROUPS_IN_CHANNEL, GROUP_MEMBERSHIP, POST, POSTS_IN_CHANNEL, @@ -68,12 +77,14 @@ const { USER, } = MM_TABLES.SERVER; +// TODO : Include timezone_count and member_count when you have the information for the group section + /** * operateAppRecord: Prepares record of entity 'App' from the DEFAULT database for update or create actions. * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateAppRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawApp; @@ -101,7 +112,7 @@ export const operateAppRecord = async ({action, database, value}: DataFactoryArg * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateGlobalRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawGlobal; @@ -128,7 +139,7 @@ export const operateGlobalRecord = async ({action, database, value}: DataFactory * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateServersRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawServers; @@ -158,7 +169,7 @@ export const operateServersRecord = async ({action, database, value}: DataFactor * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateCustomEmojiRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawCustomEmoji; @@ -185,7 +196,7 @@ export const operateCustomEmojiRecord = async ({action, database, value}: DataFa * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateRoleRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawRole; @@ -213,7 +224,7 @@ export const operateRoleRecord = async ({action, database, value}: DataFactoryAr * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateSystemRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawSystem; @@ -241,7 +252,7 @@ export const operateSystemRecord = async ({action, database, value}: DataFactory * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateTermsOfServiceRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawTermsOfService; @@ -268,7 +279,7 @@ export const operateTermsOfServiceRecord = async ({action, database, value}: Dat * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operatePostRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawPost; @@ -308,7 +319,7 @@ export const operatePostRecord = async ({action, database, value}: DataFactoryAr * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operatePostInThreadRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawPostsInThread; @@ -335,7 +346,7 @@ export const operatePostInThreadRecord = async ({action, database, value}: DataF * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateReactionRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawReaction; @@ -344,7 +355,7 @@ export const operateReactionRecord = async ({action, database, value}: DataFacto // id of reaction comes from server response const generator = (reaction: Reaction) => { - reaction._raw.id = isCreateAction ? (raw?.id ?? reaction.id) : record?.id; + reaction._raw.id = isCreateAction ? reaction.id : record?.id; reaction.userId = raw.user_id; reaction.postId = raw.post_id; reaction.emojiName = raw.emoji_name; @@ -365,7 +376,7 @@ export const operateReactionRecord = async ({action, database, value}: DataFacto * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateFileRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawFile; @@ -400,7 +411,7 @@ export const operateFileRecord = async ({action, database, value}: DataFactoryAr * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operatePostMetadataRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawPostMetadata; @@ -428,7 +439,7 @@ export const operatePostMetadataRecord = async ({action, database, value}: DataF * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateDraftRecord = async ({action, database, value}: DataFactoryArgs) => { const emptyFileInfo: FileInfo[] = []; @@ -457,13 +468,15 @@ export const operateDraftRecord = async ({action, database, value}: DataFactoryA * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operatePostsInChannelRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawPostsInChannel; + const record = value.record as PostsInChannel; + const isCreateAction = action === OperationType.CREATE; const generator = (postsInChannel: PostsInChannel) => { - postsInChannel._raw.id = raw?.id ?? postsInChannel.id; + postsInChannel._raw.id = isCreateAction ? postsInChannel.id : record.id; postsInChannel.channelId = raw.channel_id; postsInChannel.earliest = raw.earliest; postsInChannel.latest = raw.latest; @@ -483,7 +496,7 @@ export const operatePostsInChannelRecord = async ({action, database, value}: Dat * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateUserRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawUser; @@ -526,7 +539,7 @@ export const operateUserRecord = async ({action, database, value}: DataFactoryAr * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operatePreferenceRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawPreference; @@ -535,7 +548,7 @@ export const operatePreferenceRecord = async ({action, database, value}: DataFac // id of preference comes from server response const generator = (preference: Preference) => { - preference._raw.id = isCreateAction ? (raw?.id ?? preference.id) : record?.id; + preference._raw.id = isCreateAction ? preference.id : record?.id; preference.category = raw.category; preference.name = raw.name; preference.userId = raw.user_id; @@ -556,7 +569,7 @@ export const operatePreferenceRecord = async ({action, database, value}: DataFac * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateTeamMembershipRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawTeamMembership; @@ -565,7 +578,7 @@ export const operateTeamMembershipRecord = async ({action, database, value}: Dat // id of preference comes from server response const generator = (teamMembership: TeamMembership) => { - teamMembership._raw.id = isCreateAction ? (raw?.id ?? teamMembership.id) : record?.id; + teamMembership._raw.id = isCreateAction ? teamMembership.id : record?.id; teamMembership.teamId = raw.team_id; teamMembership.userId = raw.user_id; }; @@ -584,7 +597,7 @@ export const operateTeamMembershipRecord = async ({action, database, value}: Dat * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateGroupMembershipRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawGroupMembership; @@ -593,7 +606,7 @@ export const operateGroupMembershipRecord = async ({action, database, value}: Da // id of preference comes from server response const generator = (groupMember: GroupMembership) => { - groupMember._raw.id = isCreateAction ? (raw?.id ?? groupMember.id) : record?.id; + groupMember._raw.id = isCreateAction ? groupMember.id : record?.id; groupMember.groupId = raw.group_id; groupMember.userId = raw.user_id; }; @@ -612,7 +625,7 @@ export const operateGroupMembershipRecord = async ({action, database, value}: Da * @param {DataFactoryArgs} operator * @param {Database} operator.database * @param {MatchExistingRecord} operator.value - * @returns {Promise} + * @returns {Promise} */ export const operateChannelMembershipRecord = async ({action, database, value}: DataFactoryArgs) => { const raw = value.raw as RawChannelMembership; @@ -621,7 +634,7 @@ export const operateChannelMembershipRecord = async ({action, database, value}: // id of preference comes from server response const generator = (channelMember: ChannelMembership) => { - channelMember._raw.id = isCreateAction ? (raw?.id ?? channelMember.id) : record?.id; + channelMember._raw.id = isCreateAction ? channelMember.id : record?.id; channelMember.channelId = raw.channel_id; channelMember.userId = raw.user_id; }; @@ -635,6 +648,88 @@ export const operateChannelMembershipRecord = async ({action, database, value}: }); }; +/** + * operateGroupRecord: Prepares record of entity 'GROUP' from the SERVER database for update or create actions. + * @param {DataFactory} operator + * @param {Database} operator.database + * @param {MatchExistingRecord} operator.value + * @returns {Promise} + */ +export const operateGroupRecord = async ({action, database, value}: DataFactoryArgs) => { + const raw = value.raw as RawGroup; + const record = value.record as Group; + const isCreateAction = action === OperationType.CREATE; + + // id of preference comes from server response + const generator = (group: Group) => { + group._raw.id = isCreateAction ? (raw?.id ?? group.id) : record?.id; + group.name = raw.name; + group.displayName = raw.display_name; + }; + + return operateBaseRecord({ + action, + database, + tableName: GROUP, + value, + generator, + }); +}; + +/** + * operateGroupsInTeamRecord: Prepares record of entity 'GROUPS_IN_TEAM' from the SERVER database for update or create actions. + * @param {DataFactory} operator + * @param {Database} operator.database + * @param {MatchExistingRecord} operator.value + * @returns {Promise} + */ +export const operateGroupsInTeamRecord = async ({action, database, value}: DataFactoryArgs) => { + const raw = value.raw as RawGroupsInTeam; + const record = value.record as GroupsInTeam; + const isCreateAction = action === OperationType.CREATE; + + const generator = (groupsInTeam: GroupsInTeam) => { + groupsInTeam._raw.id = isCreateAction ? groupsInTeam.id : record?.id; + groupsInTeam.teamId = raw.team_id; + groupsInTeam.groupId = raw.group_id; + }; + + return operateBaseRecord({ + action, + database, + tableName: GROUPS_IN_TEAM, + value, + generator, + }); +}; + +/** + * operateGroupsInChannelRecord: Prepares record of entity 'GROUPS_IN_TEAM' from the SERVER database for update or create actions. + * @param {DataFactory} operator + * @param {Database} operator.database + * @param {MatchExistingRecord} operator.value + * @returns {Promise} + */ +export const operateGroupsInChannelRecord = async ({action, database, value}: DataFactoryArgs) => { + const raw = value.raw as RawGroupsInChannel; + const record = value.record as GroupsInChannel; + const isCreateAction = action === OperationType.CREATE; + + const generator = (groupsInChannel: GroupsInChannel) => { + groupsInChannel._raw.id = isCreateAction ? groupsInChannel.id : record?.id; + groupsInChannel.channelId = raw.channel_id; + groupsInChannel.groupId = raw.group_id; + }; + + return operateBaseRecord({ + action, + database, + tableName: GROUPS_IN_CHANNEL, + value, + generator, + }); +}; + /** * operateBaseRecord: This is the last step for each operator and depending on the 'action', it will either prepare an * existing record for UPDATE or prepare a collection for CREATE @@ -643,10 +738,10 @@ export const operateChannelMembershipRecord = async ({action, database, value}: * @param {Database} operatorBase.database * @param {string} operatorBase.tableName * @param {MatchExistingRecord} operatorBase.value - * @param {((model: Model) => void)} operatorBase.generator - * @returns {Promise} + * @param {((DataFactoryArgs) => void)} operatorBase.generator + * @returns {Promise} */ -const operateBaseRecord = async ({action, database, tableName, value, generator}: DataFactoryArgs) => { +const operateBaseRecord = async ({action, database, tableName, value, generator}: DataFactoryArgs): Promise => { if (action === OperationType.UPDATE) { // Two possible scenarios: // 1. We are dealing with either duplicates here and if so, we'll update instead of create diff --git a/app/database/admin/data_operator/operators/test.ts b/app/database/admin/data_operator/operators/test.ts index 02953ef41..fcf6c79c1 100644 --- a/app/database/admin/data_operator/operators/test.ts +++ b/app/database/admin/data_operator/operators/test.ts @@ -12,6 +12,9 @@ import { operateFileRecord, operateGlobalRecord, operateGroupMembershipRecord, + operateGroupRecord, + operateGroupsInChannelRecord, + operateGroupsInTeamRecord, operatePostInThreadRecord, operatePostMetadataRecord, operatePostRecord, @@ -134,7 +137,11 @@ describe('*** DataOperator: Operators tests ***', () => { database: database!, value: { record: undefined, - raw: {id: 'role-1', name: 'role-name-1', permissions: []}, + raw: { + id: 'role-1', + name: 'role-name-1', + permissions: [], + }, }, }); @@ -575,4 +582,93 @@ describe('*** DataOperator: Operators tests ***', () => { expect(preparedRecords).toBeTruthy(); expect(preparedRecords!.collection.modelClass.name).toMatch('ChannelMembership'); }); + + it('=> operateGroupRecord: should return an array of type Group', async () => { + expect.assertions(3); + + const database = await createConnection(); + expect(database).toBeTruthy(); + + const preparedRecords = await operateGroupRecord({ + action: OperationType.CREATE, + database: database!, + value: { + record: undefined, + raw: { + id: 'id_groupdfjdlfkjdkfdsf', + name: 'mobile_team', + display_name: 'mobile team', + description: '', + source: '', + remote_id: '', + create_at: 0, + update_at: 0, + delete_at: 0, + has_syncables: true, + }, + }, + }); + + expect(preparedRecords).toBeTruthy(); + expect(preparedRecords!.collection.modelClass.name).toMatch('Group'); + }); + + it('=> operateGroupsInTeamRecord: should return an array of type GroupsInTeam', async () => { + expect.assertions(3); + + const database = await createConnection(); + expect(database).toBeTruthy(); + + const preparedRecords = await operateGroupsInTeamRecord({ + action: OperationType.CREATE, + database: database!, + value: { + record: undefined, + raw: { + team_id: 'team_89', + team_display_name: '', + team_type: '', + group_id: 'group_id89', + auto_add: true, + create_at: 0, + delete_at: 0, + update_at: 0, + }, + }, + }); + + expect(preparedRecords).toBeTruthy(); + expect(preparedRecords!.collection.modelClass.name).toMatch('GroupsInTeam'); + }); + + it('=> operateGroupsInChannelRecord: should return an array of type GroupsInChannel', async () => { + expect.assertions(3); + + const database = await createConnection(); + expect(database).toBeTruthy(); + + const preparedRecords = await operateGroupsInChannelRecord({ + action: OperationType.CREATE, + database: database!, + value: { + record: undefined, + raw: { + auto_add: true, + channel_display_name: '', + channel_id: 'channelid', + channel_type: '', + create_at: 0, + delete_at: 0, + group_id: 'groupId', + team_display_name: '', + team_id: '', + team_type: '', + update_at: 0, + }, + }, + }); + + expect(preparedRecords).toBeTruthy(); + expect(preparedRecords!.collection.modelClass.name).toMatch('GroupsInChannel'); + }); }); diff --git a/types/database/database.d.ts b/types/database/database.d.ts index 329cecaaa..89f80c649 100644 --- a/types/database/database.d.ts +++ b/types/database/database.d.ts @@ -6,7 +6,7 @@ import Model from '@nozbe/watermelondb/Model'; import {Clause} from '@nozbe/watermelondb/QueryDescription'; import {Class} from '@nozbe/watermelondb/utils/common'; -import {DatabaseType, IsolatedEntities, OperationType} from './enums'; +import {DatabaseType, IsolatedEntities} from './enums'; export type MigrationEvents = { onSuccess: () => void; @@ -58,16 +58,16 @@ export type RawCustomEmoji = { create_at?: number; update_at?: number; delete_at?: number; - creator_id?: string; + creator_id: string; }; export type RawRole = { id: string; name: string; - display_name: string; - description: string; + display_name?: string; + description?: string; permissions: string[]; - scheme_managed: boolean; + scheme_managed?: boolean; }; export type RawSystem = { @@ -88,7 +88,7 @@ export type RawDraft = { channel_id: string; files?: FileInfo[]; message?: string; - root_id?: string; + root_id: string; }; export type RawEmbed = { data: {}; type: string; url: string }; @@ -97,7 +97,6 @@ export type RawPostMetadata = { data: any; type: string; postId: string; - id?: string; }; interface PostMetadataTypes { @@ -124,7 +123,6 @@ export type RawFile = { }; export type RawReaction = { - id?: string; create_at: number; delete_at: number; emoji_name: string; @@ -134,7 +132,6 @@ export type RawReaction = { }; export type RawPostsInChannel = { - id?: string; channel_id: string; earliest: number; latest: number; @@ -241,17 +238,15 @@ export type RawUser = { }; export type RawPreference = { - id?: string; - user_id: string; category: string; name: string; + user_id: string; value: string; }; export type RawTeamMembership = { delete_at: number; explicit_roles: string; - id?: string; roles: string; scheme_admin: boolean; scheme_guest: boolean; @@ -261,13 +256,11 @@ export type RawTeamMembership = { }; export type RawGroupMembership = { - id?: string; user_id: string; group_id: string; }; export type RawChannelMembership = { - id?: string; channel_id: string; user_id: string; roles: string; @@ -325,12 +318,49 @@ export type RawChannel = { }; export type RawPostsInThread = { - id?: string; earliest: number; latest?: number; post_id: string; }; +export type RawGroup = { + create_at: number, + delete_at: number, + description: string, + display_name: string, + has_syncables: boolean + id: string, + name: string, + remote_id: string, + source: string, + update_at: number, +} + +export type RawGroupsInTeam = { + auto_add: boolean, + create_at: number, + delete_at: number, + group_id: string, + team_display_name: string, + team_id: string, + team_type: string, + update_at: number +} + +export type RawGroupsInChannel = { + auto_add: boolean, + channel_display_name: string, + channel_id: string, + channel_type: string, + create_at: number, + delete_at: number, + group_id: string, + team_display_name: string, + team_id: string, + team_type: string, + update_at: number +} + export type RawValue = | RawApp | RawChannelMembership @@ -338,7 +368,10 @@ export type RawValue = | RawDraft | RawFile | RawGlobal + | RawGroup | RawGroupMembership + | RawGroupsInChannel + | RawGroupsInTeam | RawPost | RawPostMetadata | RawPostsInChannel @@ -355,11 +388,11 @@ export type RawValue = export type MatchExistingRecord = { record?: Model; raw: RawValue }; export type DataFactoryArgs = { + action: string; database: Database; generator?: (model: Model) => void; tableName?: string; value: MatchExistingRecord; - action: OperationType; }; export type PrepareForDatabaseArgs = { @@ -390,8 +423,8 @@ export type DatabaseConnectionArgs = { export type ActiveServerDatabaseArgs = { displayName: string; serverUrl: string }; export type HandleReactionsArgs = { - reactions: RawReaction[]; prepareRowsOnly: boolean; + reactions: RawReaction[]; }; export type HandleFilesArgs = { @@ -407,8 +440,8 @@ export type HandlePostMetadataArgs = { export type HandlePostsArgs = { orders: string[]; - values: RawPost[]; previousPostId?: string; + values: RawPost[]; }; export type SanitizeReactionsArgs = { @@ -419,13 +452,13 @@ export type SanitizeReactionsArgs = { export type ChainPostsArgs = { orders: string[]; - rawPosts: RawPost[]; previousPostId: string; + rawPosts: RawPost[]; }; export type SanitizePostsArgs = { - posts: RawPost[]; orders: string[]; + posts: RawPost[]; }; export type IdenticalRecordArgs = { @@ -456,8 +489,8 @@ export type HandleEntityRecordsArgs = { }; export type DatabaseInstances = { - url: string; dbInstance: DatabaseInstance; + url: string; }; export type RangeOfValueArgs = {