<!doctype html>
<meta charset=utf-8>
<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(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(t, new 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(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.
   */
</script>
