mirror of
https://github.com/servo/servo.git
synced 2025-07-01 20:43:39 +01:00
570 lines
18 KiB
HTML
570 lines
18 KiB
HTML
<!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 => {
|
|
assert_throws(new 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(new TypeError(), () =>
|
|
makePc({ iceServers: [null] }));
|
|
}, '{ iceServers: [null] } should throw TypeError');
|
|
|
|
config_test(makePc => {
|
|
assert_throws(new TypeError(), () =>
|
|
makePc({ iceServers: [undefined] }));
|
|
}, '{ iceServers: [undefined] } should throw TypeError');
|
|
|
|
config_test(makePc => {
|
|
assert_throws(new TypeError(), () =>
|
|
makePc({ iceServers: [{}] }));
|
|
}, '{ iceServers: [{}] } should throw TypeError');
|
|
|
|
config_test(makePc => {
|
|
const pc = makePc({ iceServers: [{
|
|
urls: []
|
|
}] });
|
|
|
|
const { iceServers } = pc.getConfiguration();
|
|
assert_equals(iceServers.length, 1);
|
|
|
|
const server = iceServers[0];
|
|
assert_array_equals(server.urls, []);
|
|
assert_equals(server.credentialType, 'password');
|
|
}, 'with empty list urls 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 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 = new RTCPeerConnection({ 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('InvalidAccessError', () =>
|
|
makePc({ iceServers: [{
|
|
urls: 'turn:turn.example.net'
|
|
}] }));
|
|
}, 'with turn server and no credentials should throw InvalidAccessError');
|
|
|
|
config_test(makePc => {
|
|
assert_throws('InvalidAccessError', () =>
|
|
makePc({ iceServers: [{
|
|
urls: 'turn:turn.example.net',
|
|
username: 'user'
|
|
}] }));
|
|
}, 'with turn server and only username should throw InvalidAccessError');
|
|
|
|
config_test(makePc => {
|
|
assert_throws('InvalidAccessError', () =>
|
|
makePc({ iceServers: [{
|
|
urls: 'turn:turn.example.net',
|
|
credential: 'cred'
|
|
}] }));
|
|
}, 'with turn server and only credential should throw InvalidAccessError');
|
|
|
|
config_test(makePc => {
|
|
assert_throws('InvalidAccessError', () =>
|
|
makePc({ iceServers: [{
|
|
urls: 'turns:turn.example.net'
|
|
}] }));
|
|
}, 'with turns server and no credentials should throw InvalidAccessError');
|
|
|
|
config_test(makePc => {
|
|
assert_throws('InvalidAccessError', () =>
|
|
makePc({ iceServers: [{
|
|
urls: 'turns:turn.example.net',
|
|
username: 'user'
|
|
}] }));
|
|
}, 'with turns server and only username should throw InvalidAccessError');
|
|
|
|
config_test(makePc => {
|
|
assert_throws('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('SyntaxError', () =>
|
|
makePc({ iceServers: [{
|
|
urls: 'relative-url'
|
|
}] }));
|
|
}, 'with relative url should throw SyntaxError');
|
|
|
|
config_test(makePc => {
|
|
assert_throws('SyntaxError', () =>
|
|
makePc({ iceServers: [{
|
|
urls: 'http://example.com'
|
|
}] }));
|
|
}, 'with http url should throw SyntaxError');
|
|
|
|
config_test(makePc => {
|
|
assert_throws('SyntaxError', () =>
|
|
makePc({ iceServers: [{
|
|
urls: 'turn://example.org/foo?x=y'
|
|
}] }));
|
|
}, 'with invalid turn url should throw SyntaxError');
|
|
|
|
config_test(makePc => {
|
|
assert_throws('SyntaxError', () =>
|
|
makePc({ iceServers: [{
|
|
urls: 'stun://example.org/foo?x=y'
|
|
}] }));
|
|
}, 'with invalid stun url should throw SyntaxError');
|
|
|
|
config_test(makePc => {
|
|
const pc = makePc({ iceServers: [{
|
|
urls: [],
|
|
credentialType: 'password'
|
|
}] });
|
|
|
|
const { iceServers } = pc.getConfiguration();
|
|
assert_equals(iceServers.length, 1);
|
|
|
|
const server = iceServers[0];
|
|
assert_array_equals(server.urls, []);
|
|
assert_equals(server.credentialType, 'password');
|
|
}, `with empty urls and credentialType password should succeed`);
|
|
|
|
config_test(makePc => {
|
|
const pc = makePc({ iceServers: [{
|
|
urls: [],
|
|
credentialType: 'oauth'
|
|
}] });
|
|
|
|
const { iceServers } = pc.getConfiguration();
|
|
assert_equals(iceServers.length, 1);
|
|
|
|
const server = iceServers[0];
|
|
assert_array_equals(server.urls, []);
|
|
assert_equals(server.credentialType, 'oauth');
|
|
}, `with empty urls and credentialType oauth should succeed`);
|
|
|
|
config_test(makePc => {
|
|
assert_throws(new 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(new 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(new 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('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('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');
|
|
|
|
// credential type validation is ignored when urls is empty and there is no scheme name
|
|
config_test(makePc => {
|
|
const pc = makePc({ iceServers: [{
|
|
urls: [],
|
|
credentialType: 'oauth',
|
|
username: 'user',
|
|
credential: 'cred'
|
|
}] });
|
|
|
|
const { iceServers } = pc.getConfiguration();
|
|
assert_equals(iceServers.length, 1);
|
|
const server = iceServers[0];
|
|
|
|
assert_array_equals(server.urls, []);
|
|
assert_equals(server.credentialType, 'oauth');
|
|
assert_equals(server.username, 'user');
|
|
assert_equals(server.credential, 'cred');
|
|
|
|
}, 'with empty urls list, credentialType oauth, and string credential should succeed');
|
|
|
|
// credential type validation is ignored when urls is empty and there is no scheme name
|
|
config_test(makePc => {
|
|
const pc = makePc({ iceServers: [{
|
|
urls: [],
|
|
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, []);
|
|
assert_equals(server.credentialType, 'password');
|
|
assert_equals(server.username, 'user');
|
|
|
|
const { credential } = server;
|
|
assert_equals(credential.macKey, '');
|
|
assert_equals(credential.accessToken, '');
|
|
|
|
}, 'with empty urls list, 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>
|