<!doctype html>
<meta charset=utf-8>
<title>RTCRtpParameters transactionId</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="dictionary-helper.js"></script>
<script src="RTCRtpParameters-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 RTCRtpParameters-helper.js:
  //   doOfferAnswerExchange
  //   validateSenderRtpParameters

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

      dictionary RTCRtpTransceiverInit {
        RTCRtpTransceiverDirection         direction = "sendrecv";
        sequence<MediaStream>              streams;
        sequence<RTCRtpEncodingParameters> sendEncodings;
      };

      addTransceiver
        2.  If the dictionary argument is present, and it has a sendEncodings member,
            let sendEncodings be that list of RTCRtpEncodingParameters objects, or an
            empty list otherwise.
        7.  Create an RTCRtpSender with track, streams and sendEncodings and let
            sender be the result.

    5.2.  RTCRtpSender Interface
      interface RTCRtpSender {
        Promise<void>           setParameters(optional RTCRtpParameters parameters);
        RTCRtpParameters        getParameters();
      };

      dictionary RTCRtpParameters {
        DOMString                                 transactionId;
        sequence<RTCRtpEncodingParameters>        encodings;
        sequence<RTCRtpHeaderExtensionParameters> headerExtensions;
        RTCRtcpParameters                         rtcp;
        sequence<RTCRtpCodecParameters>           codecs;
        RTCDegradationPreference                  degradationPreference;
      };

      getParameters
        - transactionId is set to a new unique identifier, used to match this
          getParameters call to a setParameters call that may occur later.
   */

  /*
    5.2.  getParameters
      - transactionId is set to a new unique identifier, used to match this
        getParameters call to a setParameters call that may occur later.
   */
  promise_test(async t => {
    const pc = new RTCPeerConnection();
    const { sender } = pc.addTransceiver('audio');
    await doOfferAnswerExchange(t, pc);

    const param1 = sender.getParameters();
    const param2 = sender.getParameters();

    validateSenderRtpParameters(param1);
    validateSenderRtpParameters(param2);

    assert_not_equals(param1.transactionId, param2.transactionId);

  }, `sender.getParameters() should return different transaction IDs for each call`);

  /*
    5.2.  setParameters
      7.  If parameters.encodings.length is different from N, or if any parameter
          in the parameters argument, marked as a Read-only parameter, has a value
          that is different from the corresponding parameter value returned from
          sender.getParameters(), abort these steps and return a promise rejected
          with a newly created InvalidModificationError. Note that this also applies
          to transactionId.
   */
  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const { sender } = pc.addTransceiver('audio');
    await doOfferAnswerExchange(t, pc);

    const param = sender.getParameters();
    validateSenderRtpParameters(param);

    const { transactionId } = param;
    param.transactionId = `${transactionId}-modified`;

    return promise_rejects(t, 'InvalidModificationError',
      sender.setParameters(param));
  }, `sender.setParameters() with transaction ID different from last getParameters() should reject with InvalidModificationError`);

  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const { sender } = pc.addTransceiver('audio');
    await doOfferAnswerExchange(t, pc);

    const param = sender.getParameters();
    validateSenderRtpParameters(param);

    param.transactionId = undefined;

    return promise_rejects(t, new TypeError(),
      sender.setParameters(param));
  }, `sender.setParameters() with transaction ID unset should reject with TypeError`);

  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const { sender } = pc.addTransceiver('audio');
    await doOfferAnswerExchange(t, pc);

    const param = sender.getParameters();
    validateSenderRtpParameters(param);

    return sender.setParameters(param)
    .then(() =>
      promise_rejects(t, 'InvalidStateError',
        sender.setParameters(param)));
  }, `setParameters() twice with the same parameters should reject with InvalidStateError`);

  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const { sender } = pc.addTransceiver('audio');
    await doOfferAnswerExchange(t, pc);

    const param1 = sender.getParameters();
    const param2 = sender.getParameters();

    validateSenderRtpParameters(param1);
    validateSenderRtpParameters(param2);

    assert_not_equals(param1.transactionId, param2.transactionId);

    return promise_rejects(t, 'InvalidModificationError',
      sender.setParameters(param1));
  }, `setParameters() with parameters older than last getParameters() should reject with InvalidModificationError`);

</script>
