<!doctype html>
<meta charset=utf-8>
<title>RTCPeerConnection.prototype.setLocalDescription rollback</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:
  //   assert_session_desc_similar
  //   generateAudioReceiveOnlyOffer

  /*
    4.3.2.  Interface Definition
      [Constructor(optional RTCConfiguration configuration)]
      interface RTCPeerConnection : EventTarget {
        Promise<void>                      setLocalDescription(
            RTCSessionDescriptionInit description);

        readonly attribute RTCSessionDescription? localDescription;
        readonly attribute RTCSessionDescription? currentLocalDescription;
        readonly attribute RTCSessionDescription? pendingLocalDescription;

        Promise<void>                      setRemoteDescription(
            RTCSessionDescriptionInit description);

        readonly attribute RTCSessionDescription? remoteDescription;
        readonly attribute RTCSessionDescription? currentRemoteDescription;
        readonly attribute RTCSessionDescription? pendingRemoteDescription;
        ...
      };

    4.6.2.  RTCSessionDescription Class
      dictionary RTCSessionDescriptionInit {
        required RTCSdpType type;
                 DOMString  sdp = "";
      };

    4.6.1.  RTCSdpType
      enum RTCSdpType {
        "offer",
        "pranswer",
        "answer",
        "rollback"
      };
   */

  /*
    4.3.1.6.  Set the RTCSessionSessionDescription
      2.2.2.  If description is set as a local description, then run one of the
              following steps:
        - If description is of type "rollback", then this is a rollback. Set
          connection.pendingLocalDescription to null and signaling state to stable.
   */
  promise_test(t=> {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());

    const states = [];
    pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));

    return pc.createOffer()
    .then(offer => pc.setLocalDescription(offer))
    .then(() => {
      assert_equals(pc.signalingState, 'have-local-offer');
      assert_not_equals(pc.localDescription, null);
      assert_not_equals(pc.pendingLocalDescription, null);
      assert_equals(pc.currentLocalDescription, null);

      return pc.setLocalDescription({ type: 'rollback' });
    })
    .then(() => {
      assert_equals(pc.signalingState, 'stable');
      assert_equals(pc.localDescription, null);
      assert_equals(pc.pendingLocalDescription, null);
      assert_equals(pc.currentLocalDescription, null);

      assert_array_equals(states, ['have-local-offer', 'stable']);
    });
  }, 'setLocalDescription(rollback) from have-local-offer state should reset back to stable state');

  /*
    4.3.1.6.  Set the RTCSessionSessionDescription
      2.3.  If the description's type is invalid for the current signaling state of
            connection, then reject p with a newly created InvalidStateError and abort
            these steps. Note that this implies that once the answerer has performed
            setLocalDescription with his answer, this cannot be rolled back.

    [jsep]
      4.1.8.2.  Rollback
        - Rollback can only be used to cancel proposed changes;
          there is no support for rolling back from a stable state to a
          previous stable state
   */
  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    return promise_rejects(t, 'InvalidStateError',
      pc.setLocalDescription({ type: 'rollback' }));
  }, `setLocalDescription(rollback) from stable state should reject with InvalidStateError`);

  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    return generateAudioReceiveOnlyOffer(pc)
    .then(offer =>
      pc.setRemoteDescription(offer)
      .then(() => pc.createAnswer()))
    .then(answer => pc.setLocalDescription(answer))
    .then(() => {
      return promise_rejects(t, 'InvalidStateError',
        pc.setLocalDescription({ type: 'rollback' }));
    });
  }, `setLocalDescription(rollback) after setting answer description should reject with InvalidStateError`);

  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    return pc.createOffer()
    .then(offer => pc.setLocalDescription(offer))
    .then(() => pc.setLocalDescription({
      type: 'rollback',
      sdp: '!<Invalid SDP Content>;'
    }));
  }, `setLocalDescription(rollback) should ignore invalid sdp content and succeed`);
</script>
