Skip to content

Commit

Permalink
feat(meetings): add meetings.registrationStatus flags for JMF debuggi…
Browse files Browse the repository at this point in the history
…ng (#4111)
  • Loading branch information
chburket authored Feb 22, 2025
1 parent e77cae6 commit 0f681f8
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 21 deletions.
9 changes: 9 additions & 0 deletions packages/@webex/plugin-meetings/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1389,3 +1389,12 @@ export const DESTINATION_TYPE = {
} as const;

export type DESTINATION_TYPE = Enum<typeof DESTINATION_TYPE>;

export const INITIAL_REGISTRATION_STATUS = {
fetchWebexSite: false,
getGeoHint: false,
startReachability: false,
deviceRegister: false,
mercuryConnect: false,
checkH264Support: false,
};
70 changes: 52 additions & 18 deletions packages/@webex/plugin-meetings/src/meetings/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint no-shadow: ["error", { "allow": ["eventType"] }] */
import {cloneDeep} from 'lodash';
import {cloneDeep, clone} from 'lodash';
import '@webex/internal-plugin-mercury';
import '@webex/internal-plugin-conversation';
import '@webex/internal-plugin-metrics';
Expand Down Expand Up @@ -42,6 +42,7 @@ import {
_ON_HOLD_LOBBY_,
_WAIT_,
DESTINATION_TYPE,
INITIAL_REGISTRATION_STATUS,
} from '../constants';
import BEHAVIORAL_METRICS from '../metrics/constants';
import MeetingInfo from '../meeting-info';
Expand All @@ -53,7 +54,12 @@ import Request from './request';
import PasswordError from '../common/errors/password-error';
import CaptchaError from '../common/errors/captcha-error';
import MeetingCollection from './collection';
import {MEETING_KEY, INoiseReductionEffect, IVirtualBackgroundEffect} from './meetings.types';
import {
MEETING_KEY,
INoiseReductionEffect,
IVirtualBackgroundEffect,
MeetingRegistrationStatus,
} from './meetings.types';
import MeetingsUtil from './util';
import PermissionError from '../common/errors/permission';
import JoinWebinarError from '../common/errors/join-webinar-error';
Expand Down Expand Up @@ -179,6 +185,7 @@ export default class Meetings extends WebexPlugin {
mediaHelpers: any;
breakoutLocusForHandleLater: any;
namespace = MEETINGS;
registrationStatus: MeetingRegistrationStatus;

/**
* Initializes the Meetings Plugin
Expand Down Expand Up @@ -785,6 +792,18 @@ export default class Meetings extends WebexPlugin {
}
}

/**
* Executes a registration step and updates the registration status.
* @param {Function} step - The registration step to execute.
* @param {string} stepName - The name of the registration step.
* @returns {Promise} A promise that resolves when the step is completed.
*/
executeRegistrationStep(step: () => Promise<any>, stepName: string) {
return step().then(() => {
this.registrationStatus[stepName] = true;
});
}

/**
* Explicitly sets up the meetings plugin by registering
* the device, connecting to mercury, and listening for locus events.
Expand All @@ -795,6 +814,8 @@ export default class Meetings extends WebexPlugin {
* @memberof Meetings
*/
public register(deviceRegistrationOptions?: DeviceRegistrationOptions): Promise<any> {
this.registrationStatus = clone(INITIAL_REGISTRATION_STATUS);

// @ts-ignore
if (!this.webex.canAuthorize) {
LoggerProxy.logger.error(
Expand All @@ -813,24 +834,36 @@ export default class Meetings extends WebexPlugin {
}

return Promise.all([
this.fetchUserPreferredWebexSite(),
this.getGeoHint(),
this.startReachability('registration').catch((error) => {
LoggerProxy.logger.error(`Meetings:index#register --> GDM error, ${error.message}`);
}),
// @ts-ignore
this.webex.internal.device
.register(deviceRegistrationOptions)
// @ts-ignore
.then(() =>
LoggerProxy.logger.info(
this.executeRegistrationStep(() => this.fetchUserPreferredWebexSite(), 'fetchWebexSite'),
this.executeRegistrationStep(() => this.getGeoHint(), 'getGeoHint'),
this.executeRegistrationStep(
() =>
this.startReachability('registration').catch((error) => {
LoggerProxy.logger.error(`Meetings:index#register --> GDM error, ${error.message}`);
}),
'startReachability'
),
this.executeRegistrationStep(
() =>
// @ts-ignore
this.webex.internal.device
.register(deviceRegistrationOptions)
// @ts-ignore
`Meetings:index#register --> INFO, Device registered ${this.webex.internal.device.url}`
)
)
.then(() => {
LoggerProxy.logger.info(
// @ts-ignore
`Meetings:index#register --> INFO, Device registered ${this.webex.internal.device.url}`
);
}),
'deviceRegister'
).then(
// @ts-ignore
.then(() => this.webex.internal.mercury.connect()),
MeetingsUtil.checkH264Support.call(this),
this.executeRegistrationStep(() => this.webex.internal.mercury.connect(), 'mercuryConnect')
),
this.executeRegistrationStep(
() => Promise.resolve(MeetingsUtil.checkH264Support.call(this)),
'checkH264Support'
),
])
.then(() => {
this.listenForEvents();
Expand Down Expand Up @@ -894,6 +927,7 @@ export default class Meetings extends WebexPlugin {
EVENT_TRIGGERS.MEETINGS_UNREGISTERED
);
this.registered = false;
this.registrationStatus = clone(INITIAL_REGISTRATION_STATUS);
})
);
}
Expand Down
10 changes: 10 additions & 0 deletions packages/@webex/plugin-meetings/src/meetings/meetings.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,13 @@ export const MEETING_KEY = {
} as const;

export type MEETING_KEY = Enum<typeof MEETING_KEY>;

// finer grained status for registration steps
export type MeetingRegistrationStatus = {
fetchWebexSite: boolean;
getGeoHint: boolean;
startReachability: boolean;
deviceRegister: boolean;
mercuryConnect: boolean;
checkH264Support: boolean;
};
110 changes: 107 additions & 3 deletions packages/@webex/plugin-meetings/test/unit/spec/meetings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
LOCUSINFO,
EVENT_TRIGGERS,
DESTINATION_TYPE,
INITIAL_REGISTRATION_STATUS,
} from '../../../../src/constants';
import CaptchaError from '@webex/plugin-meetings/src/common/errors/captcha-error';
import {forEach} from 'lodash';
Expand Down Expand Up @@ -420,6 +421,100 @@ describe('plugin-meetings', () => {
includeDetails: CatalogDetails.features,
});
});

