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

fix(contacts): handle optional scim fields #3827

Merged
merged 3 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
38 changes: 38 additions & 0 deletions packages/calling/src/Contacts/ContactsClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import {
mockContactGroupListOne,
mockContactGroupListTwo,
mockAvatarURL,
mockSCIMMinListResponse,
mockContactMinimum,
} from './contactFixtures';

describe('ContactClient Tests', () => {
Expand Down Expand Up @@ -724,4 +726,40 @@ describe('ContactClient Tests', () => {

expect(contactClient['contacts']).toEqual(mockContactListOne);
});

it('test resolveContacts function for a minimal contact with few details', () => {
const contact = contactClient['resolveCloudContacts'](
{userId: mockContactMinimum},
mockSCIMMinListResponse.body
);

expect(contact).toEqual([
{
avatarURL: '',
avatarUrlDomain: undefined,
contactId: 'userId',
contactType: 'CLOUD',
department: undefined,
displayName: undefined,
emails: undefined,
encryptionKeyUrl: 'kms://cisco.com/keys/dcf18f9d-155e-44ff-ad61-c8a69b7103ab',
firstName: undefined,
groups: ['1561977e-3443-4ccf-a591-69686275d7d2'],
lastName: undefined,
manager: undefined,
ownerId: 'ownerId',
phoneNumbers: undefined,
sipAddresses: undefined,
},
]);
});

it('test resolveContacts function encountering an error', () => {
const contact = contactClient['resolveCloudContacts'](
{userId: mockContactMinimum},
mockSCIMMinListResponse
);

expect(contact).toEqual(null);
});
});
26 changes: 13 additions & 13 deletions packages/calling/src/Contacts/ContactsClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ import {
} from './types';

import {scimQuery, serviceErrorCodeHandler} from '../common/Utils';
import Logger from '../Logger';
import ExtendedError from '../Errors/catalog/ExtendedError';
import {ERROR_TYPE} from '../Errors/types';

