Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding UUIDs to MessageRequests and MessageResponses #2240

Merged
merged 73 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
94fd54e
Adding UUIDs to MessageRequests and MessageResponses
jadahiya-MSFT Mar 28, 2024
31a6fff
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Mar 29, 2024
c88d928
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT Apr 5, 2024
c4cf4f5
Committing changefile
jadahiya-MSFT Apr 5, 2024
bc16dbd
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 5, 2024
22d79fb
Merge branch 'jadahiya/message-ids' of https://github.com/OfficeDev/m…
jadahiya-MSFT Apr 5, 2024
da23fb9
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT Apr 5, 2024
0561252
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT Apr 8, 2024
fa624f6
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 9, 2024
3936b05
Merge branch 'jadahiya/message-ids' of https://github.com/OfficeDev/m…
jadahiya-MSFT Apr 9, 2024
f4dec6b
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT Apr 11, 2024
493cbcf
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 11, 2024
0bbefda
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 12, 2024
810e152
Added in MessageID and MessageUUID types, added in testing for UUID c…
jadahiya-MSFT Apr 12, 2024
c4e41e5
Changing waitForResponse to have input of type MessageUUID
jadahiya-MSFT Apr 12, 2024
2cc94da
Updated references to use MessageID and MessageUUID
jadahiya-MSFT Apr 12, 2024
cfd4061
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT Apr 16, 2024
6d76fdf
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT Apr 16, 2024
c2c6e81
Fixed lint error
jadahiya-MSFT Apr 16, 2024
daed3b9
Created BaseUUID type
jadahiya-MSFT Apr 16, 2024
90484a6
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 17, 2024
973518e
Added validation for uuid to handleParentMessage
jadahiya-MSFT Apr 17, 2024
743a896
Only validate UUIDs if there is one
jadahiya-MSFT Apr 17, 2024
c811c70
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 19, 2024
6566d6b
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 22, 2024
1951d2d
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 24, 2024
09506d5
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 24, 2024
600e0ec
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 25, 2024
db545d1
Added in MessageUUID object
jadahiya-MSFT Apr 25, 2024
0a20ad3
Testing new changes to UUID
jadahiya-MSFT Apr 26, 2024
14c367a
Added in serialization of objects
jadahiya-MSFT Apr 26, 2024
588a8c7
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 26, 2024
dfbdc87
Updated to address PR feedback
jadahiya-MSFT Apr 26, 2024
1e8cdc9
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT Apr 29, 2024
d3c0472
Added comment describing MessageID vs MessageUUID
jadahiya-MSFT Apr 29, 2024
59865dc
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT Apr 29, 2024
fd61898
Added in helper function
jadahiya-MSFT Apr 29, 2024
6ac09bc
Merge branch 'main' into jadahiya/message-ids
TrevorJoelHarris Apr 30, 2024
1d971a3
Removing comment since map.delete was verified to work correctly
jadahiya-MSFT Apr 30, 2024
fd5e2ea
Merge branch 'jadahiya/message-ids' of https://github.com/OfficeDev/m…
jadahiya-MSFT Apr 30, 2024
8514bdf
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT May 1, 2024
eca774f
Moved uuid object to interfaces.ts for more general use
jadahiya-MSFT May 1, 2024
f69feeb
Merge branch 'jadahiya/message-ids' of https://github.com/OfficeDev/m…
jadahiya-MSFT May 1, 2024
b6a1e35
Replaced Function in Map declarations
jadahiya-MSFT May 1, 2024
a1f907c
Updated to use serialized and deserialized Message Response objects
jadahiya-MSFT May 1, 2024
5376b3d
Merge branch 'main' into jadahiya/message-ids
TrevorJoelHarris May 3, 2024
3ca103f
Added in unit tests for UUID class
jadahiya-MSFT May 4, 2024
ba69288
Fixed lint error
jadahiya-MSFT May 4, 2024
257b3e8
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT May 6, 2024
62c9759
Updating tests
jadahiya-MSFT May 7, 2024
61dd60f
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT May 7, 2024
960259e
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT May 8, 2024
16192cb
Moved uuid object to new file uuidObject.ts, edited changefile verbage
jadahiya-MSFT May 8, 2024
8b4e3ef
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT May 8, 2024
7ee266a
Added in unit tests for testing callback map deletion and functionality
jadahiya-MSFT May 8, 2024
6e81322
Removed unnused import
jadahiya-MSFT May 8, 2024
391c42a
Added in logging for when a callbackID fails to be generated
jadahiya-MSFT May 8, 2024
c90a59c
Fixed a typo in communication spec
jadahiya-MSFT May 8, 2024
427b356
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT May 9, 2024
466cd17
Updated serialization and deserialization and uuid toString function
jadahiya-MSFT May 10, 2024
cf723f1
Merge branch 'jadahiya/message-ids' of https://github.com/OfficeDev/m…
jadahiya-MSFT May 10, 2024
401945b
Reverted toString() change due to compatibility issues
jadahiya-MSFT May 10, 2024
e06dde9
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT May 10, 2024
ede7f6c
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT May 10, 2024
2cb196c
Removing unnecessary map clear due to already clearing in uninitializ…
jadahiya-MSFT May 10, 2024
2b41e03
Merge branch 'jadahiya/message-ids' of https://github.com/OfficeDev/m…
jadahiya-MSFT May 10, 2024
7491372
Fixed an issue with removing message ids
jadahiya-MSFT May 10, 2024
a7da461
Merge branch 'main' into jadahiya/message-ids
AE-MS May 13, 2024
cb49af1
Merge branch 'main' of https://github.com/OfficeDev/microsoft-teams-l…
jadahiya-MSFT May 13, 2024
b88fbba
Reverting uuid back to private
jadahiya-MSFT May 13, 2024
ce5504e
Merge branch 'jadahiya/message-ids' of https://github.com/OfficeDev/m…
jadahiya-MSFT May 13, 2024
959047a
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT May 13, 2024
b757441
Merge branch 'main' into jadahiya/message-ids
jadahiya-MSFT May 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Added `uuid` parameter to `MessageRequest` and `MessageResponse` interfaces",
"packageName": "@microsoft/teams-js",
"email": "jadahiya@microsoft.com",
"dependentChangeType": "patch"
}
267 changes: 190 additions & 77 deletions packages/teams-js/src/internal/communication.ts

