mirror of
https://github.com/vector-im/element-call.git
synced 2026-10-16 23:45:50 +00:00
Fix some tests
This commit is contained in:
@@ -49,11 +49,12 @@ describe("getSFUConfig", () => {
|
||||
serviceUrl: "https://sfu.example.org",
|
||||
roomId: "!example_room_id",
|
||||
slotId: "m.call#room",
|
||||
role: "subscriber",
|
||||
role: "publisher",
|
||||
logger,
|
||||
};
|
||||
});
|
||||
afterEach(() => {
|
||||
afterEach(async () => {
|
||||
void (await fetchMock.flush());
|
||||
vitest.clearAllMocks();
|
||||
fetchMock.reset();
|
||||
});
|
||||
@@ -72,7 +73,6 @@ describe("getSFUConfig", () => {
|
||||
livekitIdentity: "@me:example.org:ABCDEF",
|
||||
livekitAlias: "!example_room_id",
|
||||
});
|
||||
void (await fetchMock.flush());
|
||||
});
|
||||
|
||||
it("should fail if the SFU errors", async () => {
|
||||
@@ -95,7 +95,6 @@ describe("getSFUConfig", () => {
|
||||
"MatrixError: [500] Failed to look up user info from homeserver",
|
||||
);
|
||||
|
||||
void (await fetchMock.flush());
|
||||
return;
|
||||
}
|
||||
expect.fail("Expected test to throw;");
|
||||
@@ -137,7 +136,6 @@ describe("getSFUConfig", () => {
|
||||
|
||||
expect(config.jwt).toBe(testJWTToken);
|
||||
expect(callCount).toBe(2);
|
||||
void (await fetchMock.flush());
|
||||
});
|
||||
|
||||
it("should successfully send delay parameters to the JWT service legacy endpoint", async () => {
|
||||
@@ -150,7 +148,7 @@ describe("getSFUConfig", () => {
|
||||
if (
|
||||
body.delay_id === "mock_delay_id" &&
|
||||
body.delay_timeout === 3600000 &&
|
||||
body.delay_cs_api_url === "https://homeserverserver.org/cs_api"
|
||||
body.delay_cs_api_url === "https://matrix.homeserverserver.org"
|
||||
) {
|
||||
return {
|
||||
status: 200,
|
||||
@@ -172,98 +170,6 @@ describe("getSFUConfig", () => {
|
||||
jwt: testJWTToken,
|
||||
url: serviceUrl,
|
||||
});
|
||||
|
||||
void (await fetchMock.flush());
|
||||
});
|
||||
|
||||
it("should try legacy and then new endpoint with delay delegation", async () => {
|
||||
fetchMock.post("https://sfu.example.org/get_token", () => {
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
errcode: "M_LOOKUP_FAILED",
|
||||
error: "Failed to look up user info from homeserver",
|
||||
},
|
||||
};
|
||||
});
|
||||
fetchMock.post("https://sfu.example.org/sfu/get", () => {
|
||||
return {
|
||||
status: 500,
|
||||
body: {
|
||||
errcode: "M_LOOKUP_FAILED",
|
||||
error: "Failed to look up user info from homeserver",
|
||||
},
|
||||
};
|
||||
});
|
||||
try {
|
||||
await getSFUConfig({ ...params, ...delayParams });
|
||||
} catch (ex) {
|
||||
expect(ex).toBeInstanceOf(FailToGetOpenIdToken);
|
||||
expect((ex as FailToGetOpenIdToken).cause).toBeInstanceOf(MatrixError);
|
||||
const mxError = (ex as Error).cause as MatrixError;
|
||||
expect(mxError.message).toEqual(
|
||||
"MatrixError: [500] Failed to look up user info from homeserver",
|
||||
);
|
||||
void (await fetchMock.flush());
|
||||
}
|
||||
const calls = fetchMock.calls();
|
||||
expect(calls.length).toBe(2);
|
||||
|
||||
expect(calls[0][0]).toStrictEqual("https://sfu.example.org/get_token");
|
||||
expect(calls[0][1]).toStrictEqual({
|
||||
// check if it uses correct delayID!
|
||||
body: '{"room_id":"!example_room_id","slot_id":"m.call#ROOM","member":{"id":"@alice:example.org:DEVICE","claimed_user_id":"@alice:example.org","claimed_device_id":"DEVICE"},"delay_id":"mock_delay_id","delay_timeout":3600000,"delay_cs_api_url":"https://matrix.homeserverserver.org"}',
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
expect(calls[1][0]).toStrictEqual("https://sfu.example.org/sfu/get");
|
||||
|
||||
expect(calls[1][1]).toStrictEqual({
|
||||
body: '{"room":"!example_room_id","device_id":"DEVICE","delay_id":"mock_delay_id","delay_timeout":3600000,"delay_cs_api_url":"https://matrix.homeserverserver.org"}',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "POST",
|
||||
});
|
||||
});
|
||||
|
||||
it("dont try legacy if endpoint with delay delegation is sucessful", async () => {
|
||||
fetchMock.post("https://sfu.example.org/get_token", () => {
|
||||
return {
|
||||
status: 200,
|
||||
body: { url: serviceUrl, jwt: testJWTToken },
|
||||
};
|
||||
});
|
||||
fetchMock.post("https://sfu.example.org/sfu/get", () => {
|
||||
return {
|
||||
status: 500,
|
||||
body: { error: "Test failure" },
|
||||
};
|
||||
});
|
||||
try {
|
||||
await getSFUConfig({ ...params, ...delayParams });
|
||||
} catch (ex) {
|
||||
expect(ex).toBeInstanceOf(FailToGetOpenIdToken);
|
||||
expect((ex as FailToGetOpenIdToken).cause).toEqual(
|
||||
new Error("SFU Config fetch failed with status code 500"),
|
||||
);
|
||||
void (await fetchMock.flush());
|
||||
}
|
||||
const calls = fetchMock.calls();
|
||||
expect(calls.length).toBe(1);
|
||||
|
||||
expect(calls[0][0]).toStrictEqual("https://sfu.example.org/get_token");
|
||||
expect(calls[0][1]).toStrictEqual({
|
||||
// check if it uses correct delayID!
|
||||
body: '{"room_id":"!example_room_id","slot_id":"m.call#ROOM","member":{"id":"@alice:example.org:DEVICE","claimed_user_id":"@alice:example.org","claimed_device_id":"DEVICE"},"delay_id":"mock_delay_id","delay_timeout":3600000,"delay_cs_api_url":"https://matrix.homeserverserver.org"}',
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should retry fetching the openid token", async () => {
|
||||
@@ -293,6 +199,5 @@ describe("getSFUConfig", () => {
|
||||
livekitIdentity: "@me:example.org:ABCDEF",
|
||||
livekitAlias: "!example_room_id",
|
||||
});
|
||||
void (await fetchMock.flush());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -148,6 +148,7 @@ describe("DeveloperSettingsTab", () => {
|
||||
getCrypto: () => ({ getVersion: (): string => "x" }),
|
||||
getUserId: () => "@u:hs",
|
||||
getDeviceId: () => "DEVICE",
|
||||
getDomain: () => "hs",
|
||||
} as unknown as MatrixClient;
|
||||
it("will not update custom transport without roomId", async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
@@ -742,9 +742,12 @@ export function createCallViewModel$(
|
||||
return combineLatest(
|
||||
connections.map((connection) =>
|
||||
remoteMatrixLivekitMembers$.pipe(
|
||||
switchMap((members) =>
|
||||
combineLatest(members.value.map((m) => m.participant.value$)),
|
||||
),
|
||||
switchMap((members) => {
|
||||
if (members.value.length === 0) return of([]);
|
||||
return combineLatest(
|
||||
members.value.map((m) => m.participant.value$),
|
||||
);
|
||||
}),
|
||||
map((participants) => ({
|
||||
url: JSON.stringify(connection.transport), // TODO
|
||||
livekitRoom: connection.livekitRoom,
|
||||
|
||||
@@ -122,6 +122,8 @@ export function withCallViewModel(mode: MatrixRTCMode) {
|
||||
};
|
||||
const room = mockMatrixRoom({
|
||||
client: new (class extends EventEmitter {
|
||||
public readonly baseUrl = "https://matrix.example.com";
|
||||
|
||||
public getUserId(): string | undefined {
|
||||
return localRtcMember.userId;
|
||||
}
|
||||
|
||||
@@ -337,6 +337,7 @@ describe("LocalMembership", () => {
|
||||
}),
|
||||
state$: constant(ConnectionState.LivekitConnected),
|
||||
transport: mockTransport,
|
||||
serverName: "example.org",
|
||||
} as Connection;
|
||||
const connectionTransportAConnecting = {
|
||||
...connectionTransportAConnected,
|
||||
@@ -858,6 +859,7 @@ describe("LocalMembership", () => {
|
||||
const connection = {
|
||||
state$: constant(ConnectionState.LivekitConnected),
|
||||
transport: mockTransport,
|
||||
serverName: "example.org",
|
||||
livekitRoom: mockLivekitRoom({
|
||||
localParticipant: mockLocalParticipant({
|
||||
isScreenShareEnabled: false,
|
||||
|
||||
@@ -46,8 +46,11 @@ describe("LocalTransport", () => {
|
||||
getDomain: () => "example.org",
|
||||
}),
|
||||
).toStrictEqual({
|
||||
livekit_service_url: "https://lk.example.org",
|
||||
type: "livekit",
|
||||
transport: {
|
||||
livekit_service_url: "https://lk.example.org",
|
||||
type: "livekit",
|
||||
},
|
||||
serverName: "example.org",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -74,8 +77,11 @@ describe("LocalTransport", () => {
|
||||
});
|
||||
|
||||
expect(await getLocalTransport(client)).toStrictEqual({
|
||||
livekit_service_url: "https://lk.example.org",
|
||||
type: "livekit",
|
||||
transport: {
|
||||
livekit_service_url: "https://lk.example.org",
|
||||
type: "livekit",
|
||||
},
|
||||
serverName: "example.org",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -86,8 +92,11 @@ describe("LocalTransport", () => {
|
||||
});
|
||||
|
||||
expect(await getLocalTransport(client)).toStrictEqual({
|
||||
livekit_service_url: "https://lk.example.org",
|
||||
type: "livekit",
|
||||
transport: {
|
||||
livekit_service_url: "https://lk.example.org",
|
||||
type: "livekit",
|
||||
},
|
||||
serverName: "example.org",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -97,8 +106,11 @@ describe("LocalTransport", () => {
|
||||
]);
|
||||
|
||||
expect(await getLocalTransport(client)).toStrictEqual({
|
||||
livekit_service_url: "https://lk.example.org",
|
||||
type: "livekit",
|
||||
transport: {
|
||||
livekit_service_url: "https://lk.example.org",
|
||||
type: "livekit",
|
||||
},
|
||||
serverName: "example.org",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -28,9 +28,12 @@ import {
|
||||
} from "livekit-client";
|
||||
import fetchMock from "fetch-mock";
|
||||
import EventEmitter from "events";
|
||||
import { MatrixError, type IOpenIDToken } from "matrix-js-sdk";
|
||||
import { MatrixError } from "matrix-js-sdk";
|
||||
import { logger, type Logger } from "matrix-js-sdk/lib/logger";
|
||||
import { type UnstableLivekitTransport } from "matrix-js-sdk/lib/matrixrtc";
|
||||
import {
|
||||
type LivekitGetTokenResponse,
|
||||
type UnstableLivekitTransport,
|
||||
} from "matrix-js-sdk/lib/matrixrtc";
|
||||
|
||||
import {
|
||||
Connection,
|
||||
@@ -185,7 +188,7 @@ describe("Start connection states", () => {
|
||||
expect(connection.state$.getValue()).toEqual("Initialized");
|
||||
});
|
||||
|
||||
it("fail to getOpenId token then error state", async () => {
|
||||
it("fail to get SFU token then error state", async () => {
|
||||
setupTest();
|
||||
vi.useFakeTimers();
|
||||
|
||||
@@ -209,10 +212,10 @@ describe("Start connection states", () => {
|
||||
});
|
||||
onTestFinished(() => s.unsubscribe());
|
||||
|
||||
const deferred = Promise.withResolvers<IOpenIDToken>();
|
||||
const deferred = Promise.withResolvers<LivekitGetTokenResponse>();
|
||||
|
||||
client.getOpenIdToken.mockImplementation(
|
||||
async (): Promise<IOpenIDToken> => {
|
||||
client._unstable_getLivekitToken.mockImplementation(
|
||||
async (): Promise<LivekitGetTokenResponse> => {
|
||||
return await deferred.promise;
|
||||
},
|
||||
);
|
||||
|
||||
@@ -54,9 +54,15 @@ beforeEach(() => {
|
||||
vi.mocked(fakeConnectionFactory).createConnection = vi
|
||||
.fn()
|
||||
.mockImplementation(
|
||||
(scope: ObservableScope, transport: UnstableLivekitTransport) => {
|
||||
(
|
||||
scope: ObservableScope,
|
||||
_role: unknown,
|
||||
transport: UnstableLivekitTransport,
|
||||
serverName: string,
|
||||
) => {
|
||||
const mockConnection = {
|
||||
transport,
|
||||
serverName,
|
||||
remoteParticipants$: new BehaviorSubject([]),
|
||||
} as unknown as Connection;
|
||||
vi.mocked(mockConnection).start = vi.fn();
|
||||
@@ -229,14 +235,14 @@ describe("ConnectionManagerData", () => {
|
||||
test("warns when a second connection to the same URL is merged", () => {
|
||||
const warn = vi.spyOn(logger, "warn").mockImplementation(() => {});
|
||||
const data = new ConnectionManagerData(logger);
|
||||
const connection = { transport: TRANSPORT_1 } as unknown as Connection;
|
||||
const connection = TRANSPORT_1 as unknown as Connection;
|
||||
const p = (identity: string): RemoteParticipant =>
|
||||
({ identity }) as unknown as RemoteParticipant;
|
||||
data.add(connection, [p("a")]);
|
||||
data.add({ ...connection } as Connection, [p("b")]);
|
||||
expect(warn).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
"second connection to https://lk.example.org: existing [a], adding [b]",
|
||||
'second connection to [null,"https://lk.example.org","example.org"]: existing [a], adding [b]',
|
||||
),
|
||||
);
|
||||
expect(data.getParticipantsForTransport(TRANSPORT_1)).toHaveLength(2);
|
||||
@@ -247,12 +253,14 @@ describe("connectionManagerData$ stream", () => {
|
||||
// Used in test to control fake connections' remoteParticipants$ streams
|
||||
let fakeRemoteParticipantsStreams: Map<string, Behavior<RemoteParticipant[]>>;
|
||||
|
||||
function keyForTransport(transport: UnstableLivekitTransport): string {
|
||||
function keyForTransport({
|
||||
transport,
|
||||
serverName,
|
||||
}: TransportLocator): string {
|
||||
return JSON.stringify([
|
||||
"url" in transport ? transport.url : undefined,
|
||||
"livekit_service_url" in transport
|
||||
? transport.livekit_service_url
|
||||
: undefined,
|
||||
"url" in transport ? transport.url : null,
|
||||
"livekit_service_url" in transport ? transport.livekit_service_url : null,
|
||||
serverName,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -260,7 +268,7 @@ describe("connectionManagerData$ stream", () => {
|
||||
fakeRemoteParticipantsStreams = new Map();
|
||||
|
||||
function getRemoteParticipantsFor(
|
||||
transport: UnstableLivekitTransport,
|
||||
transport: TransportLocator,
|
||||
): Behavior<RemoteParticipant[]> {
|
||||
return (
|
||||
fakeRemoteParticipantsStreams.get(keyForTransport(transport)) ??
|
||||
@@ -272,13 +280,22 @@ describe("connectionManagerData$ stream", () => {
|
||||
vi.mocked(fakeConnectionFactory).createConnection = vi
|
||||
.fn()
|
||||
.mockImplementation(
|
||||
(scope: ObservableScope, transport: UnstableLivekitTransport) => {
|
||||
(
|
||||
scope: ObservableScope,
|
||||
_role: unknown,
|
||||
transport: UnstableLivekitTransport,
|
||||
serverName: string,
|
||||
) => {
|
||||
const fakeRemoteParticipants$ = new BehaviorSubject<
|
||||
RemoteParticipant[]
|
||||
>([]);
|
||||
const mockConnection = {
|
||||
transport,
|
||||
remoteParticipants$: getRemoteParticipantsFor(transport),
|
||||
serverName,
|
||||
remoteParticipants$: getRemoteParticipantsFor({
|
||||
transport,
|
||||
serverName,
|
||||
}),
|
||||
} as unknown as Connection;
|
||||
vi.mocked(mockConnection).start = vi.fn();
|
||||
vi.mocked(mockConnection).stop = vi.fn();
|
||||
@@ -288,7 +305,7 @@ describe("connectionManagerData$ stream", () => {
|
||||
});
|
||||
|
||||
fakeRemoteParticipantsStreams.set(
|
||||
keyForTransport(transport),
|
||||
keyForTransport({ transport, serverName }),
|
||||
fakeRemoteParticipants$,
|
||||
);
|
||||
return mockConnection;
|
||||
@@ -301,7 +318,7 @@ describe("connectionManagerData$ stream", () => {
|
||||
// Setup the fake participants streams behavior
|
||||
// ==============================
|
||||
fakeRemoteParticipantsStreams.set(
|
||||
keyForTransport(TRANSPORT_1.transport),
|
||||
keyForTransport(TRANSPORT_1),
|
||||
behavior("oa-b", {
|
||||
o: [],
|
||||
a: [{ identity: "user1A" } as RemoteParticipant],
|
||||
@@ -313,7 +330,7 @@ describe("connectionManagerData$ stream", () => {
|
||||
);
|
||||
|
||||
fakeRemoteParticipantsStreams.set(
|
||||
keyForTransport(TRANSPORT_2.transport),
|
||||
keyForTransport(TRANSPORT_2),
|
||||
behavior("o-a", {
|
||||
o: [],
|
||||
a: [{ identity: "user2A" } as RemoteParticipant],
|
||||
|
||||
@@ -50,10 +50,8 @@ export class ConnectionManagerData {
|
||||
// This is enough as a key because the ConnectionManager is already scoped by room.
|
||||
// We also do not need to consider the slotId at this point since each `MatrixRTCSession` is already scoped by `slotDescription: {id, application}`.
|
||||
return JSON.stringify([
|
||||
"url" in transport ? transport.url : undefined,
|
||||
"livekit_service_url" in transport
|
||||
? transport.livekit_service_url
|
||||
: undefined,
|
||||
"url" in transport ? transport.url : null,
|
||||
"livekit_service_url" in transport ? transport.livekit_service_url : null,
|
||||
serverName,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -142,6 +142,7 @@ test("should signal participant on a connection that is publishing", async () =>
|
||||
|
||||
const connection = {
|
||||
transport: bobMembership.getTransport(),
|
||||
serverName: "example.org",
|
||||
} as unknown as Connection;
|
||||
const dataWithPublisher = new ConnectionManagerData();
|
||||
dataWithPublisher.add(connection, [
|
||||
@@ -185,6 +186,7 @@ test("should signal participant on a connection that is not publishing", async (
|
||||
|
||||
const connection = {
|
||||
transport: bobMembership.getTransport(),
|
||||
serverName: "example.org",
|
||||
} as unknown as Connection;
|
||||
const dataWithPublisher = new ConnectionManagerData();
|
||||
dataWithPublisher.add(connection, []);
|
||||
@@ -226,9 +228,11 @@ describe("Publication edge case", () => {
|
||||
);
|
||||
const connectionA = {
|
||||
transport: transportA,
|
||||
serverName: "example.org",
|
||||
} as unknown as Connection;
|
||||
const connectionB = {
|
||||
transport: transportB,
|
||||
serverName: "sample.com",
|
||||
} as unknown as Connection;
|
||||
|
||||
connectionWithPublisher.add(connectionA, [
|
||||
@@ -284,8 +288,14 @@ test("bob is publishing in the wrong connection", async () => {
|
||||
bobMembership.userId,
|
||||
bobMembership.deviceId,
|
||||
);
|
||||
const connectionA = { transport: transportA } as unknown as Connection;
|
||||
const connectionB = { transport: transportB } as unknown as Connection;
|
||||
const connectionA = {
|
||||
transport: transportA,
|
||||
serverName: "example.org",
|
||||
} as unknown as Connection;
|
||||
const connectionB = {
|
||||
transport: transportB,
|
||||
serverName: "sample.com",
|
||||
} as unknown as Connection;
|
||||
|
||||
// Bob is not publishing on A
|
||||
connectionWithPublisher.add(connectionA, []);
|
||||
|
||||
@@ -69,7 +69,7 @@ export function getBasicRTCSession(
|
||||
getUserId: () => localRtcMember.userId,
|
||||
getDeviceId: () => localRtcMember.deviceId,
|
||||
getSyncState: () => SyncState.Syncing,
|
||||
getDomain: () => null,
|
||||
getDomain: () => "example.com",
|
||||
getAccessToken: () => "fake-token",
|
||||
sendEvent: vitest.fn().mockResolvedValue({ event_id: "$fake:event" }),
|
||||
redactEvent: vitest.fn().mockResolvedValue({ event_id: "$fake:event" }),
|
||||
|
||||
Reference in New Issue
Block a user