it('updates registration status as expected', async () => {
const clock = sinon.useFakeTimers();

const delay = (secs) => () =>
new Promise((resolve) => {
setTimeout(resolve, secs * 1000);
});

let i = 1;
sinon.stub(webex.meetings, 'fetchUserPreferredWebexSite').callsFake(delay(i++));
MeetingsUtil.checkH264Support.callsFake(delay(i++));
webex.meetings.startReachability.callsFake(delay(i++));
webex.internal.device.register.callsFake(delay(i++));
sinon.stub(webex.meetings, 'getGeoHint').callsFake(delay(i++));
webex.internal.mercury.connect.callsFake(delay(i++));

webex.canAuthorize = true;
webex.meetings.registered = false;

const registerPromise = webex.meetings.register({
includeDetails: CatalogDetails.features,
});

await clock.tick(1000);
await webex.meetings.fetchUserPreferredWebexSite;
assert.deepEqual(webex.meetings.registrationStatus, {
fetchWebexSite: true,
getGeoHint: false,
startReachability: false,
deviceRegister: false,
mercuryConnect: false,
checkH264Support: false,
});

await clock.tick(1000);
await MeetingsUtil.checkH264Support;
assert.deepEqual(webex.meetings.registrationStatus, {
fetchWebexSite: true,
getGeoHint: false,
startReachability: false,
deviceRegister: false,
mercuryConnect: false,
checkH264Support: true,
});

await clock.tick(1000);
await webex.meetings.startReachability;
assert.deepEqual(webex.meetings.registrationStatus, {
fetchWebexSite: true,
getGeoHint: false,
startReachability: true,
deviceRegister: false,
mercuryConnect: false,
checkH264Support: true,
});

await clock.tick(1000);
await webex.internal.device.register;
assert.deepEqual(webex.meetings.registrationStatus, {
fetchWebexSite: true,
getGeoHint: false,
startReachability: true,
deviceRegister: true,
mercuryConnect: false,
checkH264Support: true,
});

await clock.tick(1000);
await webex.meetings.getGeoHint;
assert.deepEqual(webex.meetings.registrationStatus, {
fetchWebexSite: true,
getGeoHint: true,
startReachability: true,
deviceRegister: true,
mercuryConnect: false,
checkH264Support: true,
});

await clock.tick(1000);
await webex.internal.mercury.connect;
assert.deepEqual(webex.meetings.registrationStatus, {
fetchWebexSite: true,
getGeoHint: true,
startReachability: true,
deviceRegister: true,
mercuryConnect: true,
checkH264Support: true,
});

await registerPromise;

clock.restore();
});
});

describe('#unregister', () => {
Expand Down Expand Up @@ -452,15 +547,24 @@ describe('plugin-meetings', () => {
assert.isRejected(webex.meetings.unregister());
});

it('resolves immediately if already registered', (done) => {
it('resolves immediately if not registered', (done) => {
webex.meetings.registered = false;
webex.meetings.unregister().then(() => {
assert.notCalled(webex.internal.device.register);
assert.notCalled(webex.internal.mercury.connect);
assert.notCalled(webex.internal.device.unregister);
assert.notCalled(webex.internal.mercury.disconnect);
assert.isFalse(webex.meetings.registered);
done();
});
});

it('resets registration status', (done) => {
webex.meetings.registered = true;
webex.meetings.registrationStatus = {foo: 'bar'};
webex.meetings.unregister().then(() => {
assert.deepEqual(webex.meetings.registrationStatus, INITIAL_REGISTRATION_STATUS);
done();
});
});
});

describe('virtual background effect', () => {
Expand Down

0 comments on commit 0f681f8

Please sign in to comment.