<!doctype html>
<meta charset=utf-8>
<title>RTCPeerConnection.prototype.removeTrack</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

  // The following helper functions are called from RTCPeerConnection-helper.js:
  // generateAnswer

  /*
    5.1.  RTCPeerConnection Interface Extensions
      partial interface RTCPeerConnection {
        ...
        void                removeTrack(RTCRtpSender sender);
        RTCRtpTransceiver   addTransceiver((MediaStreamTrack or DOMString) trackOrKind,
                                                   optional RTCRtpTransceiverInit init);
      };
   */

  // Before calling removeTrack can be tested, one needs to add MediaStreamTracks to
  // a peer connection. There are two ways for adding MediaStreamTrack: addTrack and
  // addTransceiver. addTransceiver is a newer API while addTrack has been implemented
  // in current browsers for some time. As a result some of the removeTrack tests have
  // two versions so that removeTrack can be partially tested without addTransceiver
  // and the transceiver APIs being implemented.

  /*
    5.1.  removeTrack
      3.  If connection's [[isClosed]] slot is true, throw an InvalidStateError.
   */
  promise_test(async t => {
    const pc = new RTCPeerConnection();
    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;

    pc.close();
    assert_throws_dom('InvalidStateError', () => pc.removeTrack(sender));
  }, 'addTransceiver - Calling removeTrack when connection is closed should throw 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 sender = pc.addTrack(track, stream);

    pc.close();
    assert_throws_dom('InvalidStateError', () => pc.removeTrack(sender));
  }, 'addTrack - Calling removeTrack when connection is closed should throw 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(track);
    const { sender } = transceiver;

    const pc2 = new RTCPeerConnection();
    pc2.close();
    assert_throws_dom('InvalidStateError', () => pc2.removeTrack(sender));
  }, 'addTransceiver - Calling removeTrack on different connection that is closed should throw 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 sender = pc.addTrack(track, stream);

    const pc2 = new RTCPeerConnection();
    pc2.close();
    assert_throws_dom('InvalidStateError', () => pc2.removeTrack(sender));
  }, 'addTrack - Calling removeTrack on different connection that is closed should throw InvalidStateError');

  /*
    5.1.  removeTrack
      4.  If sender was not created by connection, throw an InvalidAccessError.
   */
  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;

    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());
    assert_throws_dom('InvalidAccessError', () => pc2.removeTrack(sender));
  }, 'addTransceiver - Calling removeTrack on different connection should throw InvalidAccessError');

  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 sender = pc.addTrack(track, stream);

    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());
    assert_throws_dom('InvalidAccessError', () => pc2.removeTrack(sender));
  }, 'addTrack - Calling removeTrack on different connection should throw InvalidAccessError')

  /*
    5.1.  removeTrack
      7.  Set sender.track to null.
   */
  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);
    assert_equals(transceiver.direction, 'sendrecv');
    assert_equals(transceiver.currentDirection, null);

    pc.removeTrack(sender);
    assert_equals(sender.track, null);
    assert_equals(transceiver.direction, 'recvonly');
  }, 'addTransceiver - Calling removeTrack with valid sender should set sender.track to null');

  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 sender = pc.addTrack(track, stream);

    assert_equals(sender.track, track);

    pc.removeTrack(sender);
    assert_equals(sender.track, null);
  }, 'addTrack - Calling removeTrack with valid sender should set sender.track to null');

  /*
    5.1.  removeTrack
      7.  Set sender.track to null.
      10. If transceiver.currentDirection is sendrecv set transceiver.direction
          to recvonly.
   */
  promise_test(async t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();
    const transceiver = caller.addTransceiver(track);
    const { sender } = transceiver;

    assert_equals(sender.track, track);
    assert_equals(transceiver.direction, 'sendrecv');
    assert_equals(transceiver.currentDirection, null);

    const offer = await caller.createOffer();
    await caller.setLocalDescription(offer);
    await callee.setRemoteDescription(offer);
    callee.addTrack(track, stream);
    const answer = await callee.createAnswer();
    await callee.setLocalDescription(answer);
    await caller.setRemoteDescription(answer);
    assert_equals(transceiver.currentDirection, 'sendrecv');

    caller.removeTrack(sender);
    assert_equals(sender.track, null);
    assert_equals(transceiver.direction, 'recvonly');
    assert_equals(transceiver.currentDirection, 'sendrecv',
      'Expect currentDirection to not change');
  }, 'Calling removeTrack with currentDirection sendrecv should set direction to recvonly');

  /*
    5.1.  removeTrack
      7.  Set sender.track to null.
      11. If transceiver.currentDirection is sendonly set transceiver.direction
          to inactive.
   */
  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, { direction: 'sendonly' });
    const { sender } = transceiver;

    assert_equals(sender.track, track);
    assert_equals(transceiver.direction, 'sendonly');
    assert_equals(transceiver.currentDirection, null);

    const offer = await pc.createOffer();
    await pc.setLocalDescription(offer);
    const answer = await generateAnswer(offer);
    await pc.setRemoteDescription(answer);
    assert_equals(transceiver.currentDirection, 'sendonly');

    pc.removeTrack(sender);
    assert_equals(sender.track, null);
    assert_equals(transceiver.direction, 'inactive');
    assert_equals(transceiver.currentDirection, 'sendonly',
      'Expect currentDirection to not change');
  }, 'Calling removeTrack with currentDirection sendonly should set direction to inactive');

  /*
    5.1.  removeTrack
      7.  Set sender.track to null.
      9.  If transceiver.currentDirection is recvonly or inactive,
          then abort these steps.
   */
  promise_test(async t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();
    const transceiver = caller.addTransceiver(track, { direction: 'recvonly' });
    const { sender } = transceiver;

    assert_equals(sender.track, track);
    assert_equals(transceiver.direction, 'recvonly');
    assert_equals(transceiver.currentDirection, null);

    const offer = await caller.createOffer();
    await caller.setLocalDescription(offer);
    await callee.setRemoteDescription(offer);
    callee.addTrack(track, stream);
    const answer = await callee.createAnswer();
    await callee.setLocalDescription(answer);
    await caller.setRemoteDescription(answer);
    assert_equals(transceiver.currentDirection, 'recvonly');

    caller.removeTrack(sender);
    assert_equals(sender.track, null);
    assert_equals(transceiver.direction, 'recvonly');
    assert_equals(transceiver.currentDirection, 'recvonly');
  }, 'Calling removeTrack with currentDirection recvonly should not change direction');

  /*
    5.1.  removeTrack
      7.  Set sender.track to null.
      9.  If transceiver.currentDirection is recvonly or inactive,
          then 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(track, { direction: 'inactive' });
    const { sender } = transceiver;

    assert_equals(sender.track, track);
    assert_equals(transceiver.direction, 'inactive');
    assert_equals(transceiver.currentDirection, null);

    const offer = await pc.createOffer();
    await pc.setLocalDescription(offer);
    const answer = await generateAnswer(offer);
    await pc.setRemoteDescription(answer);
    assert_equals(transceiver.currentDirection, 'inactive');

    pc.removeTrack(sender);
    assert_equals(sender.track, null);
    assert_equals(transceiver.direction, 'inactive');
    assert_equals(transceiver.currentDirection, 'inactive');
  }, 'Calling removeTrack with currentDirection inactive should not change direction');

  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 sender = pc.addTrack(track, stream);

    pc.getTransceivers()[0].stop();
    pc.removeTrack(sender);
    assert_equals(sender.track, track);
  }, "Calling removeTrack on a stopped transceiver should be a no-op");

  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 sender = pc.addTrack(track, stream);

    await sender.replaceTrack(null);
    pc.removeTrack(sender);
    assert_equals(sender.track, null);
}, "Calling removeTrack on a null track should have no effect");


  /*
    TODO
      5.1.  removeTrack
        Stops sending media from sender. The RTCRtpSender will still appear
        in getSenders. Doing so will cause future calls to createOffer to
        mark the media description for the corresponding transceiver as
        recvonly or inactive, as defined in [JSEP] (section 5.2.2.).

        When the other peer stops sending a track in this manner, an ended
        event is fired at the MediaStreamTrack object.

        6.  If sender is not in senders (which indicates that it was removed
            due to setting an RTCSessionDescription of type "rollback"),
            then abort these steps.
        12. Update the negotiation-needed flag for connection.
   */
</script>
