diff --git a/lib/shared/message-utils.test.js b/lib/shared/message-utils.test.js index 1f8d05cf2..7971838d9 100644 --- a/lib/shared/message-utils.test.js +++ b/lib/shared/message-utils.test.js @@ -1,732 +1,750 @@ // @flow import { isInvalidSidebarSource, isInvalidPinSource } from './message-utils.js'; import { messageSpecs } from '../shared/messages/message-specs.js'; import { messageTypes } from '../types/message-types-enum.js'; import type { RawSidebarSourceMessageInfo } from '../types/message-types.js'; import type { RawAddMembersMessageInfo } from '../types/messages/add-members.js'; import type { RawChangeRoleMessageInfo } from '../types/messages/change-role.js'; import type { RawChangeSettingsMessageInfo } from '../types/messages/change-settings.js'; import type { RawCreateEntryMessageInfo } from '../types/messages/create-entry.js'; import type { RawCreateSidebarMessageInfo } from '../types/messages/create-sidebar.js'; import type { RawCreateSubthreadMessageInfo } from '../types/messages/create-subthread.js'; import type { RawCreateThreadMessageInfo } from '../types/messages/create-thread.js'; import type { RawDeleteEntryMessageInfo } from '../types/messages/delete-entry.js'; import type { RawEditEntryMessageInfo } from '../types/messages/edit-entry.js'; import type { RawEditMessageInfo } from '../types/messages/edit.js'; import type { RawImagesMessageInfo } from '../types/messages/images.js'; import type { RawJoinThreadMessageInfo } from '../types/messages/join-thread.js'; import type { RawLeaveThreadMessageInfo } from '../types/messages/leave-thread.js'; import type { RawMediaMessageInfo } from '../types/messages/media.js'; import type { RawReactionMessageInfo } from '../types/messages/reaction.js'; import type { RawRemoveMembersMessageInfo } from '../types/messages/remove-members.js'; import type { RawRestoreEntryMessageInfo } from '../types/messages/restore-entry.js'; import type { RawTextMessageInfo } from '../types/messages/text.js'; import type { RawTogglePinMessageInfo } from '../types/messages/toggle-pin.js'; import type { RawUpdateRelationshipMessageInfo } from '../types/messages/update-relationship.js'; import { threadTypes } from '../types/thread-types-enum.js'; const textMessageInfo: RawTextMessageInfo = { type: messageTypes.TEXT, localID: 'local1', threadID: '10001', creatorID: '123', time: 10000, text: 'This is a text message', id: '1', }; const createThreadMessageInfo: RawCreateThreadMessageInfo = { type: 1, threadID: '10001', creatorID: '123', time: 10000, initialThreadState: { type: threadTypes.COMMUNITY_ROOT, name: 'Random Thread', parentThreadID: '10000', color: '#FFFFFF', memberIDs: ['1', '2', '3'], }, id: '1', }; const addMembersMessageInfo: RawAddMembersMessageInfo = { type: messageTypes.ADD_MEMBERS, threadID: '10001', creatorID: '123', time: 10000, addedUserIDs: ['4', '5'], id: '1', }; const createSubthreadMessageInfo: RawCreateSubthreadMessageInfo = { type: messageTypes.CREATE_SUB_THREAD, threadID: '10001', creatorID: '123', time: 10000, childThreadID: '10002', id: '1', }; const changeSettingsMessageInfo: RawChangeSettingsMessageInfo = { type: messageTypes.CHANGE_SETTINGS, threadID: '10000', creatorID: '123', time: 10000, field: 'color', value: '#FFFFFF', id: '1', }; const removeMembersMessageInfo: RawRemoveMembersMessageInfo = { type: messageTypes.REMOVE_MEMBERS, threadID: '10000', creatorID: '123', time: 10000, removedUserIDs: ['1', '2', '3'], id: '1', }; const changeRoleMessageinfo: RawChangeRoleMessageInfo = { type: messageTypes.CHANGE_ROLE, threadID: '10000', creatorID: '123', time: 10000, userIDs: ['1', '2', '3'], newRole: '101', roleName: 'Moderators', id: '1', }; const leaveThreadMessageInfo: RawLeaveThreadMessageInfo = { type: messageTypes.LEAVE_THREAD, threadID: '10000', creatorID: '123', time: 10000, id: '1', }; const joinThreadMessageInfo: RawJoinThreadMessageInfo = { type: messageTypes.JOIN_THREAD, threadID: '10000', creatorID: '123', time: 10000, id: '1', }; const createEntryMessageInfo: RawCreateEntryMessageInfo = { type: messageTypes.CREATE_ENTRY, threadID: '10000', creatorID: '123', time: 10000, entryID: '001', date: '2018-01-01', text: 'This is a calendar entry', id: '1', }; const editEntryMessageInfo: RawEditEntryMessageInfo = { type: messageTypes.EDIT_ENTRY, threadID: '10000', creatorID: '123', time: 10000, entryID: '001', date: '2018-01-01', text: 'This is an edited calendar entry', id: '1', }; const deleteEntryMessageInfo: RawDeleteEntryMessageInfo = { type: messageTypes.DELETE_ENTRY, threadID: '10000', creatorID: '123', time: 10000, entryID: '001', date: '2018-01-01', text: 'This is a deleted calendar entry', id: '1', }; const restoreEntryMessageInfo: RawRestoreEntryMessageInfo = { type: messageTypes.RESTORE_ENTRY, threadID: '10000', creatorID: '123', time: 10000, entryID: '001', date: '2018-01-01', text: 'This is a restored calendar entry', id: '1', }; const updateRelationshipMessageInfo: RawUpdateRelationshipMessageInfo = { type: messageTypes.UPDATE_RELATIONSHIP, threadID: '10000', creatorID: '123', targetID: '456', time: 10000, operation: 'request_sent', id: '1', }; const imageMessageInfo: RawImagesMessageInfo = { type: messageTypes.IMAGES, localID: 'local1', threadID: '10001', creatorID: '123', time: 10000, media: [ { id: '1', uri: 'https://example.com/image1.jpg', type: 'photo', dimensions: { height: 100, width: 100, }, thumbHash: '1234567890', }, ], id: '1', }; const mediaMessageInfo: RawMediaMessageInfo = { type: messageTypes.MULTIMEDIA, localID: 'local1', threadID: '10001', creatorID: '123', time: 10000, media: [ { id: '1', uri: 'https://example.com/image1.jpg', type: 'photo', dimensions: { height: 100, width: 100, }, thumbHash: '1234567890', }, ], id: '1', }; const sidebarSourceMessageInfo: RawSidebarSourceMessageInfo = { type: messageTypes.SIDEBAR_SOURCE, threadID: '10000', creatorID: '123', time: 10000, sourceMessage: { type: messageTypes.TEXT, localID: 'local1', threadID: '10001', creatorID: '123', time: 10000, text: 'This is a text message', id: '1', }, id: '1', }; const createSidebarMessageInfo: RawCreateSidebarMessageInfo = { type: messageTypes.CREATE_SIDEBAR, threadID: '10000', creatorID: '123', time: 10000, sourceMessageAuthorID: '123', initialThreadState: { name: 'Random Thread', parentThreadID: '10000', color: '#FFFFFF', memberIDs: ['1', '2', '3'], }, id: '1', }; const reactionMessageInfo: RawReactionMessageInfo = { type: messageTypes.REACTION, localID: 'local1', threadID: '10001', creatorID: '123', time: 10000, targetMessageID: '1', reaction: 'like', action: 'add_reaction', id: '1', }; const editMessageInfo: RawEditMessageInfo = { type: messageTypes.EDIT_MESSAGE, threadID: '10000', creatorID: '123', time: 10000, targetMessageID: '1', text: 'This is an edited message', id: '1', }; const togglePinMessageInfo: RawTogglePinMessageInfo = { type: messageTypes.TOGGLE_PIN, threadID: '10000', targetMessageID: '1', action: 'pin', pinnedContent: 'a message', creatorID: '123', time: 10000, id: '1', }; describe('isInvalidSidebarSource & canBeSidebarSource', () => { it('should return false for RawTextMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.TEXT]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource(textMessageInfo); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawCreateThreadMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CREATE_THREAD]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( createThreadMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawAddMembersMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.ADD_MEMBERS]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( addMembersMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawCreateSubthreadMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CREATE_SUB_THREAD]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( createSubthreadMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawChangeSettingsMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CHANGE_SETTINGS]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( changeSettingsMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawRemoveMembersMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.REMOVE_MEMBERS]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( removeMembersMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawChangeRoleMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CHANGE_ROLE]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( changeRoleMessageinfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawLeaveThreadMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.LEAVE_THREAD]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( leaveThreadMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawJoinThreadMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.JOIN_THREAD]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( joinThreadMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawCreateEntryMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CREATE_ENTRY]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( createEntryMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawEditEntryMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.EDIT_ENTRY]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource(editEntryMessageInfo); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawDeleteEntryMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.DELETE_ENTRY]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( deleteEntryMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawRestoreEntryMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.RESTORE_ENTRY]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( restoreEntryMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawUpdateRelationshipMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.UPDATE_RELATIONSHIP]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( updateRelationshipMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawImagesMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.IMAGES]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource(imageMessageInfo); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return false for RawMediaMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.MULTIMEDIA]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource(mediaMessageInfo); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return true for RawSidebarSourceMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.SIDEBAR_SOURCE]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( sidebarSourceMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(true); expect(canBeSidebarSource).toBe(false); }); it('should return false for RawCreateSidebarMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CREATE_SIDEBAR]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource( createSidebarMessageInfo, ); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(false); expect(canBeSidebarSource).toBe(true); }); it('should return true for RawReactionMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.REACTION]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource(reactionMessageInfo); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(true); expect(canBeSidebarSource).toBe(false); }); it('should return true for RawEditMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.EDIT_MESSAGE]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource(editMessageInfo); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(true); expect(canBeSidebarSource).toBe(false); }); it('should return true for RawTogglePinMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.TOGGLE_PIN]; const shouldBeInvalidSidebarSource = isInvalidSidebarSource(togglePinMessageInfo); const canBeSidebarSource = messageSpec.canBeSidebarSource; expect(shouldBeInvalidSidebarSource).toBe(true); expect(canBeSidebarSource).toBe(false); }); }); describe('isInvalidPinSource & canBePinned', () => { it('should return true for RawTextMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.TEXT]; const shouldBeInvalidPinSource = isInvalidPinSource(textMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(false); expect(canBePinned).toBe(true); }); it('should return false for RawCreateThreadMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CREATE_THREAD]; const shouldBeInvalidPinSource = isInvalidPinSource( createThreadMessageInfo, ); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawAddMembersMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.ADD_MEMBERS]; const shouldBeInvalidPinSource = isInvalidPinSource(addMembersMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawCreateSubthreadMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CREATE_SUB_THREAD]; const shouldBeInvalidPinSource = isInvalidPinSource( createSubthreadMessageInfo, ); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawChangeSettingsMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CHANGE_SETTINGS]; const shouldBeInvalidPinSource = isInvalidPinSource( changeSettingsMessageInfo, ); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawRemoveMembersMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.REMOVE_MEMBERS]; const shouldBeInvalidPinSource = isInvalidPinSource( removeMembersMessageInfo, ); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawChangeRoleMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CHANGE_ROLE]; const shouldBeInvalidPinSource = isInvalidPinSource(changeRoleMessageinfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawLeaveThreadMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.LEAVE_THREAD]; const shouldBeInvalidPinSource = isInvalidPinSource(leaveThreadMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawJoinThreadMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.JOIN_THREAD]; const shouldBeInvalidPinSource = isInvalidPinSource(joinThreadMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawCreateEntryMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CREATE_ENTRY]; const shouldBeInvalidPinSource = isInvalidPinSource(createEntryMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawEditEntryMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.EDIT_ENTRY]; const shouldBeInvalidPinSource = isInvalidPinSource(editEntryMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawDeleteEntryMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.DELETE_ENTRY]; const shouldBeInvalidPinSource = isInvalidPinSource(deleteEntryMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawRestoreEntryMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.RESTORE_ENTRY]; const shouldBeInvalidPinSource = isInvalidPinSource( restoreEntryMessageInfo, ); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawUpdateRelationshipMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.UPDATE_RELATIONSHIP]; const shouldBeInvalidPinSource = isInvalidPinSource( updateRelationshipMessageInfo, ); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return true for RawImagesMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.IMAGES]; const shouldBeInvalidPinSource = isInvalidPinSource(imageMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(false); expect(canBePinned).toBe(true); }); it('should return true for RawMediaMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.MULTIMEDIA]; const shouldBeInvalidPinSource = isInvalidPinSource(mediaMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(false); expect(canBePinned).toBe(true); }); it('should return false for RawSidebarSourceMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.SIDEBAR_SOURCE]; const shouldBeInvalidPinSource = isInvalidPinSource( sidebarSourceMessageInfo, ); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawCreateSidebarMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.CREATE_SIDEBAR]; const shouldBeInvalidPinSource = isInvalidPinSource( createSidebarMessageInfo, ); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawReactionMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.REACTION]; const shouldBeInvalidPinSource = isInvalidPinSource(reactionMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawEditMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.EDIT_MESSAGE]; const shouldBeInvalidPinSource = isInvalidPinSource(editMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); it('should return false for RawTogglePinMessageInfo', () => { const messageSpec = messageSpecs[messageTypes.TOGGLE_PIN]; const shouldBeInvalidPinSource = isInvalidPinSource(togglePinMessageInfo); const canBePinned = messageSpec.canBePinned; expect(shouldBeInvalidPinSource).toBe(true); expect(canBePinned).toBe(false); }); + + describe('canBeRenderedIndependently', () => { + it('should return false for RawReactionMessageInfo', () => { + const messageSpec = messageSpecs[messageTypes.REACTION]; + + const canBeRenderedIndependently = messageSpec.canBeRenderedIndependently; + + expect(canBeRenderedIndependently).toBe(false); + }); + + it('should return false for RawEditMessageInfo', () => { + const messageSpec = messageSpecs[messageTypes.EDIT_MESSAGE]; + + const canBeRenderedIndependently = messageSpec.canBeRenderedIndependently; + + expect(canBeRenderedIndependently).toBe(false); + }); + }); }); diff --git a/lib/shared/messages/edit-message-spec.js b/lib/shared/messages/edit-message-spec.js index 4e2680b10..a8dfbef5b 100644 --- a/lib/shared/messages/edit-message-spec.js +++ b/lib/shared/messages/edit-message-spec.js @@ -1,148 +1,150 @@ // @flow import invariant from 'invariant'; import { type MessageSpec, type MessageTitleParam } from './message-spec.js'; import type { PlatformDetails } from '../../types/device-types.js'; import { assertMessageType, messageTypes, } from '../../types/message-types-enum.js'; import type { ClientDBMessageInfo } from '../../types/message-types.js'; import { type EditMessageData, type RawEditMessageInfo, type EditMessageInfo, rawEditMessageInfoValidator, } from '../../types/messages/edit.js'; import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported.js'; import type { RelativeUserInfo } from '../../types/user-types.js'; import { ET } from '../../utils/entity-text.js'; import { hasMinCodeVersion } from '../version-utils.js'; export const editMessageSpec: MessageSpec< EditMessageData, RawEditMessageInfo, EditMessageInfo, > = Object.freeze({ messageContentForServerDB( data: EditMessageData | RawEditMessageInfo, ): string { return JSON.stringify({ text: data.text, }); }, messageContentForClientDB(data: RawEditMessageInfo): string { return JSON.stringify({ targetMessageID: data.targetMessageID, text: data.text, }); }, messageTitle({ messageInfo }: MessageTitleParam) { const creator = ET.user({ userInfo: messageInfo.creator }); return ET`${creator} edited a message`; }, rawMessageInfoFromServerDBRow(row: Object): RawEditMessageInfo { invariant( row.targetMessageID !== null && row.targetMessageID !== undefined, 'targetMessageID should be set', ); const content = JSON.parse(row.content); return { type: messageTypes.EDIT_MESSAGE, id: row.id.toString(), threadID: row.threadID.toString(), time: row.time, creatorID: row.creatorID.toString(), targetMessageID: row.targetMessageID.toString(), text: content.text, }; }, rawMessageInfoFromClientDB( clientDBMessageInfo: ClientDBMessageInfo, ): RawEditMessageInfo { const messageType = assertMessageType(parseInt(clientDBMessageInfo.type)); invariant( messageType === messageTypes.EDIT_MESSAGE, 'message must be of type EDIT_MESSAGE', ); invariant( clientDBMessageInfo.content !== undefined && clientDBMessageInfo.content !== null, 'content must be defined for EditMessage', ); const content = JSON.parse(clientDBMessageInfo.content); const rawEditMessageInfo: RawEditMessageInfo = { type: messageTypes.EDIT_MESSAGE, id: clientDBMessageInfo.id, threadID: clientDBMessageInfo.thread, time: parseInt(clientDBMessageInfo.time), creatorID: clientDBMessageInfo.user, targetMessageID: content.targetMessageID, text: content.text, }; return rawEditMessageInfo; }, createMessageInfo( rawMessageInfo: RawEditMessageInfo, creator: RelativeUserInfo, ): EditMessageInfo { return { type: messageTypes.EDIT_MESSAGE, id: rawMessageInfo.id, threadID: rawMessageInfo.threadID, creator, time: rawMessageInfo.time, targetMessageID: rawMessageInfo.targetMessageID, text: rawMessageInfo.text, }; }, rawMessageInfoFromMessageData( messageData: EditMessageData, id: ?string, ): RawEditMessageInfo { invariant(id, 'RawEditMessageInfo needs id'); return { ...messageData, id }; }, shimUnsupportedMessageInfo( rawMessageInfo: RawEditMessageInfo, platformDetails: ?PlatformDetails, ): RawEditMessageInfo | RawUnsupportedMessageInfo { if (hasMinCodeVersion(platformDetails, { native: 215 })) { return rawMessageInfo; } const { id } = rawMessageInfo; invariant(id !== null && id !== undefined, 'id should be set on server'); return { type: messageTypes.UNSUPPORTED, id, threadID: rawMessageInfo.threadID, creatorID: rawMessageInfo.creatorID, time: rawMessageInfo.time, robotext: 'edited a message', unsupportedMessageInfo: rawMessageInfo, }; }, unshimMessageInfo(unwrapped: RawEditMessageInfo): RawEditMessageInfo { return unwrapped; }, canBeSidebarSource: false, canBePinned: false, + canBeRenderedIndependently: false, + validator: rawEditMessageInfoValidator, }); diff --git a/lib/shared/messages/message-spec.js b/lib/shared/messages/message-spec.js index ea7844ea3..3c509ddfc 100644 --- a/lib/shared/messages/message-spec.js +++ b/lib/shared/messages/message-spec.js @@ -1,120 +1,121 @@ // @flow import type { TType } from 'tcomb'; import type { PlatformDetails } from '../../types/device-types.js'; import type { Media } from '../../types/media-types.js'; import type { MessageInfo, ClientDBMessageInfo, RawComposableMessageInfo, RawMessageInfo, RawRobotextMessageInfo, } from '../../types/message-types.js'; import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported.js'; import type { NotifTexts } from '../../types/notif-types.js'; import type { ThreadInfo } from '../../types/thread-types.js'; import type { RelativeUserInfo, UserInfo } from '../../types/user-types.js'; import type { EntityText } from '../../utils/entity-text.js'; import { type ParserRules } from '../markdown.js'; export type MessageTitleParam = { +messageInfo: Info, +threadInfo: ThreadInfo, +markdownRules: ParserRules, }; export type RawMessageInfoFromServerDBRowParams = { +localID: ?string, +media?: $ReadOnlyArray, +derivedMessages: $ReadOnlyMap< string, RawComposableMessageInfo | RawRobotextMessageInfo, >, }; export type CreateMessageInfoParams = { +threadInfos: { +[id: string]: ThreadInfo }, +createMessageInfoFromRaw: (rawInfo: RawMessageInfo) => ?MessageInfo, +createRelativeUserInfos: ( userIDs: $ReadOnlyArray, ) => RelativeUserInfo[], }; export type RobotextParams = { +threadInfo: ?ThreadInfo, +parentThreadInfo: ?ThreadInfo, }; export type NotificationTextsParams = { +notifTargetUserInfo: UserInfo, +parentThreadInfo: ?ThreadInfo, }; export type GeneratesNotifsParams = { +notifTargetUserID: string, +userNotMemberOfSubthreads: Set, +fetchMessageInfoByID: (messageID: string) => Promise, }; export const pushTypes = Object.freeze({ NOTIF: 'notif', RESCIND: 'rescind', }); export type PushType = $Values; export type CreationSideEffectsFunc = ( messageInfo: RawInfo, threadInfo: ThreadInfo, parentThreadInfo: ?ThreadInfo, ) => Promise; export type MessageSpec = { +messageContentForServerDB?: (data: Data | RawInfo) => string, +messageContentForClientDB?: (data: RawInfo) => string, +messageTitle?: (param: MessageTitleParam) => EntityText, +rawMessageInfoFromServerDBRow?: ( row: Object, params: RawMessageInfoFromServerDBRowParams, ) => ?RawInfo, +rawMessageInfoFromClientDB: ( clientDBMessageInfo: ClientDBMessageInfo, ) => RawInfo, +createMessageInfo: ( rawMessageInfo: RawInfo, creator: RelativeUserInfo, params: CreateMessageInfoParams, ) => ?Info, +rawMessageInfoFromMessageData?: (messageData: Data, id: ?string) => RawInfo, +robotext?: (messageInfo: Info, params: RobotextParams) => EntityText, +shimUnsupportedMessageInfo?: ( rawMessageInfo: RawInfo, platformDetails: ?PlatformDetails, ) => RawInfo | RawUnsupportedMessageInfo, +unshimMessageInfo?: ( unwrapped: RawInfo, messageInfo: RawMessageInfo, ) => ?RawMessageInfo, +notificationTexts?: ( messageInfos: $ReadOnlyArray, threadInfo: ThreadInfo, params: NotificationTextsParams, ) => Promise, +notificationCollapseKey?: ( rawMessageInfo: RawInfo, messageData: Data, ) => ?string, +generatesNotifs?: ( rawMessageInfo: RawInfo, messageData: Data, params: GeneratesNotifsParams, ) => Promise, +userIDs?: (rawMessageInfo: RawInfo) => $ReadOnlyArray, +startsThread?: boolean, +threadIDs?: (rawMessageInfo: RawInfo) => $ReadOnlyArray, +includedInRepliesCount?: boolean, +canBeSidebarSource: boolean, +canBePinned: boolean, + +canBeRenderedIndependently?: boolean, +useCreationSideEffectsFunc?: () => CreationSideEffectsFunc, +validator: TType, }; diff --git a/lib/shared/messages/reaction-message-spec.js b/lib/shared/messages/reaction-message-spec.js index 0db837eb5..537b3e0fe 100644 --- a/lib/shared/messages/reaction-message-spec.js +++ b/lib/shared/messages/reaction-message-spec.js @@ -1,226 +1,228 @@ // @flow import invariant from 'invariant'; import { pushTypes, type MessageSpec, type MessageTitleParam, type GeneratesNotifsParams, } from './message-spec.js'; import { assertSingleMessageInfo, joinResult } from './utils.js'; import type { PlatformDetails } from '../../types/device-types.js'; import { assertMessageType, messageTypes, } from '../../types/message-types-enum.js'; import type { MessageInfo, ClientDBMessageInfo, } from '../../types/message-types.js'; import { type ReactionMessageData, type RawReactionMessageInfo, type ReactionMessageInfo, rawReactionMessageInfoValidator, } from '../../types/messages/reaction.js'; import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported.js'; import type { NotifTexts } from '../../types/notif-types.js'; import type { ThreadInfo } from '../../types/thread-types.js'; import type { RelativeUserInfo } from '../../types/user-types.js'; import { ET } from '../../utils/entity-text.js'; import { threadIsGroupChat } from '../thread-utils.js'; import { hasMinCodeVersion } from '../version-utils.js'; export const reactionMessageSpec: MessageSpec< ReactionMessageData, RawReactionMessageInfo, ReactionMessageInfo, > = Object.freeze({ messageContentForServerDB( data: ReactionMessageData | RawReactionMessageInfo, ): string { return JSON.stringify({ reaction: data.reaction, action: data.action, }); }, messageContentForClientDB(data: RawReactionMessageInfo): string { return JSON.stringify({ targetMessageID: data.targetMessageID, reaction: data.reaction, action: data.action, }); }, messageTitle({ messageInfo }: MessageTitleParam) { const creator = ET.user({ userInfo: messageInfo.creator }); const preview = messageInfo.action === 'add_reaction' ? `reacted ${messageInfo.reaction} to a message` : 'unreacted to a message'; return ET`${creator} ${preview}`; }, rawMessageInfoFromServerDBRow(row: Object): RawReactionMessageInfo { invariant( row.targetMessageID !== null && row.targetMessageID !== undefined, 'targetMessageID should be set', ); const content = JSON.parse(row.content); return { type: messageTypes.REACTION, id: row.id.toString(), threadID: row.threadID.toString(), time: row.time, creatorID: row.creatorID.toString(), targetMessageID: row.targetMessageID.toString(), reaction: content.reaction, action: content.action, }; }, rawMessageInfoFromClientDB( clientDBMessageInfo: ClientDBMessageInfo, ): RawReactionMessageInfo { const messageType = assertMessageType(parseInt(clientDBMessageInfo.type)); invariant( messageType === messageTypes.REACTION, 'message must be of type REACTION', ); invariant( clientDBMessageInfo.content !== undefined && clientDBMessageInfo.content !== null, 'content must be defined for Reaction', ); const content = JSON.parse(clientDBMessageInfo.content); const rawReactionMessageInfo: RawReactionMessageInfo = { type: messageTypes.REACTION, id: clientDBMessageInfo.id, threadID: clientDBMessageInfo.thread, time: parseInt(clientDBMessageInfo.time), creatorID: clientDBMessageInfo.user, targetMessageID: content.targetMessageID, reaction: content.reaction, action: content.action, }; return rawReactionMessageInfo; }, createMessageInfo( rawMessageInfo: RawReactionMessageInfo, creator: RelativeUserInfo, ): ReactionMessageInfo { return { type: messageTypes.REACTION, id: rawMessageInfo.id, threadID: rawMessageInfo.threadID, creator, time: rawMessageInfo.time, targetMessageID: rawMessageInfo.targetMessageID, reaction: rawMessageInfo.reaction, action: rawMessageInfo.action, }; }, rawMessageInfoFromMessageData( messageData: ReactionMessageData, id: ?string, ): RawReactionMessageInfo { invariant(id, 'RawReactionMessageInfo needs id'); return { ...messageData, id }; }, shimUnsupportedMessageInfo( rawMessageInfo: RawReactionMessageInfo, platformDetails: ?PlatformDetails, ): RawReactionMessageInfo | RawUnsupportedMessageInfo { if (hasMinCodeVersion(platformDetails, { native: 167 })) { return rawMessageInfo; } const { id } = rawMessageInfo; invariant(id !== null && id !== undefined, 'id should be set on server'); return { type: messageTypes.UNSUPPORTED, id, threadID: rawMessageInfo.threadID, creatorID: rawMessageInfo.creatorID, time: rawMessageInfo.time, robotext: 'reacted to a message', unsupportedMessageInfo: rawMessageInfo, }; }, unshimMessageInfo(unwrapped: RawReactionMessageInfo): RawReactionMessageInfo { return unwrapped; }, async notificationTexts( messageInfos: $ReadOnlyArray, threadInfo: ThreadInfo, ): Promise { const messageInfo = assertSingleMessageInfo(messageInfos); invariant( messageInfo.type === messageTypes.REACTION, 'messageInfo should be reaction type', ); const creator = ET.user({ userInfo: messageInfo.creator }); const body = messageInfo.action === 'add_reaction' ? `reacted ${messageInfo.reaction} to your message` : 'unreacted to your message'; let merged = ET`${creator} ${body}`; if (threadInfo.name || threadIsGroupChat(threadInfo)) { const thread = ET.thread({ display: 'shortName', threadInfo }); merged = ET`${merged} in ${thread}`; } return { merged, body, title: threadInfo.uiName, prefix: ET`${creator}`, }; }, notificationCollapseKey(rawMessageInfo: RawReactionMessageInfo): string { return joinResult( rawMessageInfo.type, rawMessageInfo.threadID, rawMessageInfo.creatorID, rawMessageInfo.targetMessageID, ); }, generatesNotifs: async ( rawMessageInfo: RawReactionMessageInfo, messageData: ReactionMessageData, params: GeneratesNotifsParams, ) => { const { action } = rawMessageInfo; const { notifTargetUserID, fetchMessageInfoByID } = params; const targetMessageInfo = await fetchMessageInfoByID( rawMessageInfo.targetMessageID, ); if (targetMessageInfo?.creatorID !== notifTargetUserID) { return undefined; } return action === 'add_reaction' ? pushTypes.NOTIF : pushTypes.RESCIND; }, canBeSidebarSource: false, canBePinned: false, + canBeRenderedIndependently: false, + validator: rawReactionMessageInfoValidator, });