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