<!doctype html>
<meta charset=utf-8>
<title>RTCPeerConnection.prototype.connectionState</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.htm

  // The following helper functions are called from RTCPeerConnection-helper.js:
  // exchangeIceCandidates
  // exchangeOfferAnswer

  /*
    4.3.2.  Interface Definition
      interface RTCPeerConnection : EventTarget {
        ...
        readonly  attribute RTCPeerConnectionState connectionState;
                  attribute EventHandler           onconnectionstatechange;
      };

    4.4.3.  RTCPeerConnectionState Enum
      enum RTCPeerConnectionState {
        "new",
        "connecting",
        "connected",
        "disconnected",
        "failed",
        "closed"
      };

    5.5.  RTCDtlsTransport Interface
      interface RTCDtlsTransport {
        readonly attribute RTCIceTransport       iceTransport;
        readonly attribute RTCDtlsTransportState state;
        ...
      };

      enum RTCDtlsTransportState {
        "new",
        "connecting",
        "connected",
        "closed",
        "failed"
      };

    5.6.  RTCIceTransport Interface
      interface RTCIceTransport {
        readonly attribute RTCIceTransportState state;
        ...
      };

      enum RTCIceTransportState {
        "new",
        "checking",
        "connected",
        "completed",
        "failed",
        "disconnected",
        "closed"
      };
   */

  /*
    4.4.3.  RTCPeerConnectionState Enum
      new
        Any of the RTCIceTransports or RTCDtlsTransports are in the new
        state and none of the transports are in the connecting, checking,
        failed or disconnected state, or all transports are in the closed state.
   */
  test(t => {
    const pc = new RTCPeerConnection();
    assert_equals(pc.connectionState, 'new');
  }, 'Initial connectionState should be new');

  test(t => {
    const pc = new RTCPeerConnection();
    pc.close();
    assert_equals(pc.connectionState, 'closed');
  }, 'Closing the connection should set connectionState to closed');

  /*
    4.4.3.  RTCPeerConnectionState Enum
      connected
        All RTCIceTransports and RTCDtlsTransports are in the connected,
        completed or closed state and at least of them is in the connected
        or completed state.

    5.5.  RTCDtlsTransportState
      connected
        DTLS has completed negotiation of a secure connection.

    5.6.  RTCIceTransportState
      connected
        The RTCIceTransport has found a usable connection, but is still
        checking other candidate pairs to see if there is a better connection.
        It may also still be gathering and/or waiting for additional remote
        candidates. If consent checks [RFC7675] fail on the connection in use,
        and there are no other successful candidate pairs available, then the
        state transitions to "checking" (if there are candidate pairs remaining
        to be checked) or "disconnected" (if there are no candidate pairs to
        check, but the peer is still gathering and/or waiting for additional
        remote candidates).

      completed
        The RTCIceTransport has finished gathering, received an indication that
        there are no more remote candidates, finished checking all candidate
        pairs and found a connection. If consent checks [RFC7675] subsequently
        fail on all successful candidate pairs, the state transitions to "failed".
   */

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

    let had_connecting = false;

    const onConnectionStateChange = t.step_func(() => {
      const {connectionState} = pc1;
      if (connectionState === 'connecting') {
        had_connecting = true;
      } else if (connectionState === 'connected') {
        assert_true(had_connecting, "state should pass connecting before reaching connected");
        t.done();
      }
    });

    pc1.createDataChannel('test');

    pc1.addEventListener('connectionstatechange', onConnectionStateChange);

    exchangeIceCandidates(pc1, pc2);
    exchangeOfferAnswer(pc1, pc2);
  }, 'connection with one data channel should eventually have connected connection state');

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

    const onConnectionStateChange = t.step_func(() => {
      const {connectionState} = pc1;
      if (connectionState === 'connected') {
        const sctpTransport = pc1.sctp;

        const dtlsTransport = sctpTransport.transport;
        assert_equals(dtlsTransport.state, 'connected',
          'Expect DTLS transport to be in connected state');

        const iceTransport = dtlsTransport.iceTransport
        assert_true(iceTransport.state ===  'connected' ||
          iceTransport.state === 'completed',
          'Expect ICE transport to be in connected or completed state');

        t.done();
      }
    });

    pc1.createDataChannel('test');

    pc1.addEventListener('connectionstatechange', onConnectionStateChange);

    exchangeIceCandidates(pc1, pc2);
    exchangeOfferAnswer(pc1, pc2);
  }, 'connection with one data channel should eventually have transports in connected state');

  /*
    TODO
    4.4.3.  RTCPeerConnectionState Enum
      connecting
        Any of the RTCIceTransports or RTCDtlsTransports are in the
        connecting or checking state and none of them is in the failed state.

      disconnected
        Any of the RTCIceTransports or RTCDtlsTransports are in the disconnected
        state and none of them are in the failed or connecting or checking state.

      failed
        Any of the RTCIceTransports or RTCDtlsTransports are in a failed state.

      closed
        The RTCPeerConnection object's [[isClosed]] slot is true.

     5.5. RTCDtlsTransportState
      new
        DTLS has not started negotiating yet.

      connecting
        DTLS is in the process of negotiating a secure connection.

      closed
        The transport has been closed.

      failed
        The transport has failed as the result of an error (such as a failure
        to validate the remote fingerprint).

    5.6.  RTCIceTransportState
      new
        The RTCIceTransport is gathering candidates and/or waiting for
        remote candidates to be supplied, and has not yet started checking.

      checking
        The RTCIceTransport has received at least one remote candidate and
        is checking candidate pairs and has either not yet found a connection
        or consent checks [RFC7675] have failed on all previously successful
        candidate pairs. In addition to checking, it may also still be gathering.

      failed
        The RTCIceTransport has finished gathering, received an indication that
        there are no more remote candidates, finished checking all candidate pairs,
        and all pairs have either failed connectivity checks or have lost consent.

      disconnected
        The ICE Agent has determined that connectivity is currently lost for this
        RTCIceTransport . This is more aggressive than failed, and may trigger
        intermittently (and resolve itself without action) on a flaky network.
        The way this state is determined is implementation dependent.

        Examples include:
          Losing the network interface for the connection in use.
          Repeatedly failing to receive a response to STUN requests.

        Alternatively, the RTCIceTransport has finished checking all existing
        candidates pairs and failed to find a connection (or consent checks
        [RFC7675] once successful, have now failed), but it is still gathering
        and/or waiting for additional remote candidates.

      closed
        The RTCIceTransport has shut down and is no longer responding to STUN requests.
   */
  promise_test(async t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();
    caller.addTrack(track, stream);

    await exchangeOfferAnswer(caller, callee);

    assert_equals(caller.iceConnectionState, 'new');
    assert_equals(callee.iceConnectionState, 'new');
  }, 'connectionState remains new when not adding remote ice candidates');

  promise_test(async t => {

    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();
    caller.addTrack(track, stream);

    const states = [];
    caller.addEventListener('connectionstatechange', () => states.push(caller.connectionState));
    exchangeIceCandidates(caller, callee);
    await exchangeOfferAnswer(caller, callee);

    await listenToConnected(caller);

    assert_array_equals(states, ['connecting', 'connected']);
  }, 'connectionState transitions to connected via connecting');


  // Make the callee act as if not bundle-aware
  async function exchangeOfferAnswerUnbundled(caller, callee) {
    const offer = await caller.createOffer();
    const sdp = offer.sdp.replace('BUNDLE', 'SOMETHING')
          .replace(/rtp-hdrext:sdes/g, 'rtp-hdrext:something')
          .replace(/a=ssrc:/g, 'a=notssrc');
    await caller.setLocalDescription(offer);
    await callee.setRemoteDescription({type: 'offer', sdp});

    await exchangeAnswer(caller, callee);
  }

  promise_test(async t => {
    const pc1 = new RTCPeerConnection({bundlePolicy: 'max-compat'});
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    t.add_cleanup(() => pc2.close());
    const stream = await getNoiseStream({ audio: true });
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    stream.getTracks().forEach(track => pc1.addTrack(track, stream));
    exchangeIceCandidates(pc1, pc2);
    exchangeOfferAnswerUnbundled(pc1, pc2);
    await listenToConnected(pc1);

    // https://github.com/w3c/webrtc-pc/issues/2678#issuecomment-948554126
    let had_intermediary_connecting = false
    let channel;
    const onConnectionStateChange = t.step_func(() => {
      const {connectionState, iceConnectionState} = pc1;
      if (connectionState === 'connecting') {
        had_intermediary_connecting = true;
      }
    });

    pc1.addEventListener('connectionstatechange', onConnectionStateChange);
    channel = pc1.createDataChannel('test');
    await exchangeOfferAnswer(pc1, pc2);
    await listenToConnected(pc1);

    assert_true(had_intermediary_connecting, "state should re-pass connecting before reaching connected");
  }, 'when adding a datachannel to an existing unbundled connected PC, it should go through a connecting state');


  promise_test(async t => {
    const pc1 = new RTCPeerConnection();
    t.add_cleanup(() => pc1.close());
    const pc2 = new RTCPeerConnection();
    const stream = await getNoiseStream({ audio: true });
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));

    stream.getTracks().forEach(track => pc1.addTrack(track, stream));
    exchangeIceCandidates(pc1, pc2);
    exchangeOfferAnswer(pc1, pc2);
    await listenToIceConnected(pc2);

    pc2.onconnectionstatechange = t.unreached_func();
    pc2.close();
    assert_equals(pc2.connectionState, 'closed');
    await new Promise(r => t.step_timeout(r, 100));
  }, 'Closing a PeerConnection should not fire connectionstatechange event');
</script>
