From 6480df44e9c4706b6b49ba723b2e70233bb00eea Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 7 Jan 2026 15:10:24 +0100 Subject: [PATCH] add tests for open id delay fallback --- src/livekit/openIDSFU.test.ts | 99 +++++++++++++++++++ .../MatrixLivekitMembers.test.ts | 16 ++- src/utils/test.ts | 3 +- 3 files changed, 106 insertions(+), 12 deletions(-) diff --git a/src/livekit/openIDSFU.test.ts b/src/livekit/openIDSFU.test.ts index 8b263662..22e487f5 100644 --- a/src/livekit/openIDSFU.test.ts +++ b/src/livekit/openIDSFU.test.ts @@ -34,6 +34,7 @@ describe("getSFUConfigWithOpenID", () => { vitest.clearAllMocks(); fetchMock.reset(); }); + it("should handle fetching a token", async () => { fetchMock.post("https://sfu.example.org/sfu/get", () => { return { @@ -56,6 +57,7 @@ describe("getSFUConfigWithOpenID", () => { }); void (await fetchMock.flush()); }); + it("should fail if the SFU errors", async () => { fetchMock.post("https://sfu.example.org/sfu/get", () => { return { @@ -81,6 +83,103 @@ describe("getSFUConfigWithOpenID", () => { expect.fail("Expected test to throw;"); }); + it("should try legacy and then new endpoint with delay delegation", async () => { + fetchMock.post("https://sfu.example.org/get_token", () => { + return { + status: 500, + body: { error: "Test failure" }, + }; + }); + fetchMock.post("https://sfu.example.org/sfu/get", () => { + return { + status: 500, + body: { error: "Test failure" }, + }; + }); + try { + await getSFUConfigWithOpenID( + matrixClient, + ownMemberMock, + "https://sfu.example.org", + false, + "!example_room_id", + "https://matrix.homeserverserver.org", + "mock_delay_id", + ); + } catch (ex) { + logger.info(ex); + expect(((ex as Error).cause as Error).message).toEqual( + "SFU Config fetch failed with status code 500", + ); + 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":1000,"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"}', + 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: sfuUrl, jwt: testJWTToken }, + }; + }); + fetchMock.post("https://sfu.example.org/sfu/get", () => { + return { + status: 500, + body: { error: "Test failure" }, + }; + }); + try { + await getSFUConfigWithOpenID( + matrixClient, + ownMemberMock, + "https://sfu.example.org", + false, + "!example_room_id", + "https://matrix.homeserverserver.org", + "mock_delay_id", + ); + } catch (ex) { + expect(((ex as Error).cause as Error).message).toEqual( + "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":1000,"delay_cs_api_url":"https://matrix.homeserverserver.org"}', + method: "POST", + headers: { + "Content-Type": "application/json", + }, + }); + }); + it("should retry fetching the openid token", async () => { let count = 0; matrixClient.getOpenIdToken.mockImplementation(async () => { diff --git a/src/state/CallViewModel/remoteMembers/MatrixLivekitMembers.test.ts b/src/state/CallViewModel/remoteMembers/MatrixLivekitMembers.test.ts index 55549a10..5d34f7be 100644 --- a/src/state/CallViewModel/remoteMembers/MatrixLivekitMembers.test.ts +++ b/src/state/CallViewModel/remoteMembers/MatrixLivekitMembers.test.ts @@ -49,16 +49,12 @@ const transportB: LivekitTransport = { livekit_alias: "!alias:sample.com", }; -const bobMembership = mockRtcMembership( - "@bob:example.org", - "DEV000", - transportA, -); -const carlMembership = mockRtcMembership( - "@carl:sample.com", - "DEV111", - transportB, -); +const bobMembership = mockRtcMembership("@bob:example.org", "DEV000", { + fociPreferred: [transportA], +}); +const carlMembership = mockRtcMembership("@carl:sample.com", "DEV111", { + fociPreferred: [transportB], +}); beforeEach(() => { testScope = new ObservableScope(); diff --git a/src/utils/test.ts b/src/utils/test.ts index b19ea961..d24ad130 100644 --- a/src/utils/test.ts +++ b/src/utils/test.ts @@ -15,7 +15,6 @@ import { vitest, } from "vitest"; import { - encodeUnpaddedBase64, MatrixEvent, type Room as MatrixRoom, type Room, @@ -44,7 +43,7 @@ import { type Room as LivekitRoom, Track, } from "livekit-client"; -import { createHash, randomUUID } from "crypto"; +import { randomUUID } from "crypto"; import { type TrackReference } from "@livekit/components-core"; import EventEmitter from "events"; import {