<!doctype html>
<meta charset=utf-8>
<title>RTCPeerConnection.prototype.setRemoteDescription - offer</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="RTCPeerConnection-helper.js"></script>
<script src="/webrtc/third_party/sdp/sdp.js"></script>
<script>
  'use strict';

  // 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>                      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.3.  Otherwise, if description is set as a remote description, then run one of
              the following steps:
        - If description is of type "offer", set connection.pendingRemoteDescription
          attribute to description and signaling state to have-remote-offer.
   */

  promise_test(t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    pc1.createDataChannel('datachannel');

    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());

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

    return pc1.createOffer()
     .then(offer => {
      return pc2.setRemoteDescription(offer)
      .then(() => {
        assert_equals(pc2.signalingState, 'have-remote-offer');
        assert_session_desc_similar(pc2.remoteDescription, offer);
        assert_session_desc_similar(pc2.pendingRemoteDescription, offer);
        assert_equals(pc2.currentRemoteDescription, null);

        assert_array_equals(states, ['have-remote-offer']);
      });
    });
  }, 'setRemoteDescription with valid offer should succeed');

  promise_test(t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    pc1.createDataChannel('datachannel');

    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());

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

    return pc1.createOffer()
    .then(offer => {
      return pc2.setRemoteDescription(offer)
      .then(() => pc2.setRemoteDescription(offer))
      .then(() => {
        assert_equals(pc2.signalingState, 'have-remote-offer');
        assert_session_desc_similar(pc2.remoteDescription, offer);
        assert_session_desc_similar(pc2.pendingRemoteDescription, offer);
        assert_equals(pc2.currentRemoteDescription, null);

        assert_array_equals(states, ['have-remote-offer']);
      });
    });
  }, 'setRemoteDescription multiple times should succeed');

  promise_test(t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    pc1.createDataChannel('datachannel');

    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());

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

    return pc1.createOffer()
    .then(offer1 => {
      return pc1.setLocalDescription(offer1)
       .then(()=> {
        return generateAudioReceiveOnlyOffer(pc1)
        .then(offer2 => {
          assert_session_desc_not_similar(offer1, offer2);

          return pc2.setRemoteDescription(offer1)
          .then(() => pc2.setRemoteDescription(offer2))
          .then(() => {
            assert_equals(pc2.signalingState, 'have-remote-offer');
            assert_session_desc_similar(pc2.remoteDescription, offer2);
            assert_session_desc_similar(pc2.pendingRemoteDescription, offer2);
            assert_equals(pc2.currentRemoteDescription, null);

            assert_array_equals(states, ['have-remote-offer']);
          });
        });
      });
    });
  }, 'setRemoteDescription multiple times with different offer should succeed');

  /*
    4.3.1.6.  Set the RTCSessionSessionDescription
      2.1.4.  If the content of description is not valid SDP syntax, then reject p with
              an RTCError (with errorDetail set to "sdp-syntax-error" and the
              sdpLineNumber attribute set to the line number in the SDP where the syntax
              error was detected) and abort these steps.
   */
  promise_test(t => {
    const pc = new RTCPeerConnection();

    t.add_cleanup(() => pc.close());

    return pc.setRemoteDescription({
      type: 'offer',
      sdp: 'Invalid SDP'
    })
    .then(() => {
      assert_unreached('Expect promise to be rejected');
    }, err => {
      assert_equals(err.errorDetail, 'sdp-syntax-error',
        'Expect error detail field to set to sdp-syntax-error');

      assert_true(err instanceof RTCError,
        'Expect err to be instance of RTCError');
    });
  }, 'setRemoteDescription(offer) with invalid SDP should reject with RTCError');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    t.add_cleanup(() => pc2.close());
    await pc1.setLocalDescription(await pc1.createOffer());
    await pc1.setRemoteDescription(await pc2.createOffer());
    assert_equals(pc1.signalingState, 'have-remote-offer');
  }, 'setRemoteDescription(offer) from have-local-offer should roll back and succeed');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    t.add_cleanup(() => pc2.close());
    await pc1.setLocalDescription(await pc1.createOffer());
    const p = pc1.setRemoteDescription(await pc2.createOffer());
    await new Promise(r => pc1.onsignalingstatechange = r);
    assert_equals(pc1.signalingState, 'stable');
    assert_equals(pc1.pendingLocalDescription, null);
    assert_equals(pc1.pendingRemoteDescription, null);
    await new Promise(r => pc1.onsignalingstatechange = r);
    assert_equals(pc1.signalingState, 'have-remote-offer');
    assert_equals(pc1.pendingLocalDescription, null);
    assert_equals(pc1.pendingRemoteDescription.type, 'offer');
    await p;
  }, 'setRemoteDescription(offer) from have-local-offer fires signalingstatechange twice');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());

    pc1.addTransceiver('audio', { direction: 'recvonly' });
    const srdPromise = pc2.setRemoteDescription(await pc1.createOffer());

    assert_equals(pc2.signalingState, "stable", "signalingState should not be set synchronously after a call to sRD");

    assert_equals(pc2.pendingRemoteDescription, null, "pendingRemoteDescription should not be set synchronously after a call to sRD");
    assert_equals(pc2.currentRemoteDescription, null, "currentRemoteDescription should not be set synchronously after a call to sRD");

    const statePromise = new Promise(resolve => {
      pc2.onsignalingstatechange = () => {
        resolve(pc2.signalingState);
      }
    });

    const raceValue = await Promise.race([statePromise, srdPromise]);
    assert_equals(raceValue, "have-remote-offer", "signalingstatechange event should fire before sRD resolves");
    assert_not_equals(pc2.pendingRemoteDescription, null, "pendingRemoteDescription should be updated before the signalingstatechange event");
    assert_equals(pc2.pendingRemoteDescription.type, "offer");
    assert_equals(pc2.pendingRemoteDescription, pc2.remoteDescription);
    assert_equals(pc2.currentRemoteDescription, null, "currentRemoteDescription should not be set after a call to sRD(offer)");

    await srdPromise;
  }, "setRemoteDescription(offer) in stable should update internal state with a queued task, in the right order");

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());

    pc2.addTransceiver('audio', { direction: 'recvonly' });
    await pc2.setLocalDescription(await pc2.createOffer());

    // Implicit rollback!
    pc1.addTransceiver('audio', { direction: 'recvonly' });
    const srdPromise = pc2.setRemoteDescription(await pc1.createOffer());

    assert_equals(pc2.signalingState, "have-local-offer", "signalingState should not be set synchronously after a call to sRD");

    assert_equals(pc2.pendingRemoteDescription, null, "pendingRemoteDescription should not be set synchronously after a call to sRD");
    assert_not_equals(pc2.pendingLocalDescription, null, "pendingLocalDescription should not be set synchronously after a call to sRD");
    assert_equals(pc2.pendingLocalDescription.type, "offer");
    assert_equals(pc2.pendingLocalDescription, pc2.localDescription);

    // First, we should go through stable (the implicit rollback part)
    const stablePromise = new Promise(resolve => {
      pc2.onsignalingstatechange = () => {
        resolve(pc2.signalingState);
      }
    });

    let raceValue = await Promise.race([stablePromise, srdPromise]);
    assert_equals(raceValue, "stable", "signalingstatechange event should fire before sRD resolves");
    assert_equals(pc2.pendingLocalDescription, null, "pendingLocalDescription should be updated before the signalingstatechange event");
    assert_equals(pc2.pendingRemoteDescription, null, "pendingRemoteDescription should be updated before the signalingstatechange event");

    const haveRemoteOfferPromise = new Promise(resolve => {
      pc2.onsignalingstatechange = () => {
        resolve(pc2.signalingState);
      }
    });

    raceValue = await Promise.race([haveRemoteOfferPromise, srdPromise]);
    assert_equals(raceValue, "have-remote-offer", "signalingstatechange event should fire before sRD resolves");
    assert_not_equals(pc2.pendingRemoteDescription, null, "pendingRemoteDescription should be updated before the signalingstatechange event");
    assert_equals(pc2.pendingRemoteDescription.type, "offer");
    assert_equals(pc2.pendingRemoteDescription, pc2.remoteDescription);
    assert_equals(pc2.pendingRemoteDescription, pc2.pendingRemoteDescription);
    assert_equals(pc2.pendingLocalDescription, null, "pendingLocalDescription should be updated before the signalingstatechange event");

    await srdPromise;
  }, "setRemoteDescription(offer) in have-local-offer should update internal state with a queued task, in the right order");

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    t.add_cleanup(() => pc2.close());
    await pc1.setLocalDescription(await pc1.createOffer());
    const offer = await pc2.createOffer();
    const p1 = pc1.setLocalDescription({type: 'rollback'});
    await new Promise(r => pc1.onsignalingstatechange = r);
    assert_equals(pc1.signalingState, 'stable');
    const p2 = pc1.addIceCandidate();
    const p3 = pc1.setRemoteDescription(offer);
    await promise_rejects_dom(t, 'InvalidStateError', p2);
    await p1;
    await p3;
    assert_equals(pc1.signalingState, 'have-remote-offer');
  }, 'Naive rollback approach is not glare-proof (control)');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    t.add_cleanup(() => pc2.close());
    await pc1.setLocalDescription(await pc1.createOffer());
    const p = pc1.setRemoteDescription(await pc2.createOffer());
    await new Promise(r => pc1.onsignalingstatechange = r);
    assert_equals(pc1.signalingState, 'stable');
    await pc1.addIceCandidate();
    await p;
    assert_equals(pc1.signalingState, 'have-remote-offer');
  }, 'setRemoteDescription(offer) from have-local-offer is glare-proof');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    t.add_cleanup(() => pc2.close());
    await pc1.setLocalDescription(await pc1.createOffer());
    const statePromise = new Promise(r => pc1.onsignalingstatechange = r);
    // SRD with invalid SDP causes rollback.
    const p = pc1.setRemoteDescription({type: 'offer', sdp: 'Invalid SDP'});
    // Ensure that p is eventually awaited for
    t.add_cleanup(async () => Promise.allSettled([p]));
    // Ensure that the test will fail rather than timing out if state
    // does not change.
    const timeoutPromise = new Promise(
    (resolve, reject) => t.step_timeout(reject, 1000));
    try {
      await Promise.any(statePromise, timeoutPromise);
    } catch (error) {
      assert_unreached('State should have changed');
    }
    assert_equals(pc1.signalingState, 'stable');
    assert_equals(pc1.pendingLocalDescription, null);
    assert_equals(pc1.pendingRemoteDescription, null);
    await promise_rejects_dom(t, 'RTCError', p);
  }, 'setRemoteDescription(invalidOffer) from have-local-offer does not undo rollback');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());
    pc1.addTransceiver('video');
    const offer = await pc1.createOffer();
    await pc2.setRemoteDescription(offer);
    assert_equals(pc2.getTransceivers().length, 1);
    await pc2.setRemoteDescription(offer);
    assert_equals(pc2.getTransceivers().length, 1);
    await pc1.setLocalDescription(offer);
    const answer = await pc2.createAnswer();
    await pc2.setLocalDescription(answer);
    await pc1.setRemoteDescription(answer);
  }, 'repeated sRD(offer) works');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());
    pc1.addTransceiver('video');
    await exchangeOfferAnswer(pc1, pc2);
    await waitForIceGatheringState(pc1, ['complete']);
    await exchangeOfferAnswer(pc1, pc2);
    await waitForIceStateChange(pc2, ['connected', 'completed']);
  }, 'sRD(reoffer) with candidates and without trickle works');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());
    pc1.addTransceiver('video');
    const offer = await pc1.createOffer();
    const srdPromise = pc2.setRemoteDescription(offer);
    assert_equals(pc2.getTransceivers().length, 0);
    await srdPromise;
    assert_equals(pc2.getTransceivers().length, 1);
  }, 'Transceivers added by sRD(offer) should not show up until sRD resolves');

  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    t.add_cleanup(() => pc2.close());
    pc1.addTransceiver('video');
    const description = await pc1.createOffer();
    const sections = SDPUtils.splitSections(description.sdp);
    // Compose SDP with a duplicated media section (equal MSID lines)
    // This is not permitted according to RFC 8830 section 2.
    const sdp = sections[0] + sections[1] + sections[1].replace('a=mid:', 'a=mid:unique');
    const p = pc2.setRemoteDescription({type: 'offer', sdp: sdp});
    await promise_rejects_dom(t, 'OperationError', p);
  }, 'setRemoteDescription(section with duplicate msid) rejects');

</script>
