[Gekidou] groups (#5593)

* Rename groups in channel/team to group channel/team

* Redefine groups schema

* Groups action and operator

* Add group at mentions

* fix uni test

* Update types/database/models/servers/group.d.ts

Co-authored-by: Avinash Lingaloo <avinashlng1080@gmail.com>

Co-authored-by: Avinash Lingaloo <avinashlng1080@gmail.com>
This commit is contained in:
Elias Nahum
2021-08-05 11:03:46 -04:00
committed by GitHub
parent 0ef1dd44ea
commit 65c3e05fd8
33 changed files with 386 additions and 209 deletions

View File

@@ -9,8 +9,8 @@ import type DraftModel from '@typings/database/models/servers/draft';
import type FileModel from '@typings/database/models/servers/file';
import type GroupModel from '@typings/database/models/servers/group';
import type GroupMembershipModel from '@typings/database/models/servers/group_membership';
import type GroupsInChannelModel from '@typings/database/models/servers/groups_in_channel';
import type GroupsInTeamModel from '@typings/database/models/servers/groups_in_team';
import type GroupsChannelModel from '@typings/database/models/servers/groups_channel';
import type GroupsTeamModel from '@typings/database/models/servers/groups_team';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
import type MyTeamModel from '@typings/database/models/servers/my_team';
@@ -86,11 +86,11 @@ export const isRecordGroupEqualToRaw = (record: GroupModel, raw: Group) => {
return raw.id === record.id;
};
export const isRecordGroupsInTeamEqualToRaw = (record: GroupsInTeamModel, raw: GroupTeam) => {
export const isRecordGroupsTeamEqualToRaw = (record: GroupsTeamModel, raw: GroupTeam) => {
return raw.team_id === record.teamId && raw.group_id === record.groupId;
};
export const isRecordGroupsInChannelEqualToRaw = (record: GroupsInChannelModel, raw: GroupChannel) => {
export const isRecordGroupsChannelEqualToRaw = (record: GroupsChannelModel, raw: GroupChannel) => {
return raw.channel_id === record.channelId && raw.group_id === record.groupId;
};

View File

@@ -5,14 +5,14 @@ import DatabaseManager from '@database/manager';
import {
isRecordGroupEqualToRaw,
isRecordGroupMembershipEqualToRaw,
isRecordGroupsInChannelEqualToRaw,
isRecordGroupsInTeamEqualToRaw,
isRecordGroupsChannelEqualToRaw,
isRecordGroupsTeamEqualToRaw,
} from '@database/operator/server_data_operator/comparators';
import {
transformGroupMembershipRecord,
transformGroupRecord,
transformGroupsInChannelRecord,
transformGroupsInTeamRecord,
transformGroupsChannelRecord,
transformGroupsTeamRecord,
} from '@database/operator/server_data_operator/transformers/group';
import ServerDataOperator from '..';
@@ -41,7 +41,7 @@ describe('*** Operator: Group Handlers tests ***', () => {
has_syncables: true,
type: '',
member_count: 1,
allow_reference: false,
allow_reference: true,
},
];
@@ -52,7 +52,7 @@ describe('*** Operator: Group Handlers tests ***', () => {
expect(spyOnHandleRecords).toHaveBeenCalledTimes(1);
expect(spyOnHandleRecords).toHaveBeenCalledWith({
fieldName: 'name',
fieldName: 'id',
createOrUpdateRawValues: groups,
tableName: 'Group',
prepareRecordsOnly: false,
@@ -61,11 +61,11 @@ describe('*** Operator: Group Handlers tests ***', () => {
});
});
it('=> HandleGroupsInTeam: should write to the GROUPS_IN_TEAM table', async () => {
it('=> HandleGroupsTeam: should write to the GROUPS_TEAM table', async () => {
expect.assertions(2);
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
const groupsInTeams = [
const groupsTeams = [
{
team_id: 'team_899',
team_display_name: '',
@@ -78,27 +78,27 @@ describe('*** Operator: Group Handlers tests ***', () => {
},
];
await operator.handleGroupsInTeam({
groupsInTeams,
await operator.handleGroupsTeam({
groupsTeams,
prepareRecordsOnly: false,
});
expect(spyOnHandleRecords).toHaveBeenCalledTimes(1);
expect(spyOnHandleRecords).toHaveBeenCalledWith({
fieldName: 'group_id',
createOrUpdateRawValues: groupsInTeams,
tableName: 'GroupsInTeam',
createOrUpdateRawValues: groupsTeams,
tableName: 'GroupsTeam',
prepareRecordsOnly: false,
findMatchingRecordBy: isRecordGroupsInTeamEqualToRaw,
transformer: transformGroupsInTeamRecord,
findMatchingRecordBy: isRecordGroupsTeamEqualToRaw,
transformer: transformGroupsTeamRecord,
});
});
it('=> HandleGroupsInChannel: should write to the GROUPS_IN_CHANNEL table', async () => {
it('=> HandleGroupsChannel: should write to the GROUPS_CHANNEL table', async () => {
expect.assertions(2);
const spyOnHandleRecords = jest.spyOn(operator, 'handleRecords');
const groupsInChannels = [
const groupsChannels = [
{
auto_add: true,
channel_display_name: '',
@@ -111,24 +111,22 @@ describe('*** Operator: Group Handlers tests ***', () => {
team_id: '',
team_type: '',
update_at: 0,
member_count: 0,
timezone_count: 0,
},
];
await operator.handleGroupsInChannel({
groupsInChannels,
await operator.handleGroupsChannel({
groupsChannels,
prepareRecordsOnly: false,
});
expect(spyOnHandleRecords).toHaveBeenCalledTimes(1);
expect(spyOnHandleRecords).toHaveBeenCalledWith({
fieldName: 'group_id',
createOrUpdateRawValues: groupsInChannels,
tableName: 'GroupsInChannel',
createOrUpdateRawValues: groupsChannels,
tableName: 'GroupsChannel',
prepareRecordsOnly: false,
findMatchingRecordBy: isRecordGroupsInChannelEqualToRaw,
transformer: transformGroupsInChannelRecord,
findMatchingRecordBy: isRecordGroupsChannelEqualToRaw,
transformer: transformGroupsChannelRecord,
});
});
@@ -150,7 +148,7 @@ describe('*** Operator: Group Handlers tests ***', () => {
expect(spyOnHandleRecords).toHaveBeenCalledTimes(1);
expect(spyOnHandleRecords).toHaveBeenCalledWith({
fieldName: 'user_id',
fieldName: 'group_id',
createOrUpdateRawValues: groupMemberships,
tableName: 'GroupMembership',
prepareRecordsOnly: false,

View File

@@ -6,35 +6,35 @@ import DataOperatorException from '@database/exceptions/data_operator_exception'
import {
isRecordGroupEqualToRaw,
isRecordGroupMembershipEqualToRaw,
isRecordGroupsInChannelEqualToRaw,
isRecordGroupsInTeamEqualToRaw,
isRecordGroupsChannelEqualToRaw,
isRecordGroupsTeamEqualToRaw,
} from '@database/operator/server_data_operator/comparators';
import {
transformGroupMembershipRecord,
transformGroupRecord,
transformGroupsInChannelRecord,
transformGroupsInTeamRecord,
transformGroupsChannelRecord,
transformGroupsTeamRecord,
} from '@database/operator/server_data_operator/transformers/group';
import {getUniqueRawsBy} from '@database/operator/utils/general';
import type {HandleGroupArgs, HandleGroupMembershipArgs, HandleGroupsInChannelArgs, HandleGroupsInTeamArgs} from '@typings/database/database';
import type {HandleGroupArgs, HandleGroupMembershipArgs, HandleGroupsChannelArgs, HandleGroupsTeamArgs} from '@typings/database/database';
import type GroupModel from '@typings/database/models/servers/group';
import type GroupMembershipModel from '@typings/database/models/servers/group_membership';
import type GroupsInChannelModel from '@typings/database/models/servers/groups_in_channel';
import type GroupsInTeamModel from '@typings/database/models/servers/groups_in_team';
import type GroupsChannelModel from '@typings/database/models/servers/groups_channel';
import type GroupsTeamModel from '@typings/database/models/servers/groups_team';
const {
GROUP,
GROUPS_IN_CHANNEL,
GROUPS_IN_TEAM,
GROUPS_CHANNEL,
GROUPS_TEAM,
GROUP_MEMBERSHIP,
} = MM_TABLES.SERVER;
export interface GroupHandlerMix {
handleGroupMembership: ({groupMemberships, prepareRecordsOnly}: HandleGroupMembershipArgs) => Promise<GroupMembershipModel[]>;
handleGroup: ({groups, prepareRecordsOnly}: HandleGroupArgs) => Promise<GroupModel[]>;
handleGroupsInTeam: ({groupsInTeams, prepareRecordsOnly}: HandleGroupsInTeamArgs) => Promise<GroupsInTeamModel[]>;
handleGroupsInChannel: ({groupsInChannels, prepareRecordsOnly}: HandleGroupsInChannelArgs) => Promise<GroupsInChannelModel[]>;
handleGroupsTeam: ({groupsTeams, prepareRecordsOnly}: HandleGroupsTeamArgs) => Promise<GroupsTeamModel[]>;
handleGroupsChannel: ({groupsChannels, prepareRecordsOnly}: HandleGroupsChannelArgs) => Promise<GroupsChannelModel[]>;
}
const GroupHandler = (superclass: any) => class extends superclass {
@@ -56,7 +56,7 @@ const GroupHandler = (superclass: any) => class extends superclass {
const createOrUpdateRawValues = getUniqueRawsBy({raws: groupMemberships, key: 'group_id'});
return this.handleRecords({
fieldName: 'user_id',
fieldName: 'group_id',
findMatchingRecordBy: isRecordGroupMembershipEqualToRaw,
transformer: transformGroupMembershipRecord,
prepareRecordsOnly,
@@ -80,10 +80,10 @@ const GroupHandler = (superclass: any) => class extends superclass {
);
}
const createOrUpdateRawValues = getUniqueRawsBy({raws: groups, key: 'name'});
const createOrUpdateRawValues = getUniqueRawsBy({raws: groups, key: 'id'});
return this.handleRecords({
fieldName: 'name',
fieldName: 'id',
findMatchingRecordBy: isRecordGroupEqualToRaw,
transformer: transformGroupRecord,
prepareRecordsOnly,
@@ -93,56 +93,58 @@ const GroupHandler = (superclass: any) => class extends superclass {
};
/**
* handleGroupsInTeam: Handler responsible for the Create/Update operations occurring on the GROUPS_IN_TEAM table from the 'Server' schema
* @param {HandleGroupsInTeamArgs} groupsInTeamsArgs
* @param {RawGroupsInTeam[]} groupsInTeamsArgs.groupsInTeams
* @param {boolean} groupsInTeamsArgs.prepareRecordsOnly
* handleGroupsTeam: Handler responsible for the Create/Update operations occurring on the GROUPS_TEAM table from the 'Server' schema
* @param {HandleGroupsTeamArgs} groupsTeamsArgs
* @param {GroupsTeam[]} groupsTeamsArgs.groupsTeams
* @param {boolean} groupsTeamsArgs.prepareRecordsOnly
* @throws DataOperatorException
* @returns {Promise<GroupsInTeamModel[]>}
* @returns {Promise<GroupsTeamModel[]>}
*/
handleGroupsInTeam = ({groupsInTeams, prepareRecordsOnly = true}: HandleGroupsInTeamArgs): Promise<GroupsInTeamModel[]> => {
if (!groupsInTeams.length) {
handleGroupsTeam = ({groupsTeams, prepareRecordsOnly = true}: HandleGroupsTeamArgs): Promise<GroupsTeamModel[]> => {
if (!groupsTeams.length) {
throw new DataOperatorException(
'An empty "groups" array has been passed to the handleGroupsInTeam method',
'An empty "groups" array has been passed to the handleGroupsTeam method',
);
}
const createOrUpdateRawValues = getUniqueRawsBy({raws: groupsInTeams, key: 'group_id'});
const createOrUpdateRawValues = groupsTeams.filter((gt, index, self) => (
index === self.findIndex((item) => item.team_id === gt.team_id && item.group_id === gt.group_id)));
return this.handleRecords({
fieldName: 'group_id',
findMatchingRecordBy: isRecordGroupsInTeamEqualToRaw,
transformer: transformGroupsInTeamRecord,
findMatchingRecordBy: isRecordGroupsTeamEqualToRaw,
transformer: transformGroupsTeamRecord,
prepareRecordsOnly,
createOrUpdateRawValues,
tableName: GROUPS_IN_TEAM,
tableName: GROUPS_TEAM,
});
};
/**
* handleGroupsInChannel: Handler responsible for the Create/Update operations occurring on the GROUPS_IN_CHANNEL table from the 'Server' schema
* @param {HandleGroupsInChannelArgs} groupsInChannelsArgs
* @param {RawGroupsInChannel[]} groupsInChannelsArgs.groupsInChannels
* @param {boolean} groupsInChannelsArgs.prepareRecordsOnly
* handleGroupsChannel: Handler responsible for the Create/Update operations occurring on the GROUPS_CHANNEL table from the 'Server' schema
* @param {HandleGroupsChannelArgs} groupsChannelsArgs
* @param {GroupsChannel[]} groupsChannelsArgs.groupsChannels
* @param {boolean} groupsChannelsArgs.prepareRecordsOnly
* @throws DataOperatorException
* @returns {Promise<GroupsInChannelModel[]>}
* @returns {Promise<GroupsChannelModel[]>}
*/
handleGroupsInChannel = ({groupsInChannels, prepareRecordsOnly = true}: HandleGroupsInChannelArgs): Promise<GroupsInChannelModel[]> => {
if (!groupsInChannels.length) {
handleGroupsChannel = ({groupsChannels, prepareRecordsOnly = true}: HandleGroupsChannelArgs): Promise<GroupsChannelModel[]> => {
if (!groupsChannels.length) {
throw new DataOperatorException(
'An empty "groups" array has been passed to the handleGroupsInTeam method',
'An empty "groups" array has been passed to the handleGroupsTeam method',
);
}
const createOrUpdateRawValues = getUniqueRawsBy({raws: groupsInChannels, key: 'channel_id'});
const createOrUpdateRawValues = groupsChannels.filter((gc, index, self) => (
index === self.findIndex((item) => item.channel_id === gc.channel_id && item.group_id === gc.group_id)));
return this.handleRecords({
fieldName: 'group_id',
findMatchingRecordBy: isRecordGroupsInChannelEqualToRaw,
transformer: transformGroupsInChannelRecord,
findMatchingRecordBy: isRecordGroupsChannelEqualToRaw,
transformer: transformGroupsChannelRecord,
prepareRecordsOnly,
createOrUpdateRawValues,
tableName: GROUPS_IN_CHANNEL,
tableName: GROUPS_CHANNEL,
});
};
};

View File

@@ -4,8 +4,8 @@
import {
transformGroupMembershipRecord,
transformGroupRecord,
transformGroupsInChannelRecord,
transformGroupsInTeamRecord,
transformGroupsChannelRecord,
transformGroupsTeamRecord,
} from '@database/operator/server_data_operator/transformers/group';
import {createTestConnection} from '@database/operator/utils/create_test_connection';
import {OperationType} from '@typings/database/enums';
@@ -43,13 +43,13 @@ describe('*** GROUP Prepare Records Test ***', () => {
expect(preparedRecords!.collection.modelClass.name).toBe('GroupModel');
});
it('=> transformGroupsInTeamRecord: should return an array of type GroupsInTeam', async () => {
it('=> transformGroupsTeamRecord: should return an array of type GroupsTeam', async () => {
expect.assertions(3);
const database = await createTestConnection({databaseName: 'group_prepare_records', setActive: true});
expect(database).toBeTruthy();
const preparedRecords = await transformGroupsInTeamRecord({
const preparedRecords = await transformGroupsTeamRecord({
action: OperationType.CREATE,
database: database!,
value: {
@@ -68,16 +68,16 @@ describe('*** GROUP Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
expect(preparedRecords!.collection.modelClass.name).toBe('GroupsInTeamModel');
expect(preparedRecords!.collection.modelClass.name).toBe('GroupsTeamModel');
});
it('=> transformGroupsInChannelRecord: should return an array of type GroupsInChannel', async () => {
it('=> transformGroupsChannelRecord: should return an array of type GroupsChannel', async () => {
expect.assertions(3);
const database = await createTestConnection({databaseName: 'group_prepare_records', setActive: true});
expect(database).toBeTruthy();
const preparedRecords = await transformGroupsInChannelRecord({
const preparedRecords = await transformGroupsChannelRecord({
action: OperationType.CREATE,
database: database!,
value: {
@@ -99,7 +99,7 @@ describe('*** GROUP Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
expect(preparedRecords!.collection.modelClass.name).toBe('GroupsInChannelModel');
expect(preparedRecords!.collection.modelClass.name).toBe('GroupsChannelModel');
});
it('=> transformGroupMembershipRecord: should return an array of type GroupMembership', async () => {

View File

@@ -8,13 +8,13 @@ import type {TransformerArgs} from '@typings/database/database';
import {OperationType} from '@typings/database/enums';
import type GroupModel from '@typings/database/models/servers/group';
import type GroupMembershipModel from '@typings/database/models/servers/group_membership';
import type GroupsInChannelModel from '@typings/database/models/servers/groups_in_channel';
import type GroupsInTeamModel from '@typings/database/models/servers/groups_in_team';
import type GroupsChannelModel from '@typings/database/models/servers/groups_channel';
import type GroupsTeamModel from '@typings/database/models/servers/groups_team';
const {
GROUP,
GROUPS_IN_CHANNEL,
GROUPS_IN_TEAM,
GROUPS_CHANNEL,
GROUPS_TEAM,
GROUP_MEMBERSHIP,
} = MM_TABLES.SERVER;
@@ -61,6 +61,8 @@ export const transformGroupRecord = ({action, database, value}: TransformerArgs)
// If isCreateAction is true, we will use the id (API response) from the RAW, else we shall use the existing record id from the database
const fieldsMapper = (group: GroupModel) => {
group._raw.id = isCreateAction ? (raw?.id ?? group.id) : record.id;
group.allowReference = raw.allow_reference;
group.deleteAt = raw.delete_at;
group.name = raw.name;
group.displayName = raw.display_name;
};
@@ -75,57 +77,55 @@ export const transformGroupRecord = ({action, database, value}: TransformerArgs)
};
/**
* transformGroupsInTeamRecord: Prepares a record of the SERVER database 'GroupsInTeam' table for update or create actions.
* transformGroupsTeamRecord: Prepares a record of the SERVER database 'GroupsTeam' table for update or create actions.
* @param {DataFactory} operator
* @param {Database} operator.database
* @param {RecordPair} operator.value
* @returns {Promise<GroupsInTeamModel>}
* @returns {Promise<GroupsTeamModel>}
*/
export const transformGroupsInTeamRecord = ({action, database, value}: TransformerArgs): Promise<GroupsInTeamModel> => {
export const transformGroupsTeamRecord = ({action, database, value}: TransformerArgs): Promise<GroupsTeamModel> => {
const raw = value.raw as GroupTeam;
const record = value.record as GroupsInTeamModel;
const record = value.record as GroupsTeamModel;
const isCreateAction = action === OperationType.CREATE;
const fieldsMapper = (groupsInTeam: GroupsInTeamModel) => {
groupsInTeam._raw.id = isCreateAction ? groupsInTeam.id : record.id;
groupsInTeam.teamId = raw.team_id;
groupsInTeam.groupId = raw.group_id;
const fieldsMapper = (groupsTeam: GroupsTeamModel) => {
groupsTeam._raw.id = isCreateAction ? groupsTeam.id : record.id;
groupsTeam.teamId = raw.team_id;
groupsTeam.groupId = raw.group_id;
};
return prepareBaseRecord({
action,
database,
tableName: GROUPS_IN_TEAM,
tableName: GROUPS_TEAM,
value,
fieldsMapper,
}) as Promise<GroupsInTeamModel>;
}) as Promise<GroupsTeamModel>;
};
/**
* transformGroupsInChannelRecord: Prepares a record of the SERVER database 'GroupsInChannel' table for update or create actions.
* transformGroupsChannelRecord: Prepares a record of the SERVER database 'GroupsChannel' table for update or create actions.
* @param {DataFactory} operator
* @param {Database} operator.database
* @param {RecordPair} operator.value
* @returns {Promise<GroupsInChannelModel>}
* @returns {Promise<GroupsChannelModel>}
*/
export const transformGroupsInChannelRecord = ({action, database, value}: TransformerArgs): Promise<GroupsInChannelModel> => {
const raw = value.raw as GroupChannel;
const record = value.record as GroupsInChannelModel;
export const transformGroupsChannelRecord = ({action, database, value}: TransformerArgs): Promise<GroupsChannelModel> => {
const raw = value.raw as GroupChannelRelation;
const record = value.record as GroupsChannelModel;
const isCreateAction = action === OperationType.CREATE;
const fieldsMapper = (groupsInChannel: GroupsInChannelModel) => {
groupsInChannel._raw.id = isCreateAction ? groupsInChannel.id : record.id;
groupsInChannel.channelId = raw.channel_id;
groupsInChannel.groupId = raw.group_id;
groupsInChannel.memberCount = raw.member_count;
groupsInChannel.timezoneCount = raw.timezone_count;
const fieldsMapper = (groupsChannel: GroupsChannelModel) => {
groupsChannel._raw.id = isCreateAction ? groupsChannel.id : record.id;
groupsChannel.channelId = raw.channel_id;
groupsChannel.groupId = raw.group_id;
};
return prepareBaseRecord({
action,
database,
tableName: GROUPS_IN_CHANNEL,
tableName: GROUPS_CHANNEL,
value,
fieldsMapper,
}) as Promise<GroupsInChannelModel>;
}) as Promise<GroupsChannelModel>;
};