Use hot marbles for speaker tests (#2815)

* Refactor the speaker detection logic into observeSpeaker and add tests

@robintown the tests pass, but some of the values were off by 1ms from what I was expecting. Please can you sanity check them?

* Extra test cases and clean up

* Make distinctUntilChanged part of the observable itself

* More suggestions from code review

* Use hot marbles for speaker tests

This was originally part of https://github.com/element-hq/element-call/pull/2810

* Only feed speaking mocks to observables that ask for IsSpeakingChanged
This commit is contained in:
Hugh Nimmo-Smith 2024-11-23 08:59:33 +00:00 committed by GitHub
parent 4e1b4fae19
commit fc8da6ef58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -20,6 +20,7 @@ import {
ConnectionState, ConnectionState,
LocalParticipant, LocalParticipant,
Participant, Participant,
ParticipantEvent,
RemoteParticipant, RemoteParticipant,
} from "livekit-client"; } from "livekit-client";
import * as ComponentsCore from "@livekit/components-core"; import * as ComponentsCore from "@livekit/components-core";
@ -188,11 +189,15 @@ function withCallViewModel(
); );
const eventsSpy = vi const eventsSpy = vi
.spyOn(ComponentsCore, "observeParticipantEvents") .spyOn(ComponentsCore, "observeParticipantEvents")
.mockImplementation((p) => .mockImplementation((p, ...eventTypes) => {
(speaking.get(p) ?? of(false)).pipe( if (eventTypes.includes(ParticipantEvent.IsSpeakingChanged)) {
map((s) => ({ ...p, isSpeaking: s }) as Participant), return (speaking.get(p) ?? of(false)).pipe(
), map((s) => ({ ...p, isSpeaking: s }) as Participant),
); );
} else {
return of(p);
}
});
const roomEventSelectorSpy = vi const roomEventSelectorSpy = vi
.spyOn(ComponentsCore, "roomEventSelector") .spyOn(ComponentsCore, "roomEventSelector")
@ -407,7 +412,7 @@ test("participants stay in the same order unless to appear/disappear", () => {
}); });
test("spotlight speakers swap places", () => { test("spotlight speakers swap places", () => {
withTestScheduler(({ cold, schedule, expectObservable }) => { withTestScheduler(({ hot, schedule, expectObservable }) => {
// Go immediately into spotlight mode for the test // Go immediately into spotlight mode for the test
const modeInputMarbles = " s"; const modeInputMarbles = " s";
// First Bob speaks, then Dave, then Alice // First Bob speaks, then Dave, then Alice
@ -424,9 +429,9 @@ test("spotlight speakers swap places", () => {
of([aliceParticipant, bobParticipant, daveParticipant]), of([aliceParticipant, bobParticipant, daveParticipant]),
of(ConnectionState.Connected), of(ConnectionState.Connected),
new Map([ new Map([
[aliceParticipant, cold(aSpeakingInputMarbles, { y: true, n: false })], [aliceParticipant, hot(aSpeakingInputMarbles, { y: true, n: false })],
[bobParticipant, cold(bSpeakingInputMarbles, { y: true, n: false })], [bobParticipant, hot(bSpeakingInputMarbles, { y: true, n: false })],
[daveParticipant, cold(dSpeakingInputMarbles, { y: true, n: false })], [daveParticipant, hot(dSpeakingInputMarbles, { y: true, n: false })],
]), ]),
(vm) => { (vm) => {
schedule(modeInputMarbles, { s: () => vm.setGridMode("spotlight") }); schedule(modeInputMarbles, { s: () => vm.setGridMode("spotlight") });