chromium/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-getRemoteStreams.html

<!DOCTYPE html>
<html>
<head>
<title>RTCPeerConnection.getRemoteStreams</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
// This is not an external/wpt/webrtc/ test because it tests APIs and behaviors
// that are not in the spec.

promise_test(async t => {
  const caller = new RTCPeerConnection();
  t.add_cleanup(() => caller.close());
  const callee = new RTCPeerConnection();
  t.add_cleanup(() => callee.close());
  return navigator.mediaDevices.getUserMedia({audio:true})
  .then((stream) => {
    caller.addStream(stream);
    return createAndSetOffer(caller, callee);
  }).then(() => {
    assert_stream_array_equals(caller.getLocalStreams(),
                               callee.getRemoteStreams(),
                               'Comparing local and remote streams.');
  });
}, 'callee.getRemoteStreams() should match caller.getLocalStreams() for ' +
   'one stream with one track.');

promise_test(async t => {
  const caller = new RTCPeerConnection();
  t.add_cleanup(() => caller.close());
  const callee = new RTCPeerConnection();
  t.add_cleanup(() => callee.close());
  return navigator.mediaDevices.getUserMedia({audio:true, video:true})
  .then((stream) => {
    caller.addStream(stream);
    return createAndSetOffer(caller, callee);
  }).then(() => {
    assert_stream_array_equals(caller.getLocalStreams(),
                               callee.getRemoteStreams(),
                               'Comparing local and remote streams.');
  });
}, 'callee.getRemoteStreams() should match caller.getLocalStreams() for ' +
   'one stream with two tracks.');

promise_test(async t => {
  const caller = new RTCPeerConnection();
  t.add_cleanup(() => caller.close());
  const callee = new RTCPeerConnection();
  t.add_cleanup(() => callee.close());
  const localStream0 =
      await navigator.mediaDevices.getUserMedia({audio:true, video:true});
  const localStream1 =
      await navigator.mediaDevices.getUserMedia({audio:true, video:true});
  caller.addStream(localStream0);
  caller.addStream(localStream1);
  // Offer both streams. The callee's remote streams updates when setting the
  // offer, we don't need to negotiate the answer for this to work.
  await caller.setLocalDescription();
  await callee.setRemoteDescription(caller.localDescription);
  assert_stream_array_equals(
      caller.getLocalStreams(), callee.getRemoteStreams(),
      'Comparing local and remote streams after adding two streams.');
  // Complete the negotiation. This makes it so that the RTCRtpSenders cannot
  // be re-cycled when we remove and then re-add the stream back later. This
  // affects the stream ordering that we assert later in this test.
  await callee.setLocalDescription();
  await caller.setRemoteDescription(callee.localDescription);
  // Remove the first stream.
  caller.removeStream(localStream0);
  await caller.setLocalDescription();
  await callee.setRemoteDescription(caller.localDescription);
  assert_stream_array_equals(
      caller.getLocalStreams(), callee.getRemoteStreams(),
      'Comparing local and remote streams after removing the first stream.');
  // Re-add the first stream. This should change the stream order, but only
  // because we cannot re-cycle the previous RTCRtpSenders.
  caller.addStream(localStream0);
  assert_stream_array_equals(caller.getLocalStreams(),
                             [ localStream1, localStream0 ]);
  await caller.setLocalDescription();
  await callee.setRemoteDescription(caller.localDescription);

  assert_stream_array_equals(
      caller.getLocalStreams(), callee.getRemoteStreams(),
      'Comparing local and remote streams after re-adding the first stream.');
}, 'callee.getRemoteStreams() should match caller.getLocalStreams() for ' +
   'a stream that is removed and re-added.');

function createAndSetOffer(caller, callee) {
  let description = null;
  return caller.createOffer()
  .then(offer => {
    description = offer;
    return caller.setLocalDescription(description);
  }).then(() => {
    return callee.setRemoteDescription(description);
  });
}

// The streams are considered equal if their IDs match. We don't care about
// track ID equality though because in Unified Plan, local and remote track IDs
// are not always guaranteed to match.
function assert_stream_equals(streamA, streamB, description) {
  assert_equals(streamA.id, streamB.id,
                description + ' The stream IDs don\'t match.');
  assert_equals(streamA.getTracks().length, streamB.getTracks().length,
                description + ' The number of tracks don\'t match.');
}

function assert_stream_array_equals(streamsA, streamsB, description) {
  assert_equals(streamsA.length, streamsB.length,
                description + ' The number of streams don\'t match.');
  for (let i = 0; i < streamsA.length; ++i) {
    assert_stream_equals(
        streamsA[i], streamsB[i],
        description + ' The ' + i + '-th streams don\'t match.');
  }
}
</script>
</body>
</html>