<!doctype html>
<meta charset=utf-8>
<title>RTCRtpParameters codecs</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.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;
      };

      dictionary RTCRtpCodecParameters {
        [readonly]
        unsigned short payloadType;

        [readonly]
        DOMString      mimeType;

        [readonly]
        unsigned long  clockRate;

        [readonly]
        unsigned short channels;

        [readonly]
        DOMString      sdpFmtpLine;
      };

      getParameters
          - The codecs sequence is populated based on the codecs that have been negotiated
            for sending, and which the user agent is currently capable of sending.

            If setParameters has removed or reordered codecs, getParameters MUST return
            the shortened/reordered list. However, every time codecs are renegotiated by
            a new offer/answer exchange, the list of codecs MUST be restored to the full
            negotiated set, in the priority order indicated by the remote description,
            in effect discarding the effects of setParameters.

      codecs
        - When using the setParameters method, the codecs sequence from the corresponding
          call to getParameters can be reordered and entries can be removed, but entries
          cannot be added, and the RTCRtpCodecParameters dictionary members cannot be modified.
   */

  // Get the first codec from param.codecs.
  // Assert that param.codecs has at least one element
  function getFirstCodec(param) {
    const { codecs } = param;
    assert_greater_than(codecs.length, 0);
    return codecs[0];
  }

  /*
    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 codec = getFirstCodec(param);

    if(codec.payloadType === undefined) {
      codec.payloadType = 8;
    } else {
      codec.payloadType += 1;
    }

    return promise_rejects(t, 'InvalidModificationError',
      sender.setParameters(param));
  }, 'setParameters() with codec.payloadType modified 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);

    const codec = getFirstCodec(param);

    if(codec.mimeType === undefined) {
      codec.mimeType = 'audio/piedpiper';
    } else {
      codec.mimeType = `${codec.mimeType}-modified`;
    }

    return promise_rejects(t, 'InvalidModificationError',
      sender.setParameters(param));
  }, 'setParameters() with codec.mimeType modified 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);

    const codec = getFirstCodec(param);

    if(codec.clockRate === undefined) {
      codec.clockRate = 8000;
    } else {
      codec.clockRate += 1;
    }

    return promise_rejects(t, 'InvalidModificationError',
      sender.setParameters(param));
  }, 'setParameters() with codec.clockRate modified 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);

    const codec = getFirstCodec(param);

    if(codec.channels === undefined) {
      codec.channels = 6;
    } else {
      codec.channels += 1;
    }

    return promise_rejects(t, 'InvalidModificationError',
      sender.setParameters(param));
  }, 'setParameters() with codec.channels modified 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);

    const codec = getFirstCodec(param);

    if(codec.sdpFmtpLine === undefined) {
      codec.sdpFmtpLine = 'a=fmtp:98 0-15';
    } else {
      codec.sdpFmtpLine = `${codec.sdpFmtpLine};foo=1`;
    }

    return promise_rejects(t, 'InvalidModificationError',
      sender.setParameters(param));
  }, 'setParameters() with codec.sdpFmtpLine modified 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);

    const { codecs } = param;

    codecs.push({
      payloadType: 2,
      mimeType: 'audio/piedpiper',
      clockRate: 1000,
      channels: 2
    });

    return promise_rejects(t, 'InvalidModificationError',
      sender.setParameters(param));
  }, 'setParameters() with new codecs inserted should reject with InvalidModificationError');

</script>
