diff --git a/app/products/calls/components/calls_custom_message/calls_custom_message.tsx b/app/products/calls/components/calls_custom_message/calls_custom_message.tsx index 9cdca0d2c..13e34fded 100644 --- a/app/products/calls/components/calls_custom_message/calls_custom_message.tsx +++ b/app/products/calls/components/calls_custom_message/calls_custom_message.tsx @@ -9,6 +9,7 @@ import {Text, TouchableOpacity, View} from 'react-native'; import {leaveCallConfirmation} from '@calls/actions/calls'; import {leaveAndJoinWithAlert, showLimitRestrictedAlert} from '@calls/alerts'; import {setJoiningChannelId} from '@calls/state'; +import {getCallPropsFromPost} from '@calls/utils'; import CompassIcon from '@components/compass_icon'; import FormattedRelativeTime from '@components/formatted_relative_time'; import FormattedText from '@components/formatted_text'; @@ -164,13 +165,15 @@ export const CallsCustomMessage = ({ leaveCallConfirmation(intl, otherParticipants, isAdmin, isHost, serverUrl, post.channelId); }, [intl, otherParticipants, isAdmin, isHost, serverUrl, post.channelId]); - const title = post.props.title ? ( + const callProps = getCallPropsFromPost(post); + + const title = callProps.title ? ( - {post.props.title} + {callProps.title} ) : null; - if (post.props.end_at) { + if (callProps.start_at > 0 && callProps.end_at > 0) { return ( <> {title} @@ -195,7 +198,7 @@ export const CallsCustomMessage = ({ {' '} @@ -204,7 +207,7 @@ export const CallsCustomMessage = ({ id={'mobile.calls_lasted'} style={style.timeText} defaultMessage={'Lasted {duration}'} - values={{duration: moment.duration(post.props.end_at - post.props.start_at).humanize(false)}} + values={{duration: moment.duration(callProps.end_at - callProps.start_at).humanize(false)}} /> @@ -273,7 +276,7 @@ export const CallsCustomMessage = ({ style={style.text} /> diff --git a/app/products/calls/utils.test.ts b/app/products/calls/utils.test.ts index b70afb726..cf59dc1c3 100644 --- a/app/products/calls/utils.test.ts +++ b/app/products/calls/utils.test.ts @@ -6,7 +6,7 @@ import assert from 'assert'; import {type CallsConfigState, DefaultCallsConfig} from '@calls/types/calls'; import {License} from '@constants'; -import {getICEServersConfigs} from './utils'; +import {getICEServersConfigs, getCallPropsFromPost} from './utils'; describe('getICEServersConfigs', () => { it('backwards compatible case, no ICEServersConfigs present', () => { @@ -97,3 +97,109 @@ describe('getICEServersConfigs', () => { ]); }); }); + +describe('getCallPropsFromPost', () => { + test('undefined props', () => { + const post = {} as Post; + + const props = getCallPropsFromPost(post); + + expect(props.title).toBe(''); + expect(props.start_at).toBe(0); + expect(props.end_at).toBe(0); + expect(props.recordings).toStrictEqual({}); + expect(props.recording_files.length).toBe(0); + expect(props.transcriptions).toStrictEqual({}); + expect(props.participants.length).toBe(0); + }); + + test('missing props', () => { + const post = { + props: {}, + } as Post; + + const props = getCallPropsFromPost(post); + + expect(props.title).toBe(''); + expect(props.start_at).toBe(0); + expect(props.end_at).toBe(0); + expect(props.recordings).toStrictEqual({}); + expect(props.recording_files.length).toBe(0); + expect(props.transcriptions).toStrictEqual({}); + expect(props.participants.length).toBe(0); + }); + + test('invalid props', () => { + const callProps = { + title: {}, + start_at: 'invalid', + end_at: [], + recordings: null, + transcriptions: 45, + participants: 'invalid', + recording_files: 45, + }; + + const post = { + props: callProps as unknown, + } as Post; + + const props = getCallPropsFromPost(post); + + expect(props.title).toBe(''); + expect(props.start_at).toBe(0); + expect(props.end_at).toBe(0); + expect(props.recordings).toStrictEqual({}); + expect(props.recording_files.length).toBe(0); + expect(props.transcriptions).toStrictEqual({}); + expect(props.participants.length).toBe(0); + }); + + test('full props', () => { + const callProps = { + title: 'call title', + start_at: 1000, + end_at: 1045, + recordings: { + recA: { + file_id: 'recAFileID', + post_id: 'recAPostID', + tr_id: 'trA', + }, + recB: { + file_id: 'recBFileID', + post_id: 'recBPostID', + tr_id: 'trB', + }, + }, + recording_files: ['recAFileID', 'recBFileID'], + transcriptions: { + trA: { + file_id: 'trAFileID', + post_id: 'trAPostID', + rec_id: 'recA', + }, + trB: { + file_id: 'trBFileID', + post_id: 'trBPostID', + rec_id: 'recB', + }, + }, + participants: ['userA', 'userB'], + }; + + const post = { + props: callProps as unknown, + } as Post; + + const props = getCallPropsFromPost(post); + + expect(props.title).toBe(post.props.title); + expect(props.start_at).toBe(post.props.start_at); + expect(props.end_at).toBe(post.props.end_at); + expect(props.recordings).toBe(post.props.recordings); + expect(props.recording_files).toBe(post.props.recording_files); + expect(props.transcriptions).toBe(post.props.transcriptions); + expect(props.participants).toBe(post.props.participants); + }); +}); diff --git a/app/products/calls/utils.ts b/app/products/calls/utils.ts index 086df8ec3..13969feb0 100644 --- a/app/products/calls/utils.ts +++ b/app/products/calls/utils.ts @@ -17,7 +17,7 @@ import type { CallsTheme, CallsVersion, } from '@calls/types/calls'; -import type {CallsConfig, Caption} from '@mattermost/calls/lib/types'; +import type {CallsConfig, Caption, CallPostProps} from '@mattermost/calls/lib/types'; import type PostModel from '@typings/database/models/servers/post'; import type UserModel from '@typings/database/models/servers/user'; import type {IntlShape} from 'react-intl'; @@ -246,3 +246,21 @@ export const getTranscriptionUri = (serverUrl: string, postProps?: Record