<!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;
      };

      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_dom(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_dom(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_dom(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_dom(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_dom(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_dom(t, 'InvalidModificationError',
      sender.setParameters(param));
  }, 'setParameters() with new codecs inserted should reject with InvalidModificationError');

</script>
