<!doctype html>
<meta name="timeout" content="long">
<title>RTCConfiguration iceTransportPolicy</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="RTCConfiguration-helper.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 function is called from RTCConfiguration-helper.js:
  //   config_test

  /*
    [Constructor(optional RTCConfiguration configuration)]
    interface RTCPeerConnection : EventTarget {
      RTCConfiguration                   getConfiguration();
      void                               setConfiguration(RTCConfiguration configuration);
      ...
    };

    dictionary RTCConfiguration {
      sequence<RTCIceServer>   iceServers;
      RTCIceTransportPolicy    iceTransportPolicy = "all";
    };

    enum RTCIceTransportPolicy {
      "relay",
      "all"
    };
   */

  test(() => {
    const pc = new RTCPeerConnection();
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
  }, `new RTCPeerConnection() should have default iceTransportPolicy all`);

  test(() => {
    const pc = new RTCPeerConnection({ iceTransportPolicy: undefined });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
  }, `new RTCPeerConnection({ iceTransportPolicy: undefined }) should have default iceTransportPolicy all`);

  test(() => {
    const pc = new RTCPeerConnection({ iceTransportPolicy: 'all' });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
  }, `new RTCPeerConnection({ iceTransportPolicy: 'all' }) should succeed`);

  test(() => {
    const pc = new RTCPeerConnection({ iceTransportPolicy: 'relay' });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'relay');
  }, `new RTCPeerConnection({ iceTransportPolicy: 'relay' }) should succeed`);

  /*
    4.3.2. Set a configuration
      8.  Set the ICE Agent's ICE transports setting to the value of
          configuration.iceTransportPolicy. As defined in [JSEP] (section 4.1.16.),
          if the new ICE transports setting changes the existing setting, no action
          will be taken until the next gathering phase. If a script wants this to
          happen immediately, it should do an ICE restart.
   */
  test(() => {
    const pc = new RTCPeerConnection({ iceTransportPolicy: 'all' });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');

    pc.setConfiguration({ iceTransportPolicy: 'relay' });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'relay');
  }, `setConfiguration({ iceTransportPolicy: 'relay' }) with initial iceTransportPolicy all should succeed`);

  test(() => {
    const pc = new RTCPeerConnection({ iceTransportPolicy: 'relay' });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'relay');

    pc.setConfiguration({ iceTransportPolicy: 'all' });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
  }, `setConfiguration({ iceTransportPolicy: 'all' }) with initial iceTransportPolicy relay should succeed`);

  test(() => {
    const pc = new RTCPeerConnection({ iceTransportPolicy: 'relay' });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'relay');

    // default value for iceTransportPolicy is all
    pc.setConfiguration({});
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
  }, `setConfiguration({}) with initial iceTransportPolicy relay should set new value to all`);

  config_test(makePc => {
    assert_throws_js(TypeError, () =>
      makePc({ iceTransportPolicy: 'invalid' }));
  }, `with invalid iceTransportPolicy should throw TypeError`);

  // "none" is in Blink and Gecko's IDL, but not in the spec.
  config_test(makePc => {
    assert_throws_js(TypeError, () =>
      makePc({ iceTransportPolicy: 'none' }));
  }, `with none iceTransportPolicy should throw TypeError`);

  config_test(makePc => {
    assert_throws_js(TypeError, () =>
      makePc({ iceTransportPolicy: null }));
  }, `with null iceTransportPolicy should throw TypeError`);

  // iceTransportPolicy is called iceTransports in Blink.
  test(() => {
    const pc = new RTCPeerConnection({ iceTransports: 'relay' });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
  }, `new RTCPeerConnection({ iceTransports: 'relay' }) should have no effect`);

  test(() => {
    const pc = new RTCPeerConnection({ iceTransports: 'invalid' });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
  }, `new RTCPeerConnection({ iceTransports: 'invalid' }) should have no effect`);

  test(() => {
    const pc = new RTCPeerConnection({ iceTransports: null });
    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
  }, `new RTCPeerConnection({ iceTransports: null }) should have no effect`);

  const getLines = (sdp, startsWith) =>
    sdp.split('\r\n').filter(l => l.startsWith(startsWith));

  const getUfrags = ({sdp}) => getLines(sdp, 'a=ice-ufrag:');

  promise_test(async t => {
    const offerer = new RTCPeerConnection({iceTransportPolicy: 'relay'});
    t.add_cleanup(() => offerer.close());

    offerer.addEventListener('icecandidate',
        e => assert_equals(e.candidate, null, 'Should get no ICE candidates'));

    offerer.addTransceiver('audio');
    await offerer.setLocalDescription();

    await waitForIceGatheringState(offerer, ['complete']);
  }, `iceTransportPolicy "relay" on offerer should prevent candidate gathering`);

  promise_test(async t => {
    const offerer = new RTCPeerConnection();
    const answerer = new RTCPeerConnection({iceTransportPolicy: 'relay'});
    t.add_cleanup(() => offerer.close());
    t.add_cleanup(() => answerer.close());

    answerer.addEventListener('icecandidate',
        e => assert_equals(e.candidate, null, 'Should get no ICE candidates'));

    offerer.addTransceiver('audio');
    const offer = await offerer.createOffer();
    await answerer.setRemoteDescription(offer);
    await answerer.setLocalDescription(await answerer.createAnswer());
    await waitForIceGatheringState(answerer, ['complete']);
  }, `iceTransportPolicy "relay" on answerer should prevent candidate gathering`);

  promise_test(async t => {
    const offerer = new RTCPeerConnection();
    const answerer = new RTCPeerConnection();
    t.add_cleanup(() => offerer.close());
    t.add_cleanup(() => answerer.close());

    offerer.addTransceiver('audio');

    exchangeIceCandidates(offerer, answerer);

    await Promise.all([
      exchangeOfferAnswer(offerer, answerer),
      listenToIceConnected(offerer),
      listenToIceConnected(answerer),
      waitForIceGatheringState(offerer, ['complete']),
      waitForIceGatheringState(answerer, ['complete'])
    ]);

    const [oldUfrag] = getUfrags(offerer.localDescription);

    offerer.setConfiguration({iceTransportPolicy: 'relay'});

    offerer.addEventListener('icecandidate',
        e => assert_equals(e.candidate, null, 'Should get no ICE candidates'));

    await Promise.all([
      exchangeOfferAnswer(offerer, answerer),
      waitForIceStateChange(offerer, ['failed']),
      waitForIceStateChange(answerer, ['failed']),
      waitForIceGatheringState(offerer, ['complete']),
      waitForIceGatheringState(answerer, ['complete'])
    ]);

    const [newUfrag] = getUfrags(offerer.localDescription);
    assert_not_equals(oldUfrag, newUfrag,
        'Changing iceTransportPolicy should prompt an ICE restart');
  }, `Changing iceTransportPolicy from "all" to "relay" causes an ICE restart which should fail, with no new candidates`);

  promise_test(async t => {
    const offerer = new RTCPeerConnection({iceTransportPolicy: 'relay'});
    const answerer = new RTCPeerConnection();
    t.add_cleanup(() => offerer.close());
    t.add_cleanup(() => answerer.close());

    offerer.addTransceiver('audio');

    exchangeIceCandidates(offerer, answerer);

    const checkNoCandidate =
        e => assert_equals(e.candidate, null, 'Should get no ICE candidates');

    offerer.addEventListener('icecandidate', checkNoCandidate);

    await Promise.all([
      exchangeOfferAnswer(offerer, answerer),
      waitForIceStateChange(offerer, ['failed']),
      waitForIceStateChange(answerer, ['failed']),
      waitForIceGatheringState(offerer, ['complete']),
      waitForIceGatheringState(answerer, ['complete'])
    ]);

    const [oldUfrag] = getUfrags(offerer.localDescription);

    offerer.setConfiguration({iceTransportPolicy: 'all'});

    offerer.removeEventListener('icecandidate', checkNoCandidate);

    await Promise.all([
      exchangeOfferAnswer(offerer, answerer),
      listenToIceConnected(offerer),
      listenToIceConnected(answerer),
      waitForIceGatheringState(offerer, ['complete']),
      waitForIceGatheringState(answerer, ['complete'])
    ]);

    const [newUfrag] = getUfrags(offerer.localDescription);
    assert_not_equals(oldUfrag, newUfrag,
        'Changing iceTransportPolicy should prompt an ICE restart');
  }, `Changing iceTransportPolicy from "relay" to "all" causes an ICE restart which should succeed`);

  promise_test(async t => {
    const offerer = new RTCPeerConnection();
    const answerer = new RTCPeerConnection();
    t.add_cleanup(() => offerer.close());
    t.add_cleanup(() => answerer.close());

    offerer.addTransceiver('audio');

    exchangeIceCandidates(offerer, answerer);

    await Promise.all([
      exchangeOfferAnswer(offerer, answerer),
      listenToIceConnected(offerer),
      listenToIceConnected(answerer),
      waitForIceGatheringState(offerer, ['complete']),
      waitForIceGatheringState(answerer, ['complete'])
    ]);

    const [oldUfrag] = getUfrags(offerer.localDescription);

    offerer.setConfiguration({iceTransportPolicy: 'relay'});
    offerer.setConfiguration({iceTransportPolicy: 'all'});

    await Promise.all([
      exchangeOfferAnswer(offerer, answerer),
      listenToIceConnected(offerer),
      listenToIceConnected(answerer),
      waitForIceGatheringState(offerer, ['complete']),
      waitForIceGatheringState(answerer, ['complete'])
    ]);

    const [newUfrag] = getUfrags(offerer.localDescription);
    assert_not_equals(oldUfrag, newUfrag,
        'Changing iceTransportPolicy should prompt an ICE restart');
  }, `Changing iceTransportPolicy from "all" to "relay", and back to "all" prompts an ICE restart`);

  promise_test(async t => {
    const offerer = new RTCPeerConnection();
    const answerer = new RTCPeerConnection();
    t.add_cleanup(() => offerer.close());
    t.add_cleanup(() => answerer.close());

    offerer.addTransceiver('audio');

    exchangeIceCandidates(offerer, answerer);

    await Promise.all([
      exchangeOfferAnswer(offerer, answerer),
      listenToIceConnected(offerer),
      listenToIceConnected(answerer),
      waitForIceGatheringState(offerer, ['complete']),
      waitForIceGatheringState(answerer, ['complete'])
    ]);

    const [oldUfrag] = getUfrags(answerer.localDescription);

    answerer.setConfiguration({iceTransportPolicy: 'relay'});

    await Promise.all([
      exchangeOfferAnswer(offerer, answerer),
      listenToIceConnected(offerer),
      listenToIceConnected(answerer),
      waitForIceGatheringState(offerer, ['complete']),
      waitForIceGatheringState(answerer, ['complete'])
    ]);

    const [newUfrag] = getUfrags(answerer.localDescription);
    assert_equals(oldUfrag, newUfrag,
        'Changing iceTransportPolicy on answerer should not effect ufrag');
  }, `Changing iceTransportPolicy from "all" to "relay" on the answerer has no effect on a subsequent offer/answer`);

</script>
