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

Update getMeetingDetailsVerbose Interface #2489

Merged
merged 21 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions apps/teams-test-app/e2e-test-data/meeting.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@
"expectedAlertValue": "getMeetingDetails called with shouldGetVerboseDetails: true",
KangxuanYe marked this conversation as resolved.
Show resolved Hide resolved
"expectedTestAppValue": "{\"details\":{\"scheduledStartTime\":\"testStartTime\",\"joinUrl\":\"testJoinUrl\",\"type\":\"oneOnOneCall\",\"originalCaller\":\"testCallerId\",\"dialedEntity\":\"testDnis\",\"trackingId\":\"testTrackingId\"},\"conversation\":{\"id\":\"testConversationId\"},\"organizer\":{\"id\":\"testOrganizerId\",\"tenantId\":\"testTenantId\"}}"
},
{
"title": "getMeetingDetailsVerbose API Call - Success",
"version": ">2.28.0",
"hostSdkVersion": {
"web": "> 4.2.2"
},
"type": "callResponse",
KangxuanYe marked this conversation as resolved.
Show resolved Hide resolved
"boxSelector": "#box_getMeetingDetailsVerbose",
"expectedAlertValue": "getMeetingDetails called with shouldGetVerboseDetails: true",
"expectedTestAppValue": "{\"details\":{\"scheduledStartTime\":\"testStartTime\",\"joinUrl\":\"testJoinUrl\",\"type\":\"oneOnOneCall\",\"originalCaller\":\"testCallerId\",\"dialedEntity\":\"testDnis\",\"originalCallerInfo\":{\"phoneNumber\":\"1234567890\",\"email\":{\"val\":\"[email protected]\"}},\"dialedEntityInfo\":{\"phoneNumber\":\"1234567890\",\"email\":{\"val\":\"[email protected]\"}},\"trackingId\":\"testTrackingId\",\"callId\":\"testCallId\"},\"conversation\":{\"id\":\"testConversationId\"},\"organizer\":{\"id\":\"testOrganizerId\",\"tenantId\":\"testTenantId\"}}"
},
{
"title": "getAuthenticationTokenForAnonymousUser API Call - Success",
"type": "callResponse",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Added three properties to `ICallDetails`, `originalCallerInfo`, `dialedEntityInfo`, and `callId`, created a new type `ICallParticipantIdentifiers`, and deprecated the `originalCaller` and `dialedEntity` properties",
"packageName": "@microsoft/teams-js",
"email": "[email protected]",
"dependentChangeType": "patch"
}
9 changes: 9 additions & 0 deletions packages/teams-js/src/internal/emailAddressValidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function validateEmailAddress(emailString: string | null | undefined): void {
const emailIsEmptyOrUndefined = emailString ? emailString.length <= 0 : true;
const atIndex = emailString?.indexOf('@');
const periodIndexAfterAt = emailString?.indexOf('.', atIndex);

if (emailIsEmptyOrUndefined || atIndex === -1 || periodIndexAfterAt === -1) {
throw new Error('Input email address does not have the correct format.');
}
}
21 changes: 21 additions & 0 deletions packages/teams-js/src/public/emailAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { validateEmailAddress } from '../internal/emailAddressValidation';

/**
* Represents a validated email.
*/
export class EmailAddress {
/** Represents the input email address string */
private readonly val: string;

public constructor(val: string) {
this.val = val;
validateEmailAddress(val);
}

/**
* Retrieve the validated email address as a string.
*/
public toString(): string {
return this.val;
}
}
1 change: 1 addition & 0 deletions packages/teams-js/src/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export {
} from './interfaces';
export { app } from './app';
export { AppId } from './appId';
export { EmailAddress } from './emailAddress';
export { appInstallDialog } from './appInstallDialog';
export { barCode } from './barCode';
export { chat, OpenGroupChatRequest, OpenSingleChatRequest } from './chat';
Expand Down
42 changes: 41 additions & 1 deletion packages/teams-js/src/public/meeting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { doesHandlerExist, registerHandler, removeHandler } from '../internal/ha
import { ensureInitialized } from '../internal/internalAPIs';
import { ApiName, ApiVersionNumber, getApiVersionTag } from '../internal/telemetry';
import { FrameContexts } from './constants';
import { EmailAddress } from './emailAddress';
import { ErrorCode, SdkError } from './interfaces';
import { runtime } from './runtime';

Expand Down Expand Up @@ -94,24 +95,63 @@ export namespace meeting {
type?: T;
}

/**
* @hidden
* Hide from docs
* Data structure to represent call participant identifiers
*/
interface ICallParticipantIdentifiers {
/**
* Phone number of a caller
*/
phoneNumber?: string;
TrevorJoelHarris marked this conversation as resolved.
Show resolved Hide resolved

/**
* Email of a caller
*/
email?: EmailAddress;
}

