|
| 1 | +import { DataPacket, DataPacket_Kind, UserPacket } from '@livekit/protocol'; |
1 | 2 | import { afterEach, describe, expect, it, vi } from 'vitest'; |
2 | | -import RTCEngine from './RTCEngine'; |
| 3 | +import RTCEngine, { DataChannelKind } from './RTCEngine'; |
3 | 4 | import { roomOptionDefaults } from './defaults'; |
| 5 | +import { PublishDataError } from './errors'; |
4 | 6 |
|
5 | 7 | describe('RTCEngine', () => { |
6 | 8 | const originalRTCRtpSender = window.RTCRtpSender; |
@@ -218,4 +220,59 @@ describe('RTCEngine', () => { |
218 | 220 | expect((sender as unknown as { transform: unknown }).transform).toBe(transform); |
219 | 221 | expect(createEncodedStreams).not.toHaveBeenCalled(); |
220 | 222 | }); |
| 223 | + |
| 224 | + describe('sendDataPacket', () => { |
| 225 | + const MAX_DATA_PACKET_SIZE = 64 * 1024 - 1; // 65535 bytes (64 KB - 1) |
| 226 | + function stubConnectedEngine(engine: RTCEngine) { |
| 227 | + const send = vi.fn(); |
| 228 | + Object.assign(engine as unknown as Record<string, unknown>, { |
| 229 | + ensurePublisherConnected: vi.fn().mockResolvedValue(undefined), |
| 230 | + waitForBufferStatusLow: vi.fn().mockResolvedValue(undefined), |
| 231 | + updateAndEmitDCBufferStatus: vi.fn(), |
| 232 | + dataChannelForKind: vi.fn(() => ({ send })), |
| 233 | + pcManager: { |
| 234 | + getMaxPublisherMessageSize: vi.fn(() => MAX_DATA_PACKET_SIZE), |
| 235 | + }, |
| 236 | + }); |
| 237 | + return send; |
| 238 | + } |
| 239 | + |
| 240 | + it('rejects packets larger than the max data packet size', async () => { |
| 241 | + const engine = new RTCEngine(roomOptionDefaults); |
| 242 | + const send = stubConnectedEngine(engine); |
| 243 | + |
| 244 | + // The serialized packet includes protobuf framing on top of the payload, so a payload at the |
| 245 | + // limit is already guaranteed to exceed it once serialized. |
| 246 | + const packet = new DataPacket({ |
| 247 | + kind: DataPacket_Kind.RELIABLE, |
| 248 | + value: { |
| 249 | + case: 'user', |
| 250 | + value: new UserPacket({ payload: new Uint8Array(MAX_DATA_PACKET_SIZE) }), |
| 251 | + }, |
| 252 | + }); |
| 253 | + |
| 254 | + await expect(engine.sendDataPacket(packet, DataChannelKind.RELIABLE)).rejects.toBeInstanceOf( |
| 255 | + PublishDataError, |
| 256 | + ); |
| 257 | + expect(send).not.toHaveBeenCalled(); |
| 258 | + }); |
| 259 | + |
| 260 | + it('sends packets within the max data packet size', async () => { |
| 261 | + const engine = new RTCEngine(roomOptionDefaults); |
| 262 | + const send = stubConnectedEngine(engine); |
| 263 | + |
| 264 | + const packet = new DataPacket({ |
| 265 | + kind: DataPacket_Kind.RELIABLE, |
| 266 | + value: { |
| 267 | + case: 'user', |
| 268 | + value: new UserPacket({ payload: new Uint8Array(1024) }), |
| 269 | + }, |
| 270 | + }); |
| 271 | + |
| 272 | + await expect( |
| 273 | + engine.sendDataPacket(packet, DataChannelKind.RELIABLE), |
| 274 | + ).resolves.toBeUndefined(); |
| 275 | + expect(send).toHaveBeenCalledTimes(1); |
| 276 | + }); |
| 277 | + }); |
221 | 278 | }); |
0 commit comments