<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>RTCRtpSender.prototype.replaceTrack</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="RTCPeerConnection-helper.js"></script>
<script>
  'use strict';

  // Test is based on the following editor draft:
  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html

  /*
    5.2.  RTCRtpSender Interface
      interface RTCRtpSender {
        readonly attribute MediaStreamTrack? track;
        Promise<void>           replaceTrack(MediaStreamTrack? withTrack);
        ...
      };

      replaceTrack
        Attempts to replace the track being sent with another track provided
        (or with a null track), without renegotiation.
   */

  /*
    5.2.  replaceTrack
      4.  If connection's [[isClosed]] slot is true, return a promise rejected
          with a newly created InvalidStateError and abort these steps.
   */
  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();

    const transceiver = pc.addTransceiver('audio');
    const { sender } = transceiver;
    pc.close();

    return promise_rejects_dom(t, 'InvalidStateError',
      sender.replaceTrack(track));
  }, 'Calling replaceTrack on closed connection should reject with InvalidStateError');

  /*
    5.2.  replaceTrack
      7.  If withTrack is non-null and withTrack.kind differs from the
          transceiver kind of transceiver, return a promise rejected with a
          newly created TypeError.
   */
  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const stream = await getNoiseStream({video: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();

    const transceiver = pc.addTransceiver('audio');
    const { sender } = transceiver;

    return promise_rejects_js(t, TypeError,
      sender.replaceTrack(track));
  }, 'Calling replaceTrack with track of different kind should reject with TypeError');

  /*
    5.2.  replaceTrack
      5.  If transceiver.stopped is true, return a promise rejected with a newly
          created InvalidStateError.
   */
  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();

    const transceiver = pc.addTransceiver('audio');
    const { sender } = transceiver;
    transceiver.stop();
    return promise_rejects_dom(t, 'InvalidStateError',
      sender.replaceTrack(track));
  }, 'Calling replaceTrack on stopped sender should reject with InvalidStateError');

  /*
    5.2.  replaceTrack
      8.  If transceiver is not yet associated with a media description [JSEP]
          (section 3.4.1.), then set sender's track attribute to withTrack, and
          return a promise resolved with undefined.
   */
  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();

    const transceiver = pc.addTransceiver('audio');
    const { sender } = transceiver;
    assert_equals(sender.track, null);

    return sender.replaceTrack(track)
    .then(() => {
      assert_equals(sender.track, track);
    });
  }, 'Calling replaceTrack on sender with null track and not set to session description should resolve with sender.track set to given track');

  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const stream1 = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream1.getTracks().forEach(track => track.stop()));
    const [track1] = stream1.getTracks();
    const stream2 = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream2.getTracks().forEach(track => track.stop()));
    const [track2] = stream2.getTracks();

    const transceiver = pc.addTransceiver(track1);
    const { sender } = transceiver;

    assert_equals(sender.track, track1);

    return sender.replaceTrack(track2)
    .then(() => {
      assert_equals(sender.track, track2);
    });
  }, 'Calling replaceTrack on sender not set to session description should resolve with sender.track set to given track');

  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();

    const transceiver = pc.addTransceiver(track);
    const { sender } = transceiver;

    assert_equals(sender.track, track);

    return sender.replaceTrack(null)
    .then(() => {
      assert_equals(sender.track, null);
    });
  }, 'Calling replaceTrack(null) on sender not set to session description should resolve with sender.track set to null');

  /*
    5.2.  replaceTrack
      10. Run the following steps in parallel:
          1.  Determine if negotiation is needed to transmit withTrack in place
              of the sender's existing track.

              Negotiation is not needed if withTrack is null.

          3.  Queue a task that runs the following steps:
              2.  Set sender's track attribute to withTrack.
   */
  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();

    const transceiver = pc.addTransceiver(track);
    const { sender } = transceiver;

    assert_equals(sender.track, track);

    return pc.createOffer()
    .then(offer => pc.setLocalDescription(offer))
    .then(() => sender.replaceTrack(null))
    .then(() => {
      assert_equals(sender.track, null);
    });
  }, 'Calling replaceTrack(null) on sender set to session description should resolve with sender.track set to null');

  /*
    5.2.  replaceTrack
      10. Run the following steps in parallel:
          1.  Determine if negotiation is needed to transmit withTrack in place
              of the sender's existing track.

              Negotiation is not needed if the sender's existing track is
              ended (which appears as though the track was muted).

          3.  Queue a task that runs the following steps:
              2.  Set sender's track attribute to withTrack.
   */
  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const stream1 = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream1.getTracks().forEach(track => track.stop()));
    const [track1] = stream1.getTracks();
    const stream2 = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream2.getTracks().forEach(track => track.stop()));
    const [track2] = stream1.getTracks();

    const transceiver = pc.addTransceiver(track1);
    const { sender } = transceiver;
    assert_equals(sender.track, track1);

    track1.stop();

    return pc.createOffer()
    .then(offer => pc.setLocalDescription(offer))
    .then(() => sender.replaceTrack(track2))
    .then(() => {
      assert_equals(sender.track, track2);
    });
  }, 'Calling replaceTrack on sender with stopped track and and set to session description should resolve with sender.track set to given track');

  /*
    5.2.  replaceTrack
      10. Run the following steps in parallel:
          1.  Determine if negotiation is needed to transmit withTrack in place
              of the sender's existing track.

              (tracks generated with default parameters *should* be similar
              enough to not require re-negotiation)

          3.  Queue a task that runs the following steps:
              2.  Set sender's track attribute to withTrack.
   */
  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const stream1 = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream1.getTracks().forEach(track => track.stop()));
    const [track1] = stream1.getTracks();
    const stream2 = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream2.getTracks().forEach(track => track.stop()));
    const [track2] = stream1.getTracks();

    const transceiver = pc.addTransceiver(track1);
    const { sender } = transceiver;
    assert_equals(sender.track, track1);

    return pc.createOffer()
    .then(offer => pc.setLocalDescription(offer))
    .then(() => sender.replaceTrack(track2))
    .then(() => {
      assert_equals(sender.track, track2);
    });
  }, 'Calling replaceTrack on sender with similar track and and set to session description should resolve with sender.track set to new track');

  /*
    TODO
      5.2.  replaceTrack
        To avoid track identifiers changing on the remote receiving end when
        a track is replaced, the sender must retain the original track
        identifier and stream associations and use these in subsequent
        negotiations.

    Non-Testable
      5.2.  replaceTrack
        10. Run the following steps in parallel:
            1.  Determine if negotiation is needed to transmit withTrack in place
                of the sender's existing track.

                Ignore which MediaStream the track resides in and the id attribute
                of the track in this determination.

                If negotiation is needed, then reject p with a newly created
                InvalidModificationError and abort these steps.

            2.  If withTrack is null, have the sender stop sending, without
                negotiating. Otherwise, have the sender switch seamlessly to
                transmitting withTrack instead of the sender's existing track,
                without negotiating.
            3.  Queue a task that runs the following steps:
              1.  If connection's [[isClosed]] slot is true, abort these steps.
  */

  promise_test(async t => {
    const v = document.createElement('video');
    v.autoplay = true;
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());
    const stream1 = await getNoiseStream({video: {signal: 20}});
    t.add_cleanup(() => stream1.getTracks().forEach(track => track.stop()));
    const [track1] = stream1.getTracks();
    const stream2 = await getNoiseStream({video: {signal: 250}});
    t.add_cleanup(() => stream2.getTracks().forEach(track => track.stop()));
    const [track2] = stream2.getTracks();
    const sender = pc1.addTrack(track1);
    pc2.ontrack = (e) => {
      v.srcObject = new MediaStream([e.track]);
    };
    const metadataToBeLoaded = new Promise((resolve) => {
      v.addEventListener('loadedmetadata', () => {
        resolve();
      });
    });
    exchangeIceCandidates(pc1, pc2);
    exchangeOfferAnswer(pc1, pc2);
    await metadataToBeLoaded;
    await detectSignal(t, v, 20);
    await sender.replaceTrack(track2);
    await detectSignal(t, v, 250);
  }, 'ReplaceTrack transmits the new track not the old track');

  promise_test(async t => {
    const v = document.createElement('video');
    v.autoplay = true;
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());
    const stream1 = await getNoiseStream({video: {signal: 20}});
    t.add_cleanup(() => stream1.getTracks().forEach(track => track.stop()));
    const [track1] = stream1.getTracks();
    const stream2 = await getNoiseStream({video: {signal: 250}});
    t.add_cleanup(() => stream2.getTracks().forEach(track => track.stop()));
    const [track2] = stream2.getTracks();
    const sender = pc1.addTrack(track1);
    pc2.ontrack = (e) => {
      v.srcObject = new MediaStream([e.track]);
    };
    const metadataToBeLoaded = new Promise((resolve) => {
      v.addEventListener('loadedmetadata', () => {
        resolve();
      });
    });
    exchangeIceCandidates(pc1, pc2);
    exchangeOfferAnswer(pc1, pc2);
    await metadataToBeLoaded;
    await detectSignal(t, v, 20);
    await sender.replaceTrack(null);
    await sender.replaceTrack(track2);
    await detectSignal(t, v, 250);
  }, 'ReplaceTrack null -> new track transmits the new track');
</script>
