From eaff34c92ff1b3be9852a7df7ba7c7bf5275ea8a Mon Sep 17 00:00:00 2001 From: achingbrain Date: Tue, 16 Sep 2025 19:22:56 +0100 Subject: [PATCH] test: mixed message types should be sent in order Resolving blob content is done asynchronously so if two messages are sent synchronously where the first is a blob and the second is not a blob, the second message will get passed off to libdatachannel first. --- test/fixtures/connect.ts | 26 +++++++++++++++++++++ test/jest-tests/polyfill.test.ts | 39 ++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 test/fixtures/connect.ts diff --git a/test/fixtures/connect.ts b/test/fixtures/connect.ts new file mode 100644 index 0000000..7834813 --- /dev/null +++ b/test/fixtures/connect.ts @@ -0,0 +1,26 @@ +import { eventPromise } from './event-promise'; + +export async function connect (peer1: RTCPeerConnection, peer2: RTCPeerConnection): Promise { + const dc: RTCDataChannel = peer1.createDataChannel(''); + + // Actions + const peer1Offer = await peer1.createOffer(); + await peer2.setRemoteDescription(peer1Offer); + + const peer2Answer = await peer2.createAnswer(); + await peer1.setRemoteDescription(peer2Answer); + + peer1.addEventListener('icecandidate', (e: RTCPeerConnectionIceEvent) => { + peer2.addIceCandidate(e.candidate); + }); + + peer2.addEventListener('icecandidate', (e: RTCPeerConnectionIceEvent) => { + peer1.addIceCandidate(e.candidate); + }); + + await eventPromise(dc, 'open'); + + dc.close(); + + await eventPromise(dc, 'close'); +} diff --git a/test/jest-tests/polyfill.test.ts b/test/jest-tests/polyfill.test.ts index 77fad5b..b6f5fbb 100644 --- a/test/jest-tests/polyfill.test.ts +++ b/test/jest-tests/polyfill.test.ts @@ -3,6 +3,7 @@ import { expect, jest } from '@jest/globals'; import { RTCPeerConnection } from '../../src/polyfill/index'; import { PeerConnection } from '../../src/lib/index'; import { eventPromise } from '../fixtures/event-promise'; +import { connect } from '../fixtures/connect'; // Polyfill for Promise.withResolvers for Node < 20 if (!Promise.withResolvers) { @@ -328,4 +329,42 @@ describe('polyfill', () => { expect(spy).toHaveBeenCalled(); expect(connectionState).toEqual(originalFunc()); }); + + test('it should send mixed types in order', async () => { + const peer1 = new RTCPeerConnection(); + const peer2 = new RTCPeerConnection(); + + await connect(peer1, peer2); + + const receivedAllMessages = Promise.withResolvers(); + + peer2.ondatachannel = (evt): void => { + const channel = evt.channel; + const output = []; + + channel.onmessage = (evt): void => { + output.push(evt.data); + + if (output.length === 2) { + receivedAllMessages.resolve(output); + } + }; + }; + + const dc = peer1.createDataChannel(''); + + await eventPromise(dc, 'open'); + + dc.send(new Blob(['hello'])); + dc.send('world'); + + const messages = await receivedAllMessages.promise; + + expect(messages[0]).toBeInstanceOf(ArrayBuffer); + expect(new TextDecoder().decode(messages[0])).toEqual('hello'); + expect(messages[1]).toEqual('world'); + + peer1.close(); + peer2.close(); + }); });