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

feat(plugin-meetings): Introduce SDK changes to call WCME and Locus APIs when current user steps away or returns #3942

Open
wants to merge 31 commits into
base: stepAway
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
fc570e9
feat: introduce step away in sdk and test-app
Oct 28, 2024
ac86df9
fix(plugin-meetings): added unit tests
fnowakow Oct 31, 2024
3cbb587
fix(plugin-meetings): added NOT unit test
fnowakow Oct 31, 2024
faf4a73
chore: rename functions, update wcme
Nov 4, 2024
c9dd4d3
chore: update brbChanged SelfUtils
Nov 4, 2024
48caff9
chore: update beRightBack, add todo
Nov 5, 2024
1300726
chore: add todo
Nov 5, 2024
317e1b7
fix(plugin-meetings): fix beRightBack sourceStateOverride
fnowakow Nov 7, 2024
7ec0182
fix(plugin-meetings): audio/video (un)mute fix
fnowakow Nov 7, 2024
6e1ba35
Merge branch 'antsukan/SPARK-559645' into fnowakow/SPARK-559645-unit_…
fnowakow Nov 7, 2024
4b2caf4
fix(plugin-meetings): updated tests
fnowakow Nov 7, 2024
74a1683
fix(plugin-meetings): added unit tests
fnowakow Oct 31, 2024
f7c5436
fix(plugin-meetings): added NOT unit test
fnowakow Oct 31, 2024
a92e0a8
fix(plugin-meetings): updated tests
fnowakow Nov 7, 2024
f6b8bb6
Merge remote-tracking branch 'fork/fnowakow/SPARK-559645-unit_tests' …
fnowakow Nov 7, 2024
1f2e3d2
fix(plugin-meetings): event name change to self
fnowakow Nov 7, 2024
403bf8e
chore(plugin-meetings): add todo
fnowakow Nov 7, 2024
ed9f255
chore(plugin-meetings): multistream support
fnowakow Nov 8, 2024
c956670
chore(plugin-meetings): removed multistream
fnowakow Nov 8, 2024
108d3ad
test(plugin-meetings): update brb tests
Nov 13, 2024
6ab2870
chore: nit updates for logs
Nov 13, 2024
550c66a
test(plugin-meetings): update brb test names
Nov 13, 2024
d20f826
chore: update beRightBack api logic
Nov 13, 2024
231698f
test(plugin-meetings): check brb for both multistream and transcoded
Nov 14, 2024
bd6f757
test(plugin-meetings): finalize brb tests
Nov 14, 2024
31dac59
test(plugin-meetings): remove unnecessary stub
Nov 14, 2024
1685a02
test(plugin-meetings): re-arrange test and add afterEach
Nov 14, 2024
4ca7e41
test(plugin-meetings): remove only
Nov 14, 2024
0056acf
fix(plugin-meetings): log error
Nov 14, 2024
7d58d02
fix(plugin-meetings): rever to return statement
Nov 14, 2024
88d1bb1
fix(plugin-meetings): throw and log error
Nov 15, 2024
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
4 changes: 2 additions & 2 deletions docs/samples/browser-plugin-meetings/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3337,9 +3337,9 @@ async function toggleBrb() {
const enabled = document.getElementById('brb').checked;
try {
const result = await meeting.beRightBack(enabled);
console.log(`meeting.beRightBack(${enabled}): SUCCESS | result: ${result}`);
console.log(`meeting.beRightBack(${enabled}): success. Result: ${result}`);
} catch (error) {
console.error(`meeting.beRightBack({${enabled}): ERROR`, error);
console.error(`meeting.beRightBack({${enabled}): error: `, error);
} finally {
localMedia?.microphoneStream?.setUserMuted(enabled);
localMedia?.cameraStream?.setUserMuted(enabled);
Expand Down
41 changes: 21 additions & 20 deletions packages/@webex/plugin-meetings/src/meeting/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3509,30 +3509,31 @@ export default class Meeting extends StatelessWebexPlugin {
/**
* Manages be right back status updates for the current participant.
*
* @param {boolean} enabled - Indicates whether the use is brb or not.
* @returns {Promise<void>} - A promise that resolves when the request is complete.
* @param {boolean} enabled - Indicates whether the user enabled brb or not.
* @returns {Promise<void>} resolves when the brb status is updated or does nothing if not in a multistream meeting.
* @throws {Error} - Throws an error if the request fails.
*
* @todo non-multistream support https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-578667
*/
public beRightBack(enabled: boolean) {
return this.meetingRequest
.sendBrb({
enabled,
locusUrl: this.locusUrl,
deviceUrl: this.deviceUrl,
selfId: this.selfId,
})
.then(() => {
if (this.isMultistream && this.mediaProperties.webrtcMediaConnection) {
public beRightBack(enabled: boolean): Promise<void> {
// this logic should be applied only to multistream meetings
if (this.isMultistream && this.mediaProperties.webrtcMediaConnection) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need this if statement anymore.

return this.meetingRequest
.sendBrb({
enabled,
locusUrl: this.locusUrl,
deviceUrl: this.deviceUrl,
selfId: this.selfId,
})
.then(() => {
this.sendSlotManager.setSourceStateOverride(MediaType.VideoMain, enabled ? 'away' : null);
}
})
.catch((error) => {
LoggerProxy.logger.error('Meeting:index#beRightBack --> Error ', error);
})
.catch((error) => {
LoggerProxy.logger.error('Meeting:index#beRightBack --> Error ', error);

return Promise.reject(error);
});
return Promise.reject(error);
});
}

return undefined;
edvujic marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export default class SendSlotManager {
}

this.LoggerProxy.logger.info(
`SendSlotsManager->setSourceStateOverride#set source state override to ${state}`
`SendSlotsManager->setSourceStateOverride#set source state override for ${mediaType} to ${state}`
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -739,46 +739,44 @@ describe('plugin-meetings', () => {

describe('#updateSelf', () => {
it('should trigger SELF_MEETING_BRB_CHANGED when brb state changed', () => {
locusInfo.self = undefined
locusInfo.self = undefined;

const assertBrb = (enabled) => {
const selfWithBrbChanged = cloneDeep(self);
selfWithBrbChanged.controls.brb = enabled
selfWithBrbChanged.controls.brb = enabled;

locusInfo.emitScoped = sinon.stub();
locusInfo.updateSelf(selfWithBrbChanged, [])
locusInfo.updateSelf(selfWithBrbChanged, []);

assert.calledWith(
locusInfo.emitScoped,
{ file: 'locus-info', function: 'updateSelf' },
LOCUSINFO.EVENTS.SELF_MEETING_BRB_CHANGED,
{ brb: enabled }
)
}
};

assertBrb(true)
assertBrb(false)
assertBrb(true);
assertBrb(false);
})

it('should not trigger SELF_MEETING_BRB_CHANGED when brb state changed', () => {
it('should not trigger SELF_MEETING_BRB_CHANGED when brb state did not change', () => {
const assertBrb = (enabled) => {
const selfWithBrbChanged = cloneDeep(self);
selfWithBrbChanged.controls.brb = enabled

locusInfo.self = selfWithBrbChanged
locusInfo.self = undefined;
locusInfo.emitScoped = sinon.stub();
locusInfo.updateSelf(selfWithBrbChanged, [])
locusInfo.updateSelf(undefined, []);
edvujic marked this conversation as resolved.
Show resolved Hide resolved

assert.neverCalledWith(
locusInfo.emitScoped,
{ file: 'locus-info', function: 'updateSelf' },
LOCUSINFO.EVENTS.SELF_MEETING_BRB_CHANGED,
{ brb: enabled }
)
}
};

assertBrb(true)
assertBrb(false)
assertBrb(true);
assertBrb(false);
})

it('should trigger CONTROLS_MEETING_LAYOUT_UPDATED when the meeting layout controls change', () => {
Expand Down
112 changes: 80 additions & 32 deletions packages/@webex/plugin-meetings/test/unit/spec/meeting/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3632,6 +3632,82 @@ describe('plugin-meetings', () => {
});
});

describe(`#beRightBack`, () => {
edvujic marked this conversation as resolved.
Show resolved Hide resolved
const fakeMultistreamRoapMediaConnection = {
createSendSlot: sinon.stub().returns({
setSourceStateOverride: sinon.stub().resolves(),
clearSourceStateOverride: sinon.stub().resolves(),
}),
};

beforeEach(() => {
edvujic marked this conversation as resolved.
Show resolved Hide resolved
meeting.meetingRequest.sendBrb = sinon.stub().resolves({body: 'test'});
edvujic marked this conversation as resolved.
Show resolved Hide resolved
meeting.mediaProperties.webrtcMediaConnection = {createSendSlot: sinon.stub()};
meeting.sendSlotManager.createSlot(
fakeMultistreamRoapMediaConnection,
MediaType.VideoMain
);

meeting.locusUrl = 'locus url';
meeting.deviceUrl = 'device url';
meeting.selfId = 'self id';
});

describe('when multistream meeting', () => {
edvujic marked this conversation as resolved.
Show resolved Hide resolved

beforeEach(() => {
meeting.isMultistream = true;
});

it('should have #beRightBack', () => {
assert.exists(meeting.beRightBack);
});

it('should enable #beRightBack and return a promise', async () => {
const brbResult = meeting.beRightBack(true);

await brbResult;
assert.exists(brbResult.then);
assert.calledOnce(meeting.meetingRequest.sendBrb);
})

it('should disable #beRightBack and return a promise', async () => {
const brbResult = meeting.beRightBack(false);

await brbResult;
assert.exists(brbResult.then);
assert.calledOnce(meeting.meetingRequest.sendBrb);
})
});

describe('when transcoded meeting', () => {

beforeEach(() => {
meeting.isMultistream = false;
});

it('should have #beRightBack', () => {
assert.exists(meeting.beRightBack);
});

it('should ignore enabling #beRightBack', async () => {
const brbResult = meeting.beRightBack(true);

await brbResult;
edvujic marked this conversation as resolved.
Show resolved Hide resolved
assert.isUndefined();
assert.notCalled(meeting.meetingRequest.sendBrb);
})

it('should ignore disabling #beRightBack', async () => {
const brbResult = meeting.beRightBack(false);

await brbResult;
assert.isUndefined();
assert.notCalled(meeting.meetingRequest.sendBrb);
})
});
});

/* This set of tests are like semi-integration tests, they use real MuteState, Media, LocusMediaRequest and Roap classes.
They mock the @webex/internal-media-core and sending of /media http requests to Locus.
Their main purpose is to test that we send the right http requests to Locus and make right calls
Expand Down Expand Up @@ -4714,6 +4790,7 @@ describe('plugin-meetings', () => {
});
});


[
{mute: true, title: 'user muting a track before confluence is created'},
{mute: false, title: 'user unmuting a track before confluence is created'},
Expand Down Expand Up @@ -8532,32 +8609,6 @@ describe('plugin-meetings', () => {
});
});

describe('#brb', () => {
it('send brb request', () => {
meeting.meetingRequest.locusDeltaRequest = sinon.stub().resolves();
meeting.locusUrl = 'locus url'
meeting.deviceUrl = 'device url'
meeting.selfId = 'self id'

const assertBrb = (enabled) => {
meeting.beRightBack(enabled)
assert.calledWithExactly(meeting.meetingRequest.locusDeltaRequest, {
method: HTTP_VERBS.PATCH,
uri: `${meeting.locusUrl}/${PARTICIPANT}/${meeting.selfId}/${CONTROLS}`,
body: {
brb: {
enabled,
deviceUrl: meeting.deviceUrl,
}
}
})
}

assertBrb(true)
assertBrb(false)
})
})

describe('#setUpLocusInfoSelfListener', () => {
it('listens to the self unadmitted guest event', (done) => {
meeting.startKeepAlive = sinon.stub();
Expand Down Expand Up @@ -8639,12 +8690,9 @@ describe('plugin-meetings', () => {
});

it('listens to the brb state changed event', () => {
meeting.sendSlotManager.setSourceStateOverride = sinon.stub()
meeting.mediaProperties.webrtcMediaConnection = true

const assertBrb = (enabled) => {
meeting.locusInfo.emit(
{ file: 'locus-info', function: 'updateSelf' },
{ function: 'test', file: 'test' },
LOCUSINFO.EVENTS.SELF_MEETING_BRB_CHANGED,
{ brb: { enabled } },
)
Expand All @@ -8657,8 +8705,8 @@ describe('plugin-meetings', () => {
);
}

assertBrb(true)
assertBrb(false)
assertBrb(true);
assertBrb(false);
})

it('listens to the interpretation changed event', () => {
Expand Down
Loading