Large diffs are not rendered by default.

84 changes: 81 additions & 3 deletions packages/teams-js/src/internal/messageObjects.ts
@@ -1,22 +1,61 @@
import { UUID as MessageUUID } from './uuidObject';

/**
* @internal
* Limited to Microsoft-internal use
*
* MessageIDs represent the legacy number id used for processing MessageRequests and MessageResponses
*/
export type MessageID = number;

/**
* @internal
* Limited to Microsoft-internal use
*/
export interface MessageRequest {
id?: number;
id?: MessageID;
uuid?: MessageUUID;
func: string;
timestamp?: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
args?: any[];
apiVersionTag?: string;
isPartialResponse?: boolean;
}

/**
* @internal
* Limited to Microsoft-internal use
*/
export interface SerializedMessageRequest {
id?: MessageID;
uuidAsString?: string;
func: string;
timestamp?: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
args?: any[];
apiVersionTag?: string;
}

/**
* @internal
* Limited to Microsoft-internal use
*/
export interface SerializedMessageResponse {
id: MessageID;
uuidAsString?: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
args?: any[];
jadahiya-MSFT marked this conversation as resolved.
Show resolved Hide resolved
isPartialResponse?: boolean; // If the message is partial, then there will be more future responses for the given message ID.
}

/**
* @internal
* Limited to Microsoft-internal use
*/
export interface MessageResponse {
jadahiya-MSFT marked this conversation as resolved.
Show resolved Hide resolved
id: number;
id: MessageID;
uuid?: MessageUUID;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
args?: any[];
isPartialResponse?: boolean; // If the message is partial, then there will be more future responses for the given message ID.
Expand All @@ -34,6 +73,45 @@ export interface MessageResponse {
* merged. However, it's a journey.
*/
export interface MessageRequestWithRequiredProperties extends MessageRequest {
id: number;
id: MessageID;
uuid: MessageUUID;
timestamp: number;
}

export const serializeMessageRequest = (message: MessageRequest): SerializedMessageRequest => {
const { uuid, ...restOfMessage } = message;
const uuidAsString = uuid?.toString();
const request: SerializedMessageRequest = {
...restOfMessage,
uuidAsString: uuidAsString,
};
return request;
};

export const deserializeMessageRequest = (message: SerializedMessageRequest): MessageRequest => {
const { uuidAsString, ...restOfMessage } = message;
const request: MessageRequest = {
...restOfMessage,
uuid: uuidAsString ? new MessageUUID(uuidAsString) : undefined,
};
return request;
};

export const deserializeMessageResponse = (serializedResponse: SerializedMessageResponse): MessageResponse => {
const { uuidAsString, ...restOfResponse } = serializedResponse;
const messageResponse: MessageResponse = {
...restOfResponse,
uuid: uuidAsString ? new MessageUUID(uuidAsString) : undefined,
};
return messageResponse;
};

export const serializeMessageResponse = (response: MessageResponse): SerializedMessageResponse => {
const { uuid, ...restOfResponse } = response;
const uuidAsString = uuid?.toString();
const messageResponse: SerializedMessageResponse = {
...restOfResponse,
uuidAsString: uuidAsString,
};
return messageResponse;
};
17 changes: 17 additions & 0 deletions packages/teams-js/src/internal/uuidObject.ts
@@ -0,0 +1,17 @@
import { generateGUID, validateUuid } from './utils';

/**
* @internal
* Limited to Microsoft-internal use
*
* UUID object
*/
export class UUID {
public constructor(private readonly uuid: string = generateGUID()) {
validateUuid(uuid);
}

public toString(): string {
return this.uuid;
}
}
142 changes: 141 additions & 1 deletion packages/teams-js/test/internal/communication.spec.ts
@@ -1,10 +1,12 @@
import * as communication from '../../src/internal/communication';
import { GlobalVars } from '../../src/internal/globalVars';
import { MessageRequest } from '../../src/internal/messageObjects';
import { NestedAppAuthMessageEventNames, NestedAppAuthRequest } from '../../src/internal/nestedAppAuthUtils';
import { ApiName, ApiVersionNumber, getApiVersionTag } from '../../src/internal/telemetry';
import { UUID } from '../../src/internal/uuidObject';
import { FrameContexts } from '../../src/public';
import { app } from '../../src/public/app';
import { MessageRequest, Utils } from '../utils';
import { Utils } from '../utils';

const testApiVersion = getApiVersionTag(ApiVersionNumber.V_1, 'mockedApiName' as ApiName);

Expand Down Expand Up @@ -1609,4 +1611,142 @@ describe('Testing communication', () => {
});
});
});
describe('UUID tests', () => {
let utils: Utils = new Utils();

beforeEach(() => {
// Set a mock window for testing
utils = new Utils();
utils.mockWindow.parent = undefined;
app._initialize(utils.mockWindow);
communication.Communication.parentWindow = undefined;
GlobalVars.isFramelessWindow = false;
});
afterEach(() => {
communication.uninitializeCommunication();
});
afterAll(() => {
GlobalVars.isFramelessWindow = false;
});
describe('postMessage', () => {
it('should delete callback correctly with uuid', async () => {
app._initialize(utils.mockWindow);
communication.initializeCommunication(undefined, testApiVersion);
let callbackWasCalled = 0;
const initializeMessage = utils.findInitializeMessageOrThrow();
let message = utils.findMessageByFunc('initialize');

if (message) {
expect(message.id).toBe(0);
}

await utils.respondToMessage(initializeMessage);

communication.sendMessageToParent(testApiVersion, 'testAction', () => {
callbackWasCalled++;
});
message = utils.findMessageByFunc('testAction');

if (message) {
expect(message.id).toBe(1);
}

await utils.respondToMessage({ id: message?.id, uuid: message?.uuid, func: 'testAction' }, false);

expect(callbackWasCalled).toBe(1);

//Call respondToMessageAgain, this should not call the callback since it should be deleted and callbackWasCalled should be still 1
await utils.respondToMessage({ id: message?.id, uuid: message?.uuid, func: 'testAction' }, false);

expect(callbackWasCalled).toBe(1);

communication.sendMessageToParent(testApiVersion, 'testAction2', () => {
callbackWasCalled++;
});

message = utils.findMessageByFunc('testAction2');

if (message) {
expect(message.id).toBe(2);
}

await utils.respondToMessage({ id: message?.id, uuid: message?.uuid, func: 'testAction2' }, false);
expect(callbackWasCalled).toBe(2);
});

it('should delete callback correctly with number id only', async () => {
app._initialize(utils.mockWindow);
communication.initializeCommunication(undefined, testApiVersion);
let callbackWasCalled = 0;
const initializeMessage = utils.findInitializeMessageOrThrow();
let message = utils.findMessageByFunc('initialize');

if (message) {
expect(message.id).toBe(0);
}

await utils.respondToMessage(initializeMessage);

communication.sendMessageToParent(testApiVersion, 'testAction', () => {
callbackWasCalled++;
});
message = utils.findMessageByFunc('testAction');

if (message) {
expect(message.id).toBe(1);
}

await utils.respondToMessage({ id: message?.id, func: 'testAction' }, false);

expect(callbackWasCalled).toBe(1);

//Call respondToMessageAgain, this should not call the callback since it should be deleted and callbackWasCalled should be still 1
await utils.respondToMessage({ id: message?.id, func: 'testAction' }, false);

expect(callbackWasCalled).toBe(1);

communication.sendMessageToParent(testApiVersion, 'testAction2', () => {
callbackWasCalled++;
});

message = utils.findMessageByFunc('testAction2');

if (message) {
expect(message.id).toBe(2);
}

await utils.respondToMessage({ id: message?.id, func: 'testAction2' }, false);
expect(callbackWasCalled).toBe(2);
});

it('should not call callback with invalid uuid', async () => {
app._initialize(utils.mockWindow);
communication.initializeCommunication(undefined, testApiVersion);
let callbackWasCalled = 0;
const initializeMessage = utils.findInitializeMessageOrThrow();

await utils.respondToMessage(initializeMessage);

communication.sendMessageToParent(testApiVersion, 'testAction', () => {
callbackWasCalled++;
});

const message = utils.findMessageByFunc('testAction');

if (message) {
expect(message.id).toBe(1);
}

await utils.respondToMessage({ id: message?.id, uuid: new UUID(), func: 'testAction' }, false);

//Since uuid is set but is not the same value as the message request, message should not process and message should not call callback
expect(callbackWasCalled).toBe(0);

//Respond with correct set of message uuid and now callback should be called
await utils.respondToMessage({ id: message?.id, uuid: message?.uuid, func: 'testAction' }, false);

expect(callbackWasCalled).toBe(1);
});
});
});
});