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

  /*
    5.1.  RTCPeerConnection Interface Extensions
      partial interface RTCPeerConnection {
        ...
        sequence<RTCRtpSender>      getSenders();
        sequence<RTCRtpReceiver>    getReceivers();
        sequence<RTCRtpTransceiver> getTransceivers();
        RTCRtpSender                addTrack(MediaStreamTrack track,
                                             MediaStream... streams);
        RTCRtpTransceiver           addTransceiver((MediaStreamTrack or DOMString) trackOrKind,
                                                   optional RTCRtpTransceiverInit init);
      };

      Note
        While addTrack checks if the MediaStreamTrack given as an argument is
        already being sent to avoid sending the same MediaStreamTrack twice,
        the other ways do not, allowing the same MediaStreamTrack to be sent
        several times simultaneously.
   */

  /*
    5.1.  addTrack
      4.  If connection's [[isClosed]] slot is true, throw an 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];

      pc.close();
      assert_throws('InvalidStateError', () => pc.addTrack(track, mediaStream))
    });
  }, 'addTrack when pc is closed should throw InvalidStateError');

  /*
    5.1.  addTrack
      8.  If sender is null, run the following steps:
          1.  Create an RTCRtpSender with track and streams and let sender be
              the result.
          2.  Create an RTCRtpReceiver with track.kind as kind and let receiver
              be the result.
          3.  Create an RTCRtpTransceiver with sender and receiver and let
              transceiver be the result.
          4.  Add transceiver to connection's set of transceivers.
   */
  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);

      assert_true(sender instanceof RTCRtpSender,
        'Expect sender to be instance of RTCRtpSender');

      assert_equals(sender.track, track,
        `Expect sender's track to be the added track`);

      const transceivers = pc.getTransceivers();
      assert_equals(transceivers.length, 1,
        'Expect only one transceiver with sender added');

      const [transceiver] = transceivers;
      assert_equals(transceiver.sender, sender);

      assert_array_equals([sender], pc.getSenders(),
        'Expect only one sender with given track added');

      const { receiver } = transceiver;
      assert_equals(receiver.track.kind, 'audio');
      assert_array_equals([transceiver.receiver], pc.getReceivers(),
        'Expect only one receiver associated with transceiver added');
    });
  }, 'addTrack with single track argument and no mediaStream should succeed');

  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_true(sender instanceof RTCRtpSender,
        'Expect sender to be instance of RTCRtpSender');

      assert_equals(sender.track, track,
        `Expect sender's track to be the added track`);
    });
  }, 'addTrack with single track argument and single mediaStream should succeed');

  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 mediaStream2 = new MediaStream([track]);
      const sender = pc.addTrack(track, mediaStream, mediaStream2);

      assert_true(sender instanceof RTCRtpSender,
        'Expect sender to be instance of RTCRtpSender');

      assert_equals(sender.track, track,
        `Expect sender's track to be the added track`);
    });
  }, 'addTrack with single track argument and multiple mediaStreams should succeed');

  /*
    5.1.  addTrack
      5.  Let senders be the result of executing the CollectSenders algorithm.
          If an RTCRtpSender for track already exists in senders, throw an
          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];

      pc.addTrack(track, mediaStream);
      assert_throws('InvalidAccessError', () => pc.addTrack(track, mediaStream));
    });
  }, 'Adding the same track multiple times should throw InvalidAccessError');

  /*
    5.1.  addTrack
      6.  The steps below describe how to determine if an existing sender can
          be reused.

          If any RTCRtpSender object in senders matches all the following
          criteria, let sender be that object, or null otherwise:
            - The sender's track is null.
            - The transceiver kind of the RTCRtpTransceiver, associated with
              the sender, matches track's kind.
            - The sender has never been used to send. More precisely, the
              RTCRtpTransceiver associated with the sender has never had a
              currentDirection of sendrecv or sendonly.
      7.  If sender is not null, run the following steps to use that sender:
          1.  Set sender.track to track.
          3.  Enable sending direction on the RTCRtpTransceiver associated
              with sender.
   */
  test(t => {
    const pc = new RTCPeerConnection();

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

    const track = generateMediaStreamTrack('audio');
    const sender = pc.addTrack(track);

    assert_equals(sender, transceiver.sender);
    assert_equals(sender.track, track);
    assert_equals(transceiver.direction, 'sendrecv');
    assert_array_equals([sender], pc.getSenders());

  }, 'addTrack with existing sender with null track, same kind, and recvonly direction should reuse sender');

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

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

    const track = generateMediaStreamTrack('audio');
    const sender = pc.addTrack(track);

    assert_equals(sender.track, track);
    assert_not_equals(sender, transceiver.sender);

    const senders = pc.getSenders();
    assert_equals(senders.length, 2,
      'Expect 2 senders added to connection');

    assert_true(senders.includes(sender),
      'Expect senders list to include sender');

    assert_true(senders.includes(transceiver.sender),
      `Expect senders list to include first transceiver's sender`);

  }, 'addTrack with existing sender with null track, same kind, and sendrecv direction should create new sender');

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

    const transceiver = pc.addTransceiver('video', { direction: 'recvonly' });
    assert_equals(transceiver.sender.track, null);
    assert_equals(transceiver.direction, 'recvonly');

    const track = generateMediaStreamTrack('audio');
    const sender = pc.addTrack(track);

    assert_equals(sender.track, track);
    assert_not_equals(sender, transceiver.sender);

    const senders = pc.getSenders();
    assert_equals(senders.length, 2,
      'Expect 2 senders added to connection');

    assert_true(senders.includes(sender),
      'Expect senders list to include sender');

    assert_true(senders.includes(transceiver.sender),
      `Expect senders list to include first transceiver's sender`);

  }, 'addTrack with existing sender with null track, different kind, and recvonly direction should create new sender');

  /*
    TODO
      5.1.  addTrack
        3.  Let streams be a list of MediaStream objects constructed from the
            method's remaining arguments, or an empty list if the method was
            called with a single argument.
        6.  The steps below describe how to determine if an existing sender can
            be reused. Doing so will cause future calls to createOffer and
            createAnswer to mark the corresponding media description as sendrecv
            or sendonly and add the MSID of the track added, as defined in [JSEP]
            (section 5.2.2. and section 5.3.2.).
        9.  A track could have contents that are inaccessible to the application.
            This can be due to being marked with a peerIdentity option or anything
            that would make a track CORS cross-origin. These tracks can be supplied
            to the addTrack method, and have an RTCRtpSender created for them, but
            content must not be transmitted, unless they are also marked with
            peerIdentity and they meet the requirements for sending (see isolated
            streams and RTCPeerConnection).

            All other tracks that are not accessible to the application must not be
            sent to the peer, with silence (audio), black frames (video) or
            equivalently absent content being sent in place of track content.

            Note that this property can change over time.

    Non-Testable
      5.1.  addTrack
        7.  If sender is not null, run the following steps to use that sender:
          2.  Set sender's [[associated MediaStreams]] to streams.

    Tested in RTCPeerConnection-onnegotiationneeded.html:
      5.1. addTrack
        10. Update the negotiation-needed flag for connection.

   */
</script>
