<!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.2.  RTCIceCredentialType Enum
      enum RTCIceCredentialType {
        "password",
        "oauth"
      };

    4.2.3.  RTCOAuthCredential Dictionary
      dictionary RTCOAuthCredential {
        required DOMString macKey;
        required DOMString accessToken;
      };

    4.2.4.  RTCIceServer Dictionary
      dictionary RTCIceServer {
        required (DOMString or sequence<DOMString>) urls;
                 DOMString                          username;
                 (DOMString or RTCOAuthCredential)  credential;
                 RTCIceCredentialType               credentialType = "password";
      };
   */

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

  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_equals(pc.getConfiguration().iceServers, undefined);
  }, '{ 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']);
    assert_equals(server.credentialType, 'password');

  }, `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']);
    assert_equals(server.credentialType, 'password');

  }, `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']);
    assert_equals(server.credentialType, 'password');

  }, `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.credentialType, 'password');
    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 => {
    const pc = makePc({ iceServers: [{
      urls: 'stun:stun1.example.net',
      credentialType: 'password'
    }] });

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

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

  }, `with stun server and credentialType password 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');

  /*
    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'
      }] }));
  }, '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`);

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

  // token credentialType was removed from the spec since 20170508
  config_test(makePc => {
    assert_throws_js(TypeError, () =>
      makePc({ iceServers: [{
        urls: [],
        credentialType: 'token'
      }] }));
  }, 'with credentialType token should throw TypeError');

  // Blink and Gecko fall back to url, but it's not in the spec.
  config_test(makePc => {
    assert_throws_js(TypeError, () =>
      makePc({ iceServers: [{
        url: 'stun:stun1.example.net'
      }] }));
  }, 'with url field should throw TypeError');

  /*
    4.3.2.  To set a configuration
      11.5. If scheme name is turn or turns, and server.credentialType is "password",
            and server.credential is not a DOMString, then throw an InvalidAccessError
            and abort these steps.
   */
  config_test(makePc => {
    assert_throws_dom('InvalidAccessError', () =>
      makePc({ iceServers: [{
        urls: 'turns:turn.example.org',
        credentialType: 'password',
        username: 'user',
        credential: {
          macKey: '',
          accessToken: ''
        }
      }] }));
  }, 'with turns server, credentialType password, and RTCOauthCredential credential should throw InvalidAccessError');

  /*
    4.3.2.  To set a configuration
      11.6. If scheme name is turn or turns, and server.credentialType is "oauth",
            and server.credential is not an RTCOAuthCredential, then throw an
            InvalidAccessError and abort these steps.
   */
  config_test(makePc => {
    assert_throws_dom('InvalidAccessError', () =>
      makePc({ iceServers: [{
        urls: 'turns:turn.example.org',
        credentialType: 'oauth',
        username: 'user',
        credential: 'cred'
      }] }));
  }, 'with turns server, credentialType oauth, and string credential should throw InvalidAccessError');

  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: 'turns:turn.example.org',
      credentialType: 'oauth',
      username: 'user',
      credential: {
        macKey: 'mac',
        accessToken: 'token'
      }
    }] });

    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.credentialType, 'oauth');
    assert_equals(server.username, 'user');

    const { credential } = server;
    assert_equals(credential.macKey, 'mac');
    assert_equals(credential.accessToken, 'token');

  }, `with turns server, credentialType oauth and RTCOAuthCredential credential should succeed`);

  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: ['turns:turn.example.org', 'stun:stun1.example.net'],
      credentialType: 'oauth',
      username: 'user',
      credential: {
        macKey: 'mac',
        accessToken: 'token'
      }
    }] });

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

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

    const { credential } = server;
    assert_equals(credential.macKey, 'mac');
    assert_equals(credential.accessToken, 'token');

  }, `with both turns and stun server, credentialType oauth and RTCOAuthCredential credential should succeed`);

  // credential type validation is ignored when scheme name is stun
  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: 'stun:stun1.example.net',
      credentialType: 'oauth',
      username: 'user',
      credential: 'cred'
    }] });

    const { iceServers } = pc.getConfiguration();
    assert_equals(iceServers.length, 1);
    const server = iceServers[0];

    assert_array_equals(server.urls, ['stun:stun1.example.net']);
    assert_equals(server.credentialType, 'oauth');
    assert_equals(server.username, 'user');
    assert_equals(server.credential, 'cred');

  }, 'with stun server, credentialType oauth, and string credential should succeed');

  // credential type validation is ignored when scheme name is stun
  config_test(makePc => {
    const pc = makePc({ iceServers: [{
      urls: 'stun:stun1.example.net',
      credentialType: 'password',
      username: 'user',
      credential: {
        macKey: '',
        accessToken: ''
      }
    }] });

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

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

    const { credential } = server;
    assert_equals(credential.macKey, '');
    assert_equals(credential.accessToken, '');

  }, 'with stun server, credentialType password, and RTCOAuthCredential credential should succeed');

  /*
    Tested
      4.3.2.  To set a configuration
        11.1-6.

    Untestable
      4.3.2.  To set a configuration
        11.7.  Append server to validatedServers.

    Coverage Report
      Tested         9
      Not Tested     0
      Untestable     1
      Total         10
   */

</script>
