mirror of
https://github.com/vector-im/element-call.git
synced 2026-10-16 23:45:50 +00:00
Delegate delayed leaves in LocalMember rather than LocalTransport
IMO this is where the delegation calls should have lived all along, since the leave event is part of the membership lifecycle, and we otherwise end up with an awkward hack to ignore transport updates. Doing this now ensures that the client won't send any delegation requests if delegation is unsupported, and prepares the code for a future change in which we use the dedicated delegation endpoint from the CS API.
This commit is contained in:
@@ -14,11 +14,8 @@ import {
|
||||
type MockedObject,
|
||||
vi,
|
||||
} from "vitest";
|
||||
import {
|
||||
type CallMembership,
|
||||
type LivekitTransportConfig,
|
||||
} from "matrix-js-sdk/lib/matrixrtc";
|
||||
import { BehaviorSubject, filter, lastValueFrom } from "rxjs";
|
||||
import { type CallMembership } from "matrix-js-sdk/lib/matrixrtc";
|
||||
import { lastValueFrom } from "rxjs";
|
||||
import fetchMock from "fetch-mock";
|
||||
|
||||
import {
|
||||
@@ -27,11 +24,7 @@ import {
|
||||
ownMemberMock,
|
||||
testScope,
|
||||
} from "../../../utils/test";
|
||||
import {
|
||||
createLocalTransport$,
|
||||
JwtEndpointVersion,
|
||||
type LocalTransportWithSFUConfig,
|
||||
} from "./LocalTransport";
|
||||
import { createLocalTransport$ } from "./LocalTransport";
|
||||
import { constant } from "../../Behavior";
|
||||
import { Epoch, ObservableScope } from "../../ObservableScope";
|
||||
import {
|
||||
@@ -62,14 +55,12 @@ describe("LocalTransport", () => {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
_unstable_getRTCTransports: async () => Promise.resolve([]),
|
||||
getDomain: () => "example.org",
|
||||
baseUrl: "example.org",
|
||||
// These won't be called in this error path but satisfy the type
|
||||
getOpenIdToken: vi.fn(),
|
||||
getDeviceId: vi.fn(),
|
||||
},
|
||||
ownMembershipIdentity: ownMemberMock,
|
||||
matrixRTCMode: MatrixRTCMode.Compatibility,
|
||||
delayId$: constant("delay_id_mock"),
|
||||
});
|
||||
await flushPromises();
|
||||
|
||||
@@ -101,7 +92,6 @@ describe("LocalTransport", () => {
|
||||
roomId: "!example_room_id",
|
||||
memberships$: constant(new Epoch<CallMembership[]>([])),
|
||||
client: {
|
||||
baseUrl: "https://example.org",
|
||||
getDomain: () => "example.org",
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
_unstable_getRTCTransports: async () => Promise.resolve([]),
|
||||
@@ -110,7 +100,6 @@ describe("LocalTransport", () => {
|
||||
},
|
||||
ownMembershipIdentity: ownMemberMock,
|
||||
matrixRTCMode: MatrixRTCMode.Compatibility,
|
||||
delayId$: constant("delay_id_mock"),
|
||||
});
|
||||
active$.subscribe(
|
||||
(o) => observations.push(o),
|
||||
@@ -148,11 +137,9 @@ describe("LocalTransport", () => {
|
||||
getDomain: () => "example.org",
|
||||
getOpenIdToken: vi.fn(),
|
||||
getDeviceId: vi.fn(),
|
||||
baseUrl: "https://example.org",
|
||||
},
|
||||
ownMembershipIdentity: ownMemberMock,
|
||||
matrixRTCMode: MatrixRTCMode.Compatibility,
|
||||
delayId$: constant("delay_id_mock"),
|
||||
});
|
||||
|
||||
openIdResolver.resolve?.({
|
||||
@@ -196,10 +183,8 @@ describe("LocalTransport", () => {
|
||||
scope: testScope(),
|
||||
roomId: "!example_room_id",
|
||||
matrixRTCMode: MatrixRTCMode.Compatibility,
|
||||
delayId$: constant(null),
|
||||
memberships$: constant(new Epoch<CallMembership[]>([])),
|
||||
client: {
|
||||
baseUrl: "https://example.org",
|
||||
getDomain: vi.fn().mockReturnValue("example.org"),
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
_unstable_getRTCTransports: vi.fn().mockResolvedValue([]),
|
||||
@@ -308,11 +293,9 @@ describe("LocalTransport", () => {
|
||||
ownMembershipIdentity: ownMemberMock,
|
||||
roomId: "!example_room_id",
|
||||
matrixRTCMode: MatrixRTCMode.Compatibility,
|
||||
delayId$: constant(null),
|
||||
memberships$: constant(new Epoch<CallMembership[]>([])),
|
||||
client: {
|
||||
getDomain: () => "example.org",
|
||||
baseUrl: "https://example.org",
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
_unstable_getRTCTransports: async () => Promise.resolve([]),
|
||||
// These won't be called in this error path but satisfy the type
|
||||
@@ -330,84 +313,4 @@ describe("LocalTransport", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("should not update advertised/active transport on delayID changes, but delay Id delegation should be called", async () => {
|
||||
// For simplicity, we'll just use the config livekit
|
||||
customLivekitUrl.setValue("https://lk.example.org");
|
||||
|
||||
const authCallSpy = vi
|
||||
.spyOn(openIDSFU, "getSFUConfigWithOpenID")
|
||||
.mockResolvedValue(openIdResponse);
|
||||
|
||||
const delayId$ = new BehaviorSubject<string | null>(null);
|
||||
|
||||
const { advertised$, active$ } = createLocalTransport$({
|
||||
scope: testScope(),
|
||||
ownMembershipIdentity: ownMemberMock,
|
||||
roomId: "!example_room_id",
|
||||
// We want multi-sdu
|
||||
forceJwtEndpoint: JwtEndpointVersion.Legacy,
|
||||
delayId$: delayId$,
|
||||
memberships$: constant(new Epoch<CallMembership[]>([])),
|
||||
client: {
|
||||
getDomain: () => "example.org",
|
||||
baseUrl: "https://example.org",
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
_unstable_getRTCTransports: async () => Promise.resolve([]),
|
||||
// These won't be called in this error path but satisfy the type
|
||||
getOpenIdToken: vi.fn(),
|
||||
getDeviceId: vi.fn(),
|
||||
},
|
||||
});
|
||||
|
||||
const advertisedValues: LivekitTransportConfig[] = [];
|
||||
const activeValues: LocalTransportWithSFUConfig[] = [];
|
||||
advertised$
|
||||
.pipe(filter((v) => v !== null))
|
||||
.subscribe((t) => advertisedValues.push(t));
|
||||
active$
|
||||
.pipe(filter((v) => v !== null))
|
||||
.subscribe((t) => activeValues.push(t));
|
||||
|
||||
await flushPromises();
|
||||
|
||||
// we have now an active and an advertised
|
||||
expect(advertisedValues.length).toEqual(1);
|
||||
expect(activeValues.length).toEqual(1);
|
||||
expect(advertisedValues[0]!.livekit_service_url).toEqual(
|
||||
"https://lk.example.org",
|
||||
);
|
||||
expect(activeValues[0]!.transport.livekit_service_url).toEqual(
|
||||
"https://lk.example.org",
|
||||
);
|
||||
|
||||
expect(authCallSpy).toHaveBeenCalledTimes(2);
|
||||
// Now emits 3 new delays id
|
||||
delayId$.next("delay_id_1");
|
||||
await flushPromises();
|
||||
delayId$.next("delay_id_2");
|
||||
await flushPromises();
|
||||
delayId$.next("delay_id_3");
|
||||
await flushPromises();
|
||||
|
||||
// No new emissions should've happened, it is the same transport.
|
||||
expect(advertisedValues.length).toEqual(1);
|
||||
expect(activeValues.length).toEqual(1);
|
||||
|
||||
// Still we should have updated the delayID to auth
|
||||
expect(authCallSpy).toHaveBeenCalledTimes(
|
||||
4 * 2 /* 2 calls for each delayId ?? why */,
|
||||
);
|
||||
|
||||
expect(authCallSpy).toHaveBeenLastCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
expect.objectContaining({
|
||||
delayId: "delay_id_3",
|
||||
}),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user