<!doctype html>
<meta charset=utf-8>
<title>RTCConfiguration iceServers</title>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='RTCConfiguration-helper.js'></script>
<script>
  'use strict';

  // Test is based on the following editor's draft:
  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html

  // The following helper function is called from
  // RTCConfiguration-helper.js:
  //   config_test

  /*
    4.3.2.  Interface Definition
      [Constructor(optional RTCConfiguration configuration)]
      interface RTCPeerConnection : EventTarget {
        ...
      };

    4.2.1.  RTCConfiguration Dictionary
      dictionary RTCConfiguration {
        sequence<RTCIceServer>   iceServers = [];
        ...
      };

    4.2.4.  RTCIceServer Dictionary
      dictionary RTCIceServer {
        required (DOMString or sequence<DOMString>) urls;
                 DOMString                          username;
                 DOMString                          credential;
      };
   */
  // RFC 8489 limits the length of the TURN username to 509 bytes:
  // https://datatracker.ietf.org/doc/html/rfc8489#section-14.3
  const kUsernameOfMaxPermittedLength = 'a'.repeat(509);

  test(() => {
    const pc = new RTCPeerConnection();
    assert_array_equals(pc.getConfiguration().iceServers, []);
  }, 'new RTCPeerConnection() should have default configuration.iceServers of []');

  config_test(makePc => {
    makePc({});
  }, '{} should succeed');

  config_test(makePc => {
    assert_throws_js(TypeError, () =>
      makePc({ iceServers: null }));
  }, '{ iceServers: null } should throw TypeError');

  config_test(makePc => {
    const pc = makePc({ iceServers: undefined });
    assert_array_equals(pc.getConfiguration().iceServers, []);
  }, '{ iceServers: undefined } should succeed');

  config_test(makePc => {
    const pc = makePc({ iceServers: [] });
    assert_array_equals(pc.getConfiguration().iceServers, []);
  }, '{ iceServers: [] } should succeed');

  config_test(makePc => {
    assert_throws_js(TypeError, () =>
      makePc({ iceServers: [null] }));
  }, '{ iceServers: [null] } should throw TypeError');

  config_test(makePc => {
    assert_throws_js(TypeError, () =>
      makePc({ iceServers: [undefined] }));
  }, '{ iceServers: [undefined] } should throw TypeError');

  config_test(makePc => {
    assert_throws_js(TypeError, () =>
      makePc({ iceServers: [{}] }));
  }, '{ iceServers: [{}] } should throw TypeError');

  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: 'stun:stun1.example.net'
    }] });

    const { iceServers } = pc.getConfiguration();
    assert_equals(iceServers.length, 1);

    const server = iceServers[0];
    assert_array_equals(server.urls, ['stun:stun1.example.net']);

  }, `with stun server should succeed`);

  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: ['stun:stun1.example.net']
    }] });

    const { iceServers } = pc.getConfiguration();
    assert_equals(iceServers.length, 1);

    const server = iceServers[0];
    assert_array_equals(server.urls, ['stun:stun1.example.net']);

  }, `with stun server array should succeed`);

  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: ['stun:stun1.example.net', 'stun:stun2.example.net']
    }] });

    const { iceServers } = pc.getConfiguration();
    assert_equals(iceServers.length, 1);

    const server = iceServers[0];
    assert_array_equals(server.urls, ['stun:stun1.example.net', 'stun:stun2.example.net']);

  }, `with 2 stun servers should succeed`);

  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: 'turn:turn.example.org',
      username: 'user',
      credential: 'cred'
    }] });

    const { iceServers } = pc.getConfiguration();
    assert_equals(iceServers.length, 1);

    const server = iceServers[0];
    assert_array_equals(server.urls, ['turn:turn.example.org']);
    assert_equals(server.username, 'user');
    assert_equals(server.credential, 'cred');

  }, `with turn server, username, credential should succeed`);

  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: 'turns:turn.example.org',
      username: '',
      credential: ''
    }] });

    const { iceServers } = pc.getConfiguration();
    assert_equals(iceServers.length, 1);

    const server = iceServers[0];
    assert_array_equals(server.urls, ['turns:turn.example.org']);
    assert_equals(server.username, '');
    assert_equals(server.credential, '');

  }, `with turns server and empty string username, credential should succeed`);

  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: 'turn:turn.example.org',
      username: '',
      credential: ''
    }] });

    const { iceServers } = pc.getConfiguration();
    assert_equals(iceServers.length, 1);

    const server = iceServers[0];
    assert_array_equals(server.urls, ['turn:turn.example.org']);
    assert_equals(server.username, '');
    assert_equals(server.credential, '');

  }, `with turn server and empty string username, credential should succeed`);

  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: ['turns:turn.example.org', 'turn:turn.example.net'],
      username: 'user',
      credential: 'cred'
    }] });

    const { iceServers } = pc.getConfiguration();
    assert_equals(iceServers.length, 1);

    const server = iceServers[0];
    assert_array_equals(server.urls, ['turns:turn.example.org', 'turn:turn.example.net']);
    assert_equals(server.username, 'user');
    assert_equals(server.credential, 'cred');

  }, `with one turns server, one turn server, username, credential should succeed`);

  config_test(makePc => {
    assert_equals(kUsernameOfMaxPermittedLength.length, 509);
    const pc = makePc({ iceServers: [{
      urls: 'turn:turn.example.net',
      username: kUsernameOfMaxPermittedLength,
      credential: 'cred'
    }] });
  }, `with a turn server and a username of 509 characters should succeed`);

  /*
    4.3.2.  To set a configuration
      11.4. If scheme name is turn or turns, and either of server.username or
            server.credential are omitted, then throw an InvalidAccessError.
   */
  config_test(makePc => {
    assert_throws_dom('InvalidAccessError', () =>
      makePc({ iceServers: [{
        urls: 'turn:turn.example.net'
      }] }));
  }, 'with turn server and no credentials should throw InvalidAccessError');

  config_test(makePc => {
    assert_throws_dom('InvalidAccessError', () =>
      makePc({ iceServers: [{
        urls: 'turn:turn.example.net',
        username: 'user'
      }] }));
  }, 'with turn server and only username should throw InvalidAccessError');

  config_test(makePc => {
    assert_throws_dom('InvalidAccessError', () =>
      makePc({ iceServers: [{
        urls: 'turn:turn.example.net',
        credential: 'cred'
      }] }));
  }, 'with turn server and only credential should throw InvalidAccessError');

  config_test(makePc => {
    assert_throws_dom('InvalidAccessError', () =>
      makePc({ iceServers: [{
        urls: 'turns:turn.example.net'
      }] }));
  }, 'with turns server and no credentials should throw InvalidAccessError');

  config_test(makePc => {
    assert_throws_dom('InvalidAccessError', () =>
      makePc({ iceServers: [{
        urls: 'turns:turn.example.net',
        username: 'user'
      }] }));
  }, 'with turns server and only username should throw InvalidAccessError');

  config_test(makePc => {
    assert_throws_dom('InvalidAccessError', () =>
      makePc({ iceServers: [{
        urls: 'turns:turn.example.net',
        credential: 'cred'
      }] }));
  }, 'with turns server and only credential should throw InvalidAccessError');

  config_test(makePc => {
    assert_equals(kUsernameOfMaxPermittedLength.length, 509);
    assert_throws_dom('InvalidAccessError', () =>
      makePc({ iceServers: [{
        urls: 'turns:turn.example.net',
        username: kUsernameOfMaxPermittedLength + 'a',
        credential: 'cred'
      }] }));
  }, `with a turn server and a username of 510 characters throw InvalidAccessError`);

  /*
    4.3.2.  To set a configuration
      11.3. For each url in server.urls parse url and obtain scheme name.
        - If the scheme name is not implemented by the browser, throw a SyntaxError.
        - or if parsing based on the syntax defined in [ RFC7064] and [RFC7065] fails,
          throw a SyntaxError.

    [RFC7064] URI Scheme for the Session Traversal Utilities for NAT (STUN) Protocol
    3.1.  URI Scheme Syntax
      stunURI       = scheme ":" host [ ":" port ]
      scheme        = "stun" / "stuns"

    [RFC7065] Traversal Using Relays around NAT (TURN) Uniform Resource Identifiers
    3.1.  URI Scheme Syntax
      turnURI       = scheme ":" host [ ":" port ]
                      [ "?transport=" transport ]
      scheme        = "turn" / "turns"
      transport     = "udp" / "tcp" / transport-ext
      transport-ext = 1*unreserved
   */
  config_test(makePc => {
    assert_throws_dom("SyntaxError", () =>
      makePc({ iceServers: [{
        urls: ''
      }] }));
  }, 'with "" url should throw SyntaxError');

  config_test(makePc => {
    assert_throws_dom("SyntaxError", () =>
      makePc({ iceServers: [{
        urls: ['stun:stun1.example.net', '']
      }] }));
  }, 'with ["stun:stun1.example.net", ""] url should throw SyntaxError');

  config_test(makePc => {
    assert_throws_dom("SyntaxError", () =>
      makePc({ iceServers: [{
        urls: 'relative-url'
      }] }));
  }, 'with relative url should throw SyntaxError');

  config_test(makePc => {
    assert_throws_dom("SyntaxError", () =>
      makePc({ iceServers: [{
        urls: 'http://example.com'
      }] }));
  }, 'with http url should throw SyntaxError');

  config_test(makePc => {
    assert_throws_dom("SyntaxError", () =>
      makePc({ iceServers: [{
        urls: 'turn://example.org/foo?x=y'
        // `username` and `credential` are not passed because the invalid url
        // should be rejected before the check for those arguments.
      }] }));
  }, 'with invalid turn url should throw SyntaxError');

  config_test(makePc => {
    assert_throws_dom("SyntaxError", () =>
      makePc({ iceServers: [{
        urls: 'stun://example.org/foo?x=y'
      }] }));
  }, 'with invalid stun url should throw SyntaxError');

  config_test(makePc => {
    assert_throws_dom("SyntaxError", () =>
      makePc({ iceServers: [{
        urls: []
      }] }));
  }, `with empty urls should throw SyntaxError`);

  test(() => {
    const pc = new RTCPeerConnection({ iceServers: [{
      urls: 'stun:stun1.example.net'
    }] });
    let config = pc.getConfiguration();
    assert_equals(config.iceServers.length, 1);
    pc.setConfiguration({});
    config = pc.getConfiguration();
    assert_equals(config.iceServers.length, 0);
  }, `setConfiguration(config) - without iceServers removes ice servers`);

  config_test(makePc => {
    const pc = makePc({ iceServers: [...Array(32)].map((_, i) => ({
      urls: `stun:stun${i+1}.example.net`
    })) });

    const { iceServers } = pc.getConfiguration();
    assert_equals(iceServers.length, 32);

    for (let i = 0; i < 32; i++) {
      const server = iceServers[i];
      assert_array_equals(server.urls, [`stun:stun${i+1}.example.net`]);
    }
  }, `with 32 ice servers must succeed`);
</script>
