<!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
  // generateMediaStreamTrack

  /*
    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.
   */
  test(t => {
    const pc = new RTCPeerConnection();
    const track = generateMediaStreamTrack('audio');
    const transceiver = pc.addTransceiver(track);
    const { sender } = transceiver;

    pc.close();
    assert_throws('InvalidStateError', () => pc.removeTrack(sender));

  }, 'addTransceiver - Calling removeTrack when connection is closed should throw InvalidStateError');

  promise_test(t => {
    const pc = new RTCPeerConnection();

    return navigator.mediaDevices.getUserMedia({ audio: true })
    .then(mediaStream => {
      const tracks = mediaStream.getTracks();
      assert_greater_than(tracks.length, 0,
        'Expect getUserMedia to return at least one audio track');

      const track = tracks[0];
      const sender = pc.addTrack(track, mediaStream);

      pc.close();
      assert_throws('InvalidStateError', () => pc.removeTrack(sender));
    });
  }, 'addTrack - Calling removeTrack when connection is closed should throw InvalidStateError');

  test(t => {
    const pc = new RTCPeerConnection();
    const track = generateMediaStreamTrack('audio');
    const transceiver = pc.addTransceiver(track);
    const { sender } = transceiver;

    const pc2 = new RTCPeerConnection();
    pc2.close();
    assert_throws('InvalidStateError', () => pc2.removeTrack(sender));

  }, 'addTransceiver - Calling removeTrack on different connection that is closed should throw InvalidStateError');

  promise_test(t => {
    const pc = new RTCPeerConnection();

    return navigator.mediaDevices.getUserMedia({ audio: true })
    .then(mediaStream => {
      const tracks = mediaStream.getTracks();
      assert_greater_than(tracks.length, 0,
        'Expect getUserMedia to return at least one audio track');

      const track = tracks[0];
      const sender = pc.addTrack(track, mediaStream);

      const pc2 = new RTCPeerConnection();
      pc2.close();
      assert_throws('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.
   */
  test(t => {
    const pc = new RTCPeerConnection();
    const track = generateMediaStreamTrack('audio');
    const transceiver = pc.addTransceiver(track);
    const { sender } = transceiver;

    const pc2 = new RTCPeerConnection();
    assert_throws('InvalidAccessError', () => pc2.removeTrack(sender));

  }, 'addTransceiver - Calling removeTrack on different connection should throw InvalidAccessError');

  promise_test(t => {
    const pc = new RTCPeerConnection();

    return navigator.mediaDevices.getUserMedia({ audio: true })
    .then(mediaStream => {
      const tracks = mediaStream.getTracks();
      assert_greater_than(tracks.length, 0,
        'Expect getUserMedia to return at least one audio track');

      const track = tracks[0];
      const sender = pc.addTrack(track, mediaStream);

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

  /*
    5.1.  removeTrack
      7.  Set sender.track to null.
   */
  test(t => {
    const pc = new RTCPeerConnection();
    const track = generateMediaStreamTrack('audio');
    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, 'sendrecv',
      'direction should not be altered');

  }, 'addTransceiver - Calling removeTrack with valid sender should set sender.track to null');

  promise_test(t => {
    const pc = new RTCPeerConnection();

    return navigator.mediaDevices.getUserMedia({ audio: true })
    .then(mediaStream => {
      const tracks = mediaStream.getTracks();
      assert_greater_than(tracks.length, 0,
        'Expect getUserMedia to return at least one audio track');

      const track = tracks[0];
      const sender = pc.addTrack(track, mediaStream);

      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(t => {
    const pc = new RTCPeerConnection();
    const track = generateMediaStreamTrack('audio');
    const transceiver = pc.addTransceiver(track);
    const { sender } = transceiver;

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

    return pc.createOffer()
    .then(offer =>
      pc.setLocalDescription(offer)
      .then(() => generateAnswer(offer)))
    .then(answer => pc.setRemoteDescription(answer))
    .then(() => {
      assert_equals(transceiver.currentDirection, 'sendrecv');

      pc.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(t => {
    const pc = new RTCPeerConnection();
    const track = generateMediaStreamTrack('audio');
    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);

    return pc.createOffer()
    .then(offer =>
      pc.setLocalDescription(offer)
      .then(() => generateAnswer(offer)))
    .then(answer => pc.setRemoteDescription(answer))
    .then(() => {
      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(t => {
    const pc = new RTCPeerConnection();
    const track = generateMediaStreamTrack('audio');
    const transceiver = pc.addTransceiver(track, { direction: 'recvonly' });
    const { sender } = transceiver;

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

    return pc.createOffer()
    .then(offer =>
      pc.setLocalDescription(offer)
      .then(() => generateAnswer(offer)))
    .then(answer => pc.setRemoteDescription(answer))
    .then(() => {
      assert_equals(transceiver.currentDirection, 'recvonly');

      pc.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(t => {
    const pc = new RTCPeerConnection();
    const track = generateMediaStreamTrack('audio');
    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);

    return pc.createOffer()
    .then(offer =>
      pc.setLocalDescription(offer)
      .then(() => generateAnswer(offer)))
    .then(answer => pc.setRemoteDescription(answer))
    .then(() => {
      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');

  /*
    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>
