diff --git a/__tests__/ic3/enhancers/egress/createEgressTypingActivityMiddleware.spec.js b/__tests__/ic3/enhancers/egress/createEgressTypingActivityMiddleware.spec.js index 881bf01..b9f7167 100644 --- a/__tests__/ic3/enhancers/egress/createEgressTypingActivityMiddleware.spec.js +++ b/__tests__/ic3/enhancers/egress/createEgressTypingActivityMiddleware.spec.js @@ -2,6 +2,7 @@ import { ActivityType } from './../../../../src/types/DirectLineTypes'; import { StateKey } from './../../../../src/types/ic3/IC3AdapterState'; import { TelemetryEvents } from './../../../../src/types/ic3/TelemetryEvents'; import createEgressTypingActivityMiddleware from './../../../../src/ic3/enhancers/egress/createEgressTypingActivityMiddleware'; +import { MessageTag } from './../../../../src/types/ic3/MessageTag'; describe('createEgressTypingActivityMiddleware test', () => { let globalMicrosoftBefore; @@ -65,7 +66,8 @@ describe('createEgressTypingActivityMiddleware test', () => { } createEgressTypingActivityMiddleware()({getState: mockGetState})(next)(activity); expect(indicateTypingStatusMock).toHaveBeenCalledWith('Typing', { - imdisplayname: StateKey.UserDisplayName + imdisplayname: StateKey.UserDisplayName, + tag: "public" }); expect(sendMessageToBotMock).toHaveBeenCalledWith(StateKey.BotId, { payload: '{"isTyping":true}' @@ -76,4 +78,25 @@ describe('createEgressTypingActivityMiddleware test', () => { CustomProperties: expect.anything() }); }); + + test('should indicate typing status, and pass tag', () => { + const activity = { + type: ActivityType.Typing, + channelData: { tags: ['private'] } + } + createEgressTypingActivityMiddleware()({getState: mockGetState})(next)(activity); + expect(indicateTypingStatusMock).toHaveBeenCalledWith('Typing', { + imdisplayname: StateKey.UserDisplayName, + tag: 'private' + }); + + expect(sendMessageToBotMock).toHaveBeenCalledWith(StateKey.BotId, { + payload: '{"isTyping":true}' + }); + expect(logClientSdkTelemetryEventSpy).toHaveBeenCalledWith('DEBUG', { + Event: TelemetryEvents.SEND_TYPING_SUCCESS, + Description: `Adapter: Successfully sent a typing indication`, + CustomProperties: expect.anything() + }); + }); }); diff --git a/__tests__/ic3/enhancers/ingress/createPatchFromRoleAndNameMiddleware.spec.js b/__tests__/ic3/enhancers/ingress/createPatchFromRoleAndNameMiddleware.spec.js index a5d6358..14a272b 100644 --- a/__tests__/ic3/enhancers/ingress/createPatchFromRoleAndNameMiddleware.spec.js +++ b/__tests__/ic3/enhancers/ingress/createPatchFromRoleAndNameMiddleware.spec.js @@ -57,4 +57,19 @@ describe('createPatchFromRoleAndNameMiddleware test', () => { expect(result).toBe('next'); expect(next).toHaveBeenCalledWith({...activity}); }); + + test('should call next with correct params and include tag', () => { + const getState = (key) => key === StateKey.UserId ? 'userId' : key === StateKey.UserDisplayName ? 'userName' : null; + const activity = { + from: { + id: 'userIdActivity', + name: 'activityName', + role: Role.Channel, + tag: 'private' + } + } + const result = createPatchFromRoleAndNameMiddleware()({ getState })(next)(activity); + expect(result).toBe('next'); + expect(next).toHaveBeenCalledWith({...activity}); + }); }); diff --git a/__tests__/ic3/enhancers/ingress/mappers/createTypingMessageToDirectLineActivityMapper.spec.js b/__tests__/ic3/enhancers/ingress/mappers/createTypingMessageToDirectLineActivityMapper.spec.js index 879a135..de6d38d 100644 --- a/__tests__/ic3/enhancers/ingress/mappers/createTypingMessageToDirectLineActivityMapper.spec.js +++ b/__tests__/ic3/enhancers/ingress/mappers/createTypingMessageToDirectLineActivityMapper.spec.js @@ -70,4 +70,26 @@ describe('createTypingMessageToDirectLineActivityMapper test', () => { } expect(result).toEqual(expectedResult); }); + + test('should pass tag with sender', async () => { + spyOn(Date.prototype, 'toISOString').and.returnValue('dateString'); + spyOn(uniqueId, 'default').and.returnValue('uniqueId'); + const conversation = { id: 'tesConvId' }; + const getState = () => conversation; + const message = { + messageType: 'Typing', + timestamp: new Date(), + sender: { displayName: 'displayName', id: 'senderId', tag: 'private' } + }; + const result = await createTypingMessageToDirectLineActivityMapper({ getState })()(message); + const expectedResult = { + channelId: IC3_CHANNEL_ID, + conversation, + from: { id: message.sender.id, name: message.sender.displayName, tag: message.sender.tag }, + id: 'uniqueId', + timestamp: 'dateString', + type: ActivityType.Typing + } + expect(result).toEqual(expectedResult); + }); }); diff --git a/src/ic3/enhancers/egress/createEgressTypingActivityMiddleware.ts b/src/ic3/enhancers/egress/createEgressTypingActivityMiddleware.ts index 0471ca1..a42bc5c 100644 --- a/src/ic3/enhancers/egress/createEgressTypingActivityMiddleware.ts +++ b/src/ic3/enhancers/egress/createEgressTypingActivityMiddleware.ts @@ -15,6 +15,16 @@ function isInternalActivity(activity: IC3DirectLineActivity): boolean { return activity.channelData && activity.channelData.tags && activity.channelData.tags.includes(MessageTag.Private); } +function getTags(isInternalActivity: boolean): string { + if (isInternalActivity) + { + return MessageTag.Private; + } + else { + return "public"; + } +} + export default function createEgressTypingActivityMiddleware(): EgressMiddleware< IC3DirectLineActivity, IC3AdapterState @@ -32,7 +42,8 @@ export default function createEgressTypingActivityMiddleware(): EgressMiddleware } conversation.indicateTypingStatus(Microsoft.CRM.Omnichannel.IC3Client.Model.TypingStatus.Typing, { - imdisplayname: getState(StateKey.UserDisplayName) || activity.from.name || '' + imdisplayname: getState(StateKey.UserDisplayName) || activity.from.name || '', + tag: getTags(isInternalActivity(activity)) }); const botIds = getState(StateKey.BotId); diff --git a/src/ic3/enhancers/ingress/createPatchFromRoleAndNameMiddleware.ts b/src/ic3/enhancers/ingress/createPatchFromRoleAndNameMiddleware.ts index 79d912e..bbcda3a 100644 --- a/src/ic3/enhancers/ingress/createPatchFromRoleAndNameMiddleware.ts +++ b/src/ic3/enhancers/ingress/createPatchFromRoleAndNameMiddleware.ts @@ -12,7 +12,7 @@ export default function createPatchFromRoleAndNameMiddleware(): IngressMiddlewar > { return ({ getState }) => next => (activity: IC3DirectLineActivity) => { const { - from: { id, name, role } + from: { id, name, role, tag } } = activity; const userId = getState(StateKey.UserId); @@ -26,7 +26,8 @@ export default function createPatchFromRoleAndNameMiddleware(): IngressMiddlewar from: { id, role: patchedRole, - name: (patchedRole === Role.User && getState(StateKey.UserDisplayName)) || name + name: (patchedRole === Role.User && getState(StateKey.UserDisplayName)) || name, + tag } } return next(patchedActivity); diff --git a/src/ic3/enhancers/ingress/mappers/createTypingMessageToDirectLineActivityMapper.ts b/src/ic3/enhancers/ingress/mappers/createTypingMessageToDirectLineActivityMapper.ts index b920de9..899a6d2 100644 --- a/src/ic3/enhancers/ingress/mappers/createTypingMessageToDirectLineActivityMapper.ts +++ b/src/ic3/enhancers/ingress/mappers/createTypingMessageToDirectLineActivityMapper.ts @@ -34,7 +34,7 @@ export default function createTypingMessageToDirectLineActivityMapper({ } const { - sender: { displayName: name, id }, + sender: { displayName: name, id, tag }, timestamp } = message; @@ -43,7 +43,8 @@ export default function createTypingMessageToDirectLineActivityMapper({ conversation: { id: conversation.id }, from: { id, - name + name, + tag }, id: uniqueId(), timestamp: timestamp.toISOString(), diff --git a/src/types/DirectLineTypes.ts b/src/types/DirectLineTypes.ts index 54ab57e..6d5fcaf 100644 --- a/src/types/DirectLineTypes.ts +++ b/src/types/DirectLineTypes.ts @@ -42,6 +42,7 @@ interface IDirectLineActivity { id: string; name?: string; role?: Role; + tag?: string; }; id?: string; suggestedActions?: SuggestedActions; diff --git a/src/types/ic3/external/Model.d.ts b/src/types/ic3/external/Model.d.ts index cf75c05..98f4d6c 100644 --- a/src/types/ic3/external/Model.d.ts +++ b/src/types/ic3/external/Model.d.ts @@ -227,6 +227,7 @@ declare namespace Microsoft.CRM.Omnichannel.IC3Client.Model { displayName: string; id: string; type: PersonType; + tag?: string; } }