/**
* @hidden
* Hide from docs
* Data structure to represent call details
*/
export interface ICallDetails extends IMeetingOrCallDetailsBase<CallType> {
/**
* @deprecated please use {@link ICallDetails.originalCallerInfo} instead
*
* @hidden
* Phone number of a PSTN caller or email of a VoIP caller
*/
originalCaller?: string;

/**
* @hidden
* Object representing the original caller
*/
originalCallerInfo?: ICallParticipantIdentifiers;

/**
* @hidden
* Identifier for the current call
*/
callId?: string;

/**
* @deprecated please use {@link ICallDetails.dialedEntityInfo} instead
*
* @hidden
* Phone number of a PSTN callee or email of a VoIP callee
*/
dialedEntity?: never;

/**
* @hidden
* Object representing the entity the caller dialed
*/
dialedEntityInfo?: never;
TrevorJoelHarris marked this conversation as resolved.
Show resolved Hide resolved

/**
* @hidden
* Tracking identifier for grouping related calls
Expand Down Expand Up @@ -665,7 +705,7 @@ export namespace meeting {

if (
(response.details?.type == CallType.GroupCall || response.details?.type == CallType.OneOnOneCall) &&
!response.details.originalCaller
!response.details.originalCallerInfo
TrevorJoelHarris marked this conversation as resolved.
Show resolved Hide resolved
) {
throw new Error(ErrorCode.NOT_SUPPORTED_ON_PLATFORM.toString());
}
Expand Down
23 changes: 23 additions & 0 deletions packages/teams-js/test/internal/emailAddressValidation.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { validateEmailAddress } from '../../src/internal/emailAddressValidation';

describe('emailAddressValidation', () => {
const invalidEmails = ['domain.com', 'name.domain@com', 'name@domain', '', null];
invalidEmails.forEach((invalidEmail) => {
it('should throw errors for invalid email addresses', () => {
expect(() => validateEmailAddress(invalidEmail)).toThrow('Input email address does not have the correct format.');
});
});
const validEmails = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
];
validEmails.forEach((validEmail) => {
it('should not throw errors for valid email addresses', () => {
expect(() => validateEmailAddress(validEmail)).not.toThrow(
'Input email address does not have the correct format.',
);
});
});
});
24 changes: 24 additions & 0 deletions packages/teams-js/test/public/emailAddress.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { EmailAddress } from '../../src/public';

describe('emailAddress', () => {
const invalidEmails = ['domain.com', 'name.domain@com', 'name@domain'];
invalidEmails.forEach((invalidEmail) => {
it('should throw errors for invalid email addresses', () => {
expect(() => new EmailAddress(invalidEmail)).toThrowError(
'Input email address does not have the correct format.',
);
});
});
const validEmails = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
];
validEmails.forEach((validEmail) => {
it('should not throw errors for valid email addresses', () => {
const email = new EmailAddress(validEmail);
expect(email.toString()).toBe(validEmail);
});
});
});
12 changes: 9 additions & 3 deletions packages/teams-js/test/public/meeting.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { errorLibraryNotInitialized } from '../../src/internal/constants';
import { GlobalVars } from '../../src/internal/globalVars';
import { DOMMessageEvent } from '../../src/internal/interfaces';
import { MessageRequest } from '../../src/internal/messageObjects';
import { FrameContexts } from '../../src/public';
import { EmailAddress, FrameContexts } from '../../src/public';
import { app } from '../../src/public/app';
import { ErrorCode, SdkError } from '../../src/public/interfaces';
import { meeting } from '../../src/public/meeting';
Expand Down Expand Up @@ -277,7 +277,10 @@ describe('meeting', () => {
'https://teams.microsoft.com/l/meetup-join/19%3ameeting_qwertyuiop[phgfdsasdfghjkjbvcxcvbnmyt1234567890!@#$%^&*(%40thread.v2/0?context=%7b%22Tid%22%3a%2272f988bf-86f1-41af-91ab-2d7cd011db47%22%2c%22Oid%22%3a%226b33ac33-85ae-4995-be29-1d38a77aa8e3%22%7d',
type: meeting.CallType.OneOnOneCall,
// Verbose details
originalCaller: 'testCallerId',
originalCallerInfo: {
phoneNumber: '1234567890',
email: new EmailAddress('[email protected]'),
},
};
const organizer: meeting.IOrganizer = {
id: '8:orgid:6b33ac33-85ae-4995-be29-1d38a77aa8e3',
Expand Down Expand Up @@ -627,7 +630,10 @@ describe('meeting', () => {
'https://teams.microsoft.com/l/meetup-join/19%3ameeting_qwertyuiop[phgfdsasdfghjkjbvcxcvbnmyt1234567890!@#$%^&*(%40thread.v2/0?context=%7b%22Tid%22%3a%2272f988bf-86f1-41af-91ab-2d7cd011db47%22%2c%22Oid%22%3a%226b33ac33-85ae-4995-be29-1d38a77aa8e3%22%7d',
type: meeting.CallType.OneOnOneCall,
// Verbose details
originalCaller: 'testCallerId',
originalCallerInfo: {
phoneNumber: '1234567890',
email: new EmailAddress('[email protected]'),
},
};
const organizer: meeting.IOrganizer = {
id: '8:orgid:6b33ac33-85ae-4995-be29-1d38a77aa8e3',
Expand Down