/**
* `ContactsClient` module is designed to offer a set of APIs for retrieving and updating contacts and groups from the contacts-service.
Expand Down Expand Up @@ -264,6 +261,10 @@ export class ContactsClient implements IContacts {
contactsDataMap: ContactIdContactInfo,
inputList: SCIMListResponse
): Contact[] | null {
const loggerContext = {
file: CONTACTS_FILE,
method: 'resolveCloudContacts',
};
const finalContactList: Contact[] = [];

try {
Expand All @@ -272,16 +273,15 @@ export class ContactsClient implements IContacts {
const filteredContact = inputList.Resources.filter((item) => item.id === contactList[n])[0];

const {displayName, emails, phoneNumbers, photos} = filteredContact;
const {sipAddresses} = filteredContact[SCIM_WEBEXIDENTITY_USER];
const firstName = filteredContact.name.givenName;
const lastName = filteredContact.name.familyName;
const manager = filteredContact[SCIM_ENTERPRISE_USER].manager.displayName;
const department = filteredContact[SCIM_ENTERPRISE_USER].department;

let avatarURL = '';
if (photos?.length) {
avatarURL = photos[0].value;
let sipAddresses;
if (filteredContact[SCIM_WEBEXIDENTITY_USER]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Maybe we can use ternary operator here also.. but just a suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adhmenon the ternary operator doesn't work here. Something to do with the way typescript recognizes this object member. I initially tried with ternary but kept getting errors that SCIM_WEBEXIDENTITY_USER could be undefined.

sipAddresses = filteredContact[SCIM_WEBEXIDENTITY_USER].sipAddresses;
}
const firstName = filteredContact.name?.givenName;
const lastName = filteredContact.name?.familyName;
const manager = filteredContact[SCIM_ENTERPRISE_USER]?.manager?.displayName;
const department = filteredContact[SCIM_ENTERPRISE_USER]?.department;
const avatarURL = photos?.length ? photos[0].value : '';

const {contactType, avatarUrlDomain, encryptionKeyUrl, ownerId, groups} =
contactsDataMap[contactList[n]];
Expand All @@ -307,7 +307,7 @@ export class ContactsClient implements IContacts {
finalContactList.push(cloudContact);
}
} catch (error: any) {
Logger.error(new ExtendedError(error.message, {}, ERROR_TYPE.DEFAULT), {});
log.warn('Error occurred while parsing resolved contacts', loggerContext);

return null;
}
Expand Down
30 changes: 28 additions & 2 deletions packages/calling/src/Contacts/contactFixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,21 @@ export const mockContactGroupListTwo = [
},
];

export const mockContactMinimum = {
contactId: 'userId',
contactType: 'CLOUD',
encryptionKeyUrl: 'kms://cisco.com/keys/dcf18f9d-155e-44ff-ad61-c8a69b7103ab',
groups: ['1561977e-3443-4ccf-a591-69686275d7d2'],
ownerId: 'ownerId',
};

export const scimUserMinimum = {
schemas: ['urn:ietf:params:scim:schemas:core:2.0:User'],
id: 'userId',
userName: 'userName',
userType: 'user',
};

const scimUser1 = {
schemas: [
'urn:ietf:params:scim:schemas:core:2.0:User',
Expand Down Expand Up @@ -448,13 +463,24 @@ export const mockSCIMListResponse = {
statusCode: 200,
body: {
schemas: ['urn:ietf:params:scim:api:messages:2.0:ListResponse'],
totalResults: 11,
itemsPerPage: 11,
totalResults: 2,
itemsPerPage: 2,
startIndex: 1,
Resources: [scimUser1, scimUser2NoPhoto],
},
};

export const mockSCIMMinListResponse = {
statusCode: 200,
body: {
schemas: ['urn:ietf:params:scim:api:messages:2.0:ListResponse'],
totalResults: 1,
itemsPerPage: 1,
startIndex: 1,
Resources: [scimUserMinimum],
},
};

export const mockKmsKey = {
uri: 'kms://kms-cisco.wbx2.com/keys/16095024-612d-4424-ba51-57cad2402e14',
};
Expand Down
4 changes: 2 additions & 2 deletions packages/calling/src/Contacts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export type Contact = {
/**
* Unique identifier of the contact.
*/
contactId?: string;
contactId: string;
/**
* Indicates the type of the contact, can be `CLOUD` or `CUSTOM`.
*/
Expand All @@ -41,7 +41,7 @@ export type Contact = {
/**
* This represents the display name of the contact.
*/
displayName: string;
displayName?: string;
/**
* This represents the array of different email addresses of the contact.
*/
Expand Down
24 changes: 12 additions & 12 deletions packages/calling/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ interface WebexIdentityMeta {
organizationId: string;
}
interface WebexIdentityUser {
sipAddresses: URIAddress[];
meta: WebexIdentityMeta;
sipAddresses?: URIAddress[];
meta?: WebexIdentityMeta;
}

interface Manager {
Expand All @@ -231,24 +231,24 @@ interface Manager {
}

interface EnterpriseUser {
department: string;
manager: Manager;
department?: string;
manager?: Manager;
}

interface Resource {
schemas: string[];
id: string;
userName: string;
active: boolean;
name: Name;
displayName: string;
emails: URIAddress[];
active?: boolean;
name?: Name;
displayName?: string;
emails?: URIAddress[];
userType: string;
phoneNumbers: PhoneNumber[];
phoneNumbers?: PhoneNumber[];
photos?: ContactDetail[];
addresses: Address[];
[SCIM_WEBEXIDENTITY_USER]: WebexIdentityUser;
[SCIM_ENTERPRISE_USER]: EnterpriseUser;
addresses?: Address[];
[SCIM_WEBEXIDENTITY_USER]?: WebexIdentityUser;
[SCIM_ENTERPRISE_USER]?: EnterpriseUser;
}

export interface SCIMListResponse {
Expand Down
Loading