Skip to content

Commit 29879e8

Browse files
committed
incorporate CallMembership changes
- rename Focus -> Transport - add RtcMembershipData (next to `sessionMembershipData`) - make `new CallMembership` initializable with both - move oldest member calculation into CallMembership Signed-off-by: Timo K <[email protected]>
1 parent ca4a9c6 commit 29879e8

15 files changed

+650
-307
lines changed

spec/unit/matrixrtc/CallMembership.spec.ts

Lines changed: 134 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
CallMembership,
2020
type SessionMembershipData,
2121
DEFAULT_EXPIRE_DURATION,
22+
type RtcMembershipData,
2223
} from "../../../src/matrixrtc/CallMembership";
2324
import { membershipTemplate } from "./mocks";
2425

@@ -44,7 +45,7 @@ describe("CallMembership", () => {
4445
scope: "m.room",
4546
application: "m.call",
4647
device_id: "AAAAAAA",
47-
focus_active: { type: "livekit" },
48+
focus_active: { type: "livekit", focus_selection: "oldest_membership" },
4849
foci_preferred: [{ type: "livekit" }],
4950
};
5051

@@ -94,11 +95,138 @@ describe("CallMembership", () => {
9495
it("returns preferred foci", () => {
9596
const fakeEvent = makeMockEvent();
9697
const mockFocus = { type: "this_is_a_mock_focus" };
97-
const membership = new CallMembership(
98-
fakeEvent,
99-
Object.assign({}, membershipTemplate, { foci_preferred: [mockFocus] }),
100-
);
101-
expect(membership.getPreferredFoci()).toEqual([mockFocus]);
98+
const membership = new CallMembership(fakeEvent, { ...membershipTemplate, foci_preferred: [mockFocus] });
99+
expect(membership.transports).toEqual([mockFocus]);
100+
});
101+
describe("getTransport", () => {
102+
const mockFocus = { type: "this_is_a_mock_focus" };
103+
const oldestMembership = new CallMembership(makeMockEvent(), membershipTemplate);
104+
it("gets the correct active transport with oldest_membership", () => {
105+
const membership = new CallMembership(makeMockEvent(), {
106+
...membershipTemplate,
107+
foci_preferred: [mockFocus],
108+
focus_active: { type: "livekit", focus_selection: "oldest_membership" },
109+
});
110+
111+
// if we are the oldest member we use our focus.
112+
expect(membership.getTransport(membership)).toStrictEqual(mockFocus);
113+
114+
// If there is an older member we use its focus.
115+
expect(membership.getTransport(oldestMembership)).toBe(membershipTemplate.foci_preferred[0]);
116+
});
117+
118+
it("does not provide focus if the selection method is unknown", () => {
119+
const membership = new CallMembership(makeMockEvent(), {
120+
...membershipTemplate,
121+
foci_preferred: [mockFocus],
122+
focus_active: { type: "livekit", focus_selection: "multi_sfu" },
123+
});
124+
125+
// if we are the oldest member we use our focus.
126+
expect(membership.getTransport(membership)).toStrictEqual(mockFocus);
127+
128+
// If there is an older member we still use our own focus in multi sfu.
129+
expect(membership.getTransport(oldestMembership)).toBe(mockFocus);
130+
});
131+
});
132+
});
133+
134+
describe("RtcMembershipData", () => {
135+
beforeEach(() => {
136+
jest.useFakeTimers();
137+
});
138+
139+
afterEach(() => {
140+
jest.useRealTimers();
141+
});
142+
143+
const membershipTemplate: RtcMembershipData = {
144+
slot_id: "m.call#1",
145+
application: { type: "m.call" },
146+
member: { user_id: "@alice:example.org", device_id: "AAAAAAA", id: "xyzHASHxyz" },
147+
rtc_transports: [{ type: "livekit" }],
148+
versions: [],
149+
};
150+
151+
it("rejects membership with no slot_id", () => {
152+
expect(() => {
153+
new CallMembership(makeMockEvent(), { ...membershipTemplate, slot_id: undefined });
154+
}).toThrow();
155+
});
156+
157+
it("rejects membership with no application", () => {
158+
expect(() => {
159+
new CallMembership(makeMockEvent(), { ...membershipTemplate, application: undefined });
160+
}).toThrow();
161+
});
162+
163+
it("rejects membership with incorrect application", () => {
164+
expect(() => {
165+
new CallMembership(makeMockEvent(), {
166+
...membershipTemplate,
167+
application: { wrong_type_key: "unknown" },
168+
});
169+
}).toThrow();
170+
});
171+
172+
it("rejects membership with no member", () => {
173+
expect(() => {
174+
new CallMembership(makeMockEvent(), { ...membershipTemplate, member: undefined });
175+
}).toThrow();
176+
});
177+
178+
it("rejects membership with incorrect member", () => {
179+
expect(() => {
180+
new CallMembership(makeMockEvent(), { ...membershipTemplate, member: { i: "test" } });
181+
}).toThrow();
182+
expect(() => {
183+
new CallMembership(makeMockEvent(), {
184+
...membershipTemplate,
185+
member: { id: "test", device_id: "test", user_id_wrong: "test" },
186+
});
187+
}).toThrow();
188+
expect(() => {
189+
new CallMembership(makeMockEvent(), {
190+
...membershipTemplate,
191+
member: { id: "test", device_id_wrong: "test", user_id_wrong: "test" },
192+
});
193+
}).toThrow();
194+
expect(() => {
195+
new CallMembership(makeMockEvent(), {
196+
...membershipTemplate,
197+
member: { id: "test", device_id: "test", user_id: "@@test" },
198+
});
199+
}).toThrow();
200+
expect(() => {
201+
new CallMembership(makeMockEvent(), {
202+
...membershipTemplate,
203+
member: { id: "test", device_id: "test", user_id: "@test:user.id" },
204+
});
205+
}).not.toThrow();
206+
});
207+
208+
it("considers memberships unexpired if local age low enough", () => {
209+
// TODO link prev event
210+
});
211+
212+
it("considers memberships expired if local age large enough", () => {
213+
// TODO link prev event
214+
});
215+
216+
describe("getTransport", () => {
217+
it("gets the correct active transport with oldest_membership", () => {
218+
const oldestMembership = new CallMembership(makeMockEvent(), {
219+
...membershipTemplate,
220+
rtc_transports: [{ type: "oldest_transport" }],
221+
});
222+
const membership = new CallMembership(makeMockEvent(), membershipTemplate);
223+
224+
// if we are the oldest member we use our focus.
225+
expect(membership.getTransport(membership)).toStrictEqual({ type: "livekit" });
226+
227+
// If there is an older member we use our own focus focus. (RtcMembershipData always uses multi sfu)
228+
expect(membership.getTransport(oldestMembership)).toStrictEqual({ type: "livekit" });
229+
});
102230
});
103231
});
104232

spec/unit/matrixrtc/LivekitFocus.spec.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,30 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import { isLivekitFocus, isLivekitFocusSelection, isLivekitFocusConfig } from "../../../src/matrixrtc/LivekitFocus";
17+
import {
18+
isLivekitTransport,
19+
isLivekitFocusSelection,
20+
isLivekitTransportConfig,
21+
} from "../../../src/matrixrtc/LivekitFocus";
1822

1923
describe("LivekitFocus", () => {
2024
it("isLivekitFocus", () => {
2125
expect(
22-
isLivekitFocus({
26+
isLivekitTransport({
2327
type: "livekit",
2428
livekit_service_url: "http://test.com",
2529
livekit_alias: "test",
2630
}),
2731
).toBeTruthy();
28-
expect(isLivekitFocus({ type: "livekit" })).toBeFalsy();
32+
expect(isLivekitTransport({ type: "livekit" })).toBeFalsy();
2933
expect(
30-
isLivekitFocus({ type: "not-livekit", livekit_service_url: "http://test.com", livekit_alias: "test" }),
34+
isLivekitTransport({ type: "not-livekit", livekit_service_url: "http://test.com", livekit_alias: "test" }),
3135
).toBeFalsy();
3236
expect(
33-
isLivekitFocus({ type: "livekit", other_service_url: "http://test.com", livekit_alias: "test" }),
37+
isLivekitTransport({ type: "livekit", other_service_url: "http://test.com", livekit_alias: "test" }),
3438
).toBeFalsy();
3539
expect(
36-
isLivekitFocus({ type: "livekit", livekit_service_url: "http://test.com", other_alias: "test" }),
40+
isLivekitTransport({ type: "livekit", livekit_service_url: "http://test.com", other_alias: "test" }),
3741
).toBeFalsy();
3842
});
3943
it("isLivekitFocusActive", () => {
@@ -48,13 +52,13 @@ describe("LivekitFocus", () => {
4852
});
4953
it("isLivekitFocusConfig", () => {
5054
expect(
51-
isLivekitFocusConfig({
55+
isLivekitTransportConfig({
5256
type: "livekit",
5357
livekit_service_url: "http://test.com",
5458
}),
5559
).toBeTruthy();
56-
expect(isLivekitFocusConfig({ type: "livekit" })).toBeFalsy();
57-
expect(isLivekitFocusConfig({ type: "not-livekit", livekit_service_url: "http://test.com" })).toBeFalsy();
58-
expect(isLivekitFocusConfig({ type: "livekit", other_service_url: "oldest_membership" })).toBeFalsy();
60+
expect(isLivekitTransportConfig({ type: "livekit" })).toBeFalsy();
61+
expect(isLivekitTransportConfig({ type: "not-livekit", livekit_service_url: "http://test.com" })).toBeFalsy();
62+
expect(isLivekitTransportConfig({ type: "livekit", other_service_url: "oldest_membership" })).toBeFalsy();
5963
});
6064
});

spec/unit/matrixrtc/MatrixRTCSession.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ describe("MatrixRTCSession", () => {
5353

5454
sess = MatrixRTCSession.sessionForRoom(client, mockRoom, callSession);
5555
expect(sess?.memberships.length).toEqual(1);
56-
expect(sess?.memberships[0].sessionDescription.id).toEqual("");
56+
expect(sess?.memberships[0].slotDescription.id).toEqual("");
5757
expect(sess?.memberships[0].scope).toEqual("m.room");
5858
expect(sess?.memberships[0].application).toEqual("m.call");
5959
expect(sess?.memberships[0].deviceId).toEqual("AAAAAAA");
6060
expect(sess?.memberships[0].isExpired()).toEqual(false);
61-
expect(sess?.sessionDescription.id).toEqual("");
61+
expect(sess?.slotDescription.id).toEqual("");
6262
});
6363

6464
it("ignores memberships where application is not m.call", () => {
@@ -268,7 +268,9 @@ describe("MatrixRTCSession", () => {
268268
type: "livekit",
269269
focus_selection: "oldest_membership",
270270
});
271-
expect(sess.resolveActiveFocus()).toBe(firstPreferredFocus);
271+
expect(sess.resolveActiveFocus(sess.memberships.find((m) => m.deviceId === "old"))).toBe(
272+
firstPreferredFocus,
273+
);
272274
jest.useRealTimers();
273275
});
274276
it("does not provide focus if the selection method is unknown", () => {
@@ -288,7 +290,7 @@ describe("MatrixRTCSession", () => {
288290
type: "livekit",
289291
focus_selection: "unknown",
290292
});
291-
expect(sess.resolveActiveFocus()).toBe(undefined);
293+
expect(sess.resolveActiveFocus(sess.memberships.find((m) => m.deviceId === "old"))).toBe(undefined);
292294
});
293295
});
294296

0 commit comments

Comments
 (0)