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..b145138 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,101 @@ describe('polyfill', () => { expect(spy).toHaveBeenCalled(); expect(connectionState).toEqual(originalFunc()); }); + + test('it should send lots of data', async () => { + const chunkSize = 1024; + const count = 1024 * 10; + const bytes = chunkSize * count; + let received = 0; + + const peer1 = new RTCPeerConnection(); + const peer2 = new RTCPeerConnection(); + + await connect(peer1, peer2); + + const receivedAllMessages = Promise.withResolvers(); + + const incomingChannelPromise = Promise.withResolvers(); + let incomingChannel + + peer2.ondatachannel = async (evt): Promise => { + // prevent gc of channel + incomingChannelPromise.resolve(evt.channel) + incomingChannel = evt.channel; + + incomingChannel.onmessage = (evt): void => { + received += evt.data.byteLength; + + if (received === bytes) { + receivedAllMessages.resolve(); + } + } + }; + + const outgoingChannel = peer1.createDataChannel(''); + await eventPromise(outgoingChannel, 'open') + + for (let i = 0; i < count; i++) { + outgoingChannel.send(new Uint8Array(chunkSize)); + } + + outgoingChannel.close(); + + await Promise.any([ + receivedAllMessages.promise, + incomingChannelPromise.promise.then(channel => { + return eventPromise(channel, 'close') + }) + ]); + + expect(received).toEqual(bytes); + + peer1.close(); + peer2.close(); + }); + + test('it should receive lots of data', async () => { + const chunkSize = 1024; + const count = 1024 * 10; + const bytes = chunkSize * count; + + const peer1 = new RTCPeerConnection(); + const peer2 = new RTCPeerConnection(); + + await connect(peer1, peer2); + + const receivedAllMessages = Promise.withResolvers(); + + peer2.ondatachannel = async (evt): Promise => { + const channel = evt.channel; + channel.bufferedAmountLowThreshold = 0; + + for (let i = 0; i < count; i++) { + channel.send(new Uint8Array(chunkSize)); + } + + channel.close(); + }; + + const dc = peer1.createDataChannel(''); + let received = 0; + + dc.onmessage = (evt): void => { + received += evt.data.byteLength; + + if (received === bytes) { + receivedAllMessages.resolve(); + } + }; + + await Promise.any([ + receivedAllMessages.promise, + eventPromise(dc, 'close') + ]); + + expect(received).toEqual(bytes); + + peer1.close(); + peer2.close(); + }); });