4 <title>Test EME syntax</title>
5 <script src="encrypted-media-utils.js"></script>
6 <script src="../../resources/testharness.js"></script>
7 <script src="../../resources/testharnessreport.js"></script>
12 // Since promises catch any exception and convert it into a
13 // rejected Promise, there is no current way to have the W3C
14 // test framework report a failed test. For now, simply force
15 // a timeout to indicate failure.
16 // FIXME: Once W3C test framework handles Promises, fix this.
18 // This function checks that calling |testCase.func| returns a
19 // rejected Promise with the error.name equal to
20 // |testCase.exception|.
21 function test_exception(testCase /*...*/)
23 var func = testCase.func;
24 var exception = testCase.exception;
25 var args = Array.prototype.slice.call(arguments, 1);
27 // Currently blink throws for TypeErrors rather than returning
28 // a rejected promise (http://crbug.com/359386).
29 // FIXME: Remove try/catch once they become failed promises.
31 return func.apply(null, args).then(
34 assert_unreached(format_value(func));
38 assert_equals(error.name, exception, format_value(func));
39 assert_not_equals(error.message, "", format_value(func));
43 // Only allow 'TypeError' exceptions to be thrown.
44 // Everything else should be a failed promise.
45 assert_equals('TypeError', exception, format_value(func));
46 assert_equals(e.name, exception, format_value(func));
50 var kRequestMediaKeySystemAccessExceptionsTestCases = [
51 // Too few parameters.
53 exception: 'TypeError',
54 func: function() { return navigator.requestMediaKeySystemAccess(); }
56 // Invalid parameters.
58 exception: 'InvalidAccessError',
59 func: function() { return navigator.requestMediaKeySystemAccess(''); }
61 // Invalid key systems. Note that JavaScript converts all these
62 // values into strings by calling toString(), so they fail due
63 // to the key system not being supported, not due to the type.
65 exception: 'NotSupportedError',
66 func: function() { return navigator.requestMediaKeySystemAccess(null); }
69 exception: 'NotSupportedError',
70 func: function() { return navigator.requestMediaKeySystemAccess(undefined); }
73 exception: 'NotSupportedError',
74 func: function() { return navigator.requestMediaKeySystemAccess(1); }
77 exception: 'NotSupportedError',
78 func: function() { return navigator.requestMediaKeySystemAccess(new Uint8Array(0)); }
81 exception: 'NotSupportedError',
82 func: function() { return navigator.requestMediaKeySystemAccess('unsupported'); }
86 exception: 'NotSupportedError',
87 func: function() { return navigator.requestMediaKeySystemAccess('org.w3\u263A.clearkey'); }
91 async_test(function(test)
93 var createPromises = kRequestMediaKeySystemAccessExceptionsTestCases.map(function(testCase) {
94 return test_exception(testCase);
97 Promise.all(createPromises).then(function(result) {
99 }).catch(function(error) {
100 forceTestFailureFromPromise(test, error, 'requestMediaKeySystemAccess() tests failed');
102 }, 'Test Navigator.requestMediaKeySystemAccess() exceptions.');
104 async_test(function(test)
106 assert_equals(typeof navigator.requestMediaKeySystemAccess, 'function');
107 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
108 assert_not_equals(access, null);
109 assert_equals(typeof access, 'object');
110 assert_equals(access.keySystem, 'org.w3.clearkey');
111 assert_equals(typeof access.createMediaKeys, 'function');
113 }).catch(function(error) {
114 forceTestFailureFromPromise(test, error, 'requestMediaKeySystemAccess() tests failed');
116 }, 'Test Navigator.requestMediaKeySystemAccess().');
118 async_test(function(test)
122 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(result) {
124 assert_equals(access.keySystem, 'org.w3.clearkey');
125 return access.createMediaKeys();
126 }).then(function(mediaKeys) {
127 assert_not_equals(mediaKeys, null);
128 assert_equals(typeof mediaKeys, 'object');
129 assert_equals(typeof mediaKeys.createSession, 'function');
130 assert_equals(typeof mediaKeys.setServerCertificate, 'function');
132 // Test creation of a second MediaKeys.
133 // The extra parameter is ignored.
134 return access.createMediaKeys('extra');
135 }).then(function(mediaKeys) {
136 assert_not_equals(mediaKeys, null);
137 assert_equals(typeof mediaKeys, 'object');
138 assert_equals(typeof mediaKeys.createSession, 'function');
139 assert_equals(typeof mediaKeys.setServerCertificate, 'function');
141 }).catch(function(error) {
142 forceTestFailureFromPromise(test, error, 'create() tests failed');
144 }, 'Test MediaKeys create().');
146 var kCreateSessionExceptionsTestCases = [
147 // Tests in this set use a shortened parameter name due to
148 // format_value() only returning the first 60 characters as the
149 // result. With a longer name the first 60 characters is not
150 // enough to determine which test failed.
152 // Invalid parameters.
154 exception: 'TypeError',
155 func: function(mk) { return mk.createSession(); }
158 exception: 'TypeError',
159 func: function(mk) { return mk.createSession(''); }
162 exception: 'TypeError',
163 func: function(mk) { return mk.createSession(null); }
166 exception: 'TypeError',
167 func: function(mk) { return mk.createSession(undefined); }
170 exception: 'TypeError',
171 func: function(mk) { return mk.createSession(1); }
174 exception: 'TypeError',
175 func: function(mk) { return mk.createSession(new Uint8Array(0)); }
178 exception: 'TypeError',
179 func: function(mk) { return mk.createSession('TEMPORARY'); }
183 async_test(function(test)
185 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
186 return access.createMediaKeys();
187 }).then(function(mediaKeys) {
188 var sessionPromises = kCreateSessionExceptionsTestCases.map(function(testCase) {
189 return test_exception(testCase, mediaKeys);
192 assert_not_equals(sessionPromises.length, 0);
193 return Promise.all(sessionPromises);
194 }).then(function(result) {
196 }).catch(function(error) {
197 forceTestFailureFromPromise(test, error, 'createSession() tests failed');
199 }, 'Test MediaKeys createSession() exceptions.');
201 var kGenerateRequestExceptionsTestCases = [
202 // Tests in this set use a shortened parameter name due to
203 // format_value() only returning the first 60 characters as the
204 // result. With a longer name the first 60 characters is not
205 // enough to determine which test failed. Even with the
206 // shortened name, the error message for the last couple of
207 // tests is the same.
208 // Too few parameters.
210 exception: 'TypeError',
211 func: function(mk1) { return mk1.createSession().generateRequest(); }
214 exception: 'TypeError',
215 func: function(mk2) { return mk2.createSession().generateRequest(''); }
218 exception: 'TypeError',
219 func: function(mk3) { return mk3.createSession().generateRequest(null); }
222 exception: 'TypeError',
223 func: function(mk4) { return mk4.createSession().generateRequest(undefined); }
226 exception: 'TypeError',
227 func: function(mk5) { return mk5.createSession().generateRequest(1); }
230 exception: 'TypeError',
231 func: function(mk6) { return mk6.createSession().generateRequest(new Uint8Array(0)); }
234 exception: 'TypeError',
235 func: function(mk7, _, initData) { return mk7.createSession().generateRequest(initData); }
237 // Invalid parameters.
239 exception: 'InvalidAccessError',
240 func: function(mk8, _, initData) { return mk8.createSession().generateRequest('', initData); }
242 // Not supported initDataTypes.
244 exception: 'NotSupportedError',
245 func: function(mk9, _, initData) { return mk9.createSession().generateRequest(null, initData); }
248 exception: 'NotSupportedError',
249 func: function(mk10, _, initData) { return mk10.createSession().generateRequest(undefined, initData); }
252 exception: 'NotSupportedError',
253 func: function(mk11, _, initData) { return mk11.createSession().generateRequest(1, initData); }
256 exception: 'NotSupportedError',
257 func: function(mk12, _, initData) { return mk12.createSession().generateRequest(new Uint8Array(0), initData); }
260 exception: 'NotSupportedError',
261 func: function(mk13, _, initData) { return mk13.createSession().generateRequest('unsupported', initData); }
264 exception: 'NotSupportedError',
265 func: function(mk14, _, initData) { return mk14.createSession().generateRequest('video/foo', initData); }
268 exception: 'NotSupportedError',
269 func: function(mk15, _, initData) { return mk15.createSession().generateRequest('text/webm', initData); }
271 // FIXME: Enable when switching to initDataType from MIME type.
272 // http://crbug.com/385874.
274 // exception: 'NotSupportedError',
275 // func: function(mk16, _, initData) { return mk16.createSession('video/webm', initData); }
279 var kTypeSpecificGenerateRequestExceptionsTestCases = [
280 // Tests in this set use a shortened parameter name due to
281 // format_value() only returning the first 60 characters as the
282 // result. With a longer name the first 60 characters is not
283 // enough to determine which test failed. Even with the
284 // shortened name, the error message for the last couple of
285 // tests is the same.
287 // Too few parameters.
289 exception: 'TypeError',
290 func: function(mk1, type) { return mk1.createSession().generateRequest(type); }
292 // Invalid parameters.
294 exception: 'TypeError',
295 func: function(mk2, type) { return mk2.createSession().generateRequest(type, ''); }
298 exception: 'TypeError',
299 func: function(mk3, type) { return mk3.createSession().generateRequest(type, null); }
302 exception: 'TypeError',
303 func: function(mk4, type) { return mk4.createSession().generateRequest(type, undefined); }
306 exception: 'TypeError',
307 func: function(mk5, type) { return mk5.createSession().generateRequest(type, 1); }
310 exception: 'InvalidAccessError',
311 func: function(mk6, type) { return mk6.createSession().generateRequest(type, new Uint8Array(0)); }
315 async_test(function(test)
317 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
318 return access.createMediaKeys();
319 }).then(function(mediaKeys) {
320 // FIXME: Remove "video/" from the calls to isTypeSupported() once it is updated.
321 // http://crbug.com/405731.
322 var initData = stringToUint8Array('init data');
323 var sessionPromises = kGenerateRequestExceptionsTestCases.map(function(testCase) {
324 return test_exception(testCase, mediaKeys, '', initData);
327 // Test that WebM sessions generate the expected error, if
329 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
330 var WebmSessionPromises = kTypeSpecificGenerateRequestExceptionsTestCases.map(function(testCase) {
331 return test_exception(testCase, mediaKeys, 'webm', getInitData('webm'));
333 sessionPromises = sessionPromises.concat(WebmSessionPromises);
336 // Repeat for MP4, if supported.
337 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
338 var mp4SessionPromises = kTypeSpecificGenerateRequestExceptionsTestCases.map(function(testCase) {
339 return test_exception(testCase, mediaKeys, 'cenc', getInitData('cenc'));
341 sessionPromises = sessionPromises.concat(mp4SessionPromises);
344 assert_not_equals(sessionPromises.length, 0);
345 return Promise.all(sessionPromises);
346 }).then(function(result) {
348 }).catch(function(error) {
349 forceTestFailureFromPromise(test, error, 'generateRequest() tests failed');
351 }, 'Test MediaKeys generateRequest() exceptions.');
353 var kLoadExceptionsTestCases = [
354 // Too few parameters.
356 exception: 'TypeError',
357 func: function(mk1) { return mk1.createSession('temporary').load(); }
360 exception: 'TypeError',
361 func: function(mk2) { return mk2.createSession('persistent').load(); }
363 // Invalid parameters.
364 // 'temporary' sessions are never allowed, so always return
365 // 'InvalidAccessError'. For 'persistent' sessions, JS calls
366 // .toString() on the parameter if it is not already a string
367 // before passing it to code. So tests like mk6 or mk8 pass in
368 // "null" or "undefined" as the sessionId.
370 exception: 'InvalidAccessError',
371 func: function(mk3) { return mk3.createSession('temporary').load(''); }
374 exception: 'InvalidAccessError',
375 func: function(mk4) { return mk4.createSession('persistent').load(''); }
378 exception: 'InvalidAccessError',
379 func: function(mk5) { return mk5.createSession('temporary').load(null); }
382 exception: 'NotSupportedError',
383 func: function(mk6) { return mk6.createSession('persistent').load(null); }
386 exception: 'InvalidAccessError',
387 func: function(mk7) { return mk7.createSession('temporary').load(undefined); }
390 exception: 'NotSupportedError',
391 func: function(mk8) { return mk8.createSession('persistent').load(undefined); }
394 exception: 'InvalidAccessError',
395 func: function(mk9) { return mk9.createSession('temporary').load(1); }
398 exception: 'NotSupportedError',
399 func: function(mk10) { return mk10.createSession('persistent').load(1); }
402 exception: 'InvalidAccessError',
403 func: function(mk11) { return mk11.createSession('temporary').load(new Uint8Array(0)); }
406 exception: 'InvalidAccessError',
407 func: function(mk12) { return mk12.createSession('persistent').load(new Uint8Array(0)); }
409 // Invalid session id.
411 exception: 'InvalidAccessError',
412 func: function(mk13) { return mk13.createSession('temporary').load('!@#$%^&*()'); }
415 exception: 'InvalidAccessError',
416 func: function(mk14) { return mk14.createSession('persistent').load('!@#$%^&*()'); }
418 // Valid session id (but not supported by ClearKey).
420 exception: 'InvalidAccessError',
421 func: function(mk15) { return mk15.createSession('temporary').load('1234'); }
424 exception: 'NotSupportedError',
425 func: function(mk16) { return mk16.createSession('persistent').load('1234'); }
429 async_test(function(test)
431 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
432 return access.createMediaKeys();
433 }).then(function(mediaKeys) {
434 // FIXME: Remove "video/" from the calls to isTypeSupported() once it is updated.
435 // http://crbug.com/405731.
436 var initData = stringToUint8Array('init data');
437 var sessionPromises = kLoadExceptionsTestCases.map(function(testCase) {
438 return test_exception(testCase, mediaKeys);
441 assert_not_equals(sessionPromises.length, 0);
442 return Promise.all(sessionPromises);
443 }).then(function(result) {
445 }).catch(function(error) {
446 forceTestFailureFromPromise(test, error, 'load() tests failed');
448 }, 'Test MediaKeys load() exceptions.');
450 // All calls to |func| in this group are supposed to succeed.
451 // However, the spec notes that some things are optional for
452 // Clear Key. In particular, support for persistent sessions
453 // is optional. Since some implementations won't support some
454 // features, a NotSupportedError is treated as a success
455 // if |isNotSupportedAllowed| is true.
456 var kCreateSessionTestCases = [
457 // Use the default sessionType.
459 func: function(mk) { return mk.createSession(); },
460 isNotSupportedAllowed: false
462 // Try variations of sessionType.
464 func: function(mk) { return mk.createSession('temporary'); },
465 isNotSupportedAllowed: false
468 func: function(mk) { return mk.createSession(undefined); },
469 isNotSupportedAllowed: false
472 // Since this is optional, some Clear Key implementations
473 // will succeed, others will return a "NotSupportedError".
474 // Both are allowed results.
475 func: function(mk) { return mk.createSession('persistent'); },
476 isNotSupportedAllowed: true
478 // Try additional parameter, which should be ignored.
480 func: function(mk) { return mk.createSession('temporary', 'extra'); },
481 isNotSupportedAllowed: false
485 // This function checks that calling |testCase.func| creates a
486 // MediaKeySession object with some default values. It also
487 // allows for an NotSupportedError to be generated and treated as a
488 // success, if allowed. See comment above kCreateSessionTestCases.
489 function test_createSession(testCase, mediaKeys)
493 mediaKeySession = testCase.func.call(null, mediaKeys);
495 assert_true(testCase.isNotSupportedAllowed);
499 // FIXME: Update this set of tests when done
500 // implementing the latest spec.
501 assert_equals(typeof mediaKeySession, 'object');
502 assert_equals(typeof mediaKeySession.addEventListener, 'function');
503 assert_equals(typeof mediaKeySession.generateRequest, 'function');
504 assert_equals(typeof mediaKeySession.update, 'function');
505 assert_equals(typeof mediaKeySession.close, 'function');
506 assert_equals(typeof mediaKeySession.remove, 'function');
507 assert_equals(mediaKeySession.error, null);
508 assert_equals(mediaKeySession.sessionId, '');
509 assert_equals(typeof mediaKeySession.sessionId, 'string');
510 assert_equals(typeof mediaKeySession.onopen, 'undefined');
511 assert_equals(typeof mediaKeySession.onmessage, 'undefined');
512 assert_equals(typeof mediaKeySession.onclose, 'undefined');
513 assert_equals(typeof mediaKeySession.onerror, 'undefined');
516 async_test(function(test)
518 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
519 return access.createMediaKeys();
520 }).then(function(mediaKeys) {
521 kCreateSessionTestCases.map(function(testCase) {
522 test_createSession(testCase, mediaKeys);
525 }).catch(function(error) {
526 forceTestFailureFromPromise(test, error, 'createSession() tests failed');
528 }, 'Test MediaKeys createSession().');
530 // This function checks that calling generateRequest() works for
531 // various sessions. |testCase.func| creates a MediaKeySession
532 // object, and then generateRequest() is called on that object. It
533 // allows for an NotSupportedError to be generated and treated as a
534 // success, if allowed. See comment above kCreateSessionTestCases.
535 function test_generateRequest(testCase, mediaKeys, type, initData)
539 mediaKeySession = testCase.func.call(null, mediaKeys);
541 assert_true(testCase.isNotSupportedAllowed);
542 return new Promise(new Promise(function() {}));
544 return mediaKeySession.generateRequest(type, initData);
547 async_test(function(test)
549 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
550 return access.createMediaKeys();
551 }).then(function(mediaKeys) {
552 var sessionPromises = [];
554 // Test that WebM sessions generate the expected error, if
556 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
557 var WebmSessionPromises = kCreateSessionTestCases.map(function(testCase) {
558 return test_generateRequest(testCase, mediaKeys, 'webm', getInitData('webm'));
560 sessionPromises = sessionPromises.concat(WebmSessionPromises);
563 // Repeat for MP4, if supported.
564 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
565 var mp4SessionPromises = kCreateSessionTestCases.map(function(testCase) {
566 return test_generateRequest(testCase, mediaKeys, 'cenc', getInitData('cenc'));
568 sessionPromises = sessionPromises.concat(mp4SessionPromises);
571 assert_not_equals(sessionPromises.length, 0);
572 return Promise.all(sessionPromises);
573 }).then(function(result) {
575 }).catch(function(error) {
576 forceTestFailureFromPromise(test, error, 'generateRequest() tests failed');
578 }, 'Test MediaKeys generateRequest().');
580 var kUpdateSessionExceptionsTestCases = [
581 // Tests in this set use a shortened parameter name due to
582 // format_value() only returning the first 60 characters as the
583 // result. With a longer name (mediaKeySession) the first 60
584 // characters is not enough to determine which test failed.
586 // Too few parameters.
588 exception: 'TypeError',
589 func: function(s) { return s.update(); }
591 // Invalid parameters.
593 exception: 'TypeError',
594 func: function(s) { return s.update(''); }
597 exception: 'TypeError',
598 func: function(s) { return s.update(null); }
601 exception: 'TypeError',
602 func: function(s) { return s.update(undefined); }
605 exception: 'TypeError',
606 func: function(s) { return s.update(1); }
609 exception: 'InvalidAccessError',
610 func: function(s) { return s.update(new Uint8Array(0)); }
614 async_test(function(test)
616 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
617 return access.createMediaKeys();
618 }).then(function(mediaKeys) {
621 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
622 var WebmSessionPromises = kUpdateSessionExceptionsTestCases.map(function(testCase) {
623 var mediaKeySession = mediaKeys.createSession();
624 return mediaKeySession.generateRequest('webm', getInitData('webm')).then(function(result) {
625 return test_exception(testCase, mediaKeySession);
628 promises = promises.concat(WebmSessionPromises);
631 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
632 var mp4SessionPromises = kUpdateSessionExceptionsTestCases.map(function(testCase) {
633 var mediaKeySession = mediaKeys.createSession();
634 return mediaKeySession.generateRequest('cenc', getInitData('cenc')).then(function(result) {
635 return test_exception(testCase, mediaKeySession);
638 promises = promises.concat(mp4SessionPromises);
641 assert_not_equals(promises.length, 0);
642 return Promise.all(promises);
643 }).then(function(result) {
645 }).catch(function(error) {
646 forceTestFailureFromPromise(test, error, 'update() tests failed');
648 }, 'Test MediaKeySession update() exceptions.');
650 function create_update_test(mediaKeys, type, initData)
652 var mediaKeySession = mediaKeys.createSession();
653 var promise = mediaKeySession.generateRequest(type, initData).then(function(result) {
654 var validLicense = stringToUint8Array(createJWKSet(createJWK(stringToUint8Array('123'), stringToUint8Array('1234567890abcdef'))));
655 return mediaKeySession.update(validLicense);
656 }).then(function(result) {
657 // Call update() with a different license and an extra
658 // parameter. The extra parameter is ignored.
659 var validLicense = stringToUint8Array(createJWKSet(createJWK(stringToUint8Array('4567890'), stringToUint8Array('01234567890abcde'))));
660 return mediaKeySession.update(validLicense, 'extra');
665 async_test(function(test)
667 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
668 return access.createMediaKeys();
669 }).then(function(mediaKeys) {
672 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
673 promises.push(create_update_test(mediaKeys, 'webm', getInitData('webm')));
676 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
677 promises.push(create_update_test(mediaKeys, 'cenc', getInitData('cenc')));
680 assert_not_equals(promises.length, 0);
681 return Promise.all(promises);
682 }).then(function(result) {
684 }).catch(function(error) {
685 forceTestFailureFromPromise(test, error, 'update() tests failed');
687 }, 'Test MediaKeySession update().');
689 function create_close_exception_test(mediaKeys, type, initData)
691 var mediaKeySession = mediaKeys.createSession();
692 return mediaKeySession.close().then(function(result) {
693 assert_unreached('close() should not succeed if session uninitialized');
694 }).catch(function(error) {
695 assert_equals(error.name, 'InvalidStateError');
696 // Return something so the promise resolves.
697 return Promise.resolve();
701 async_test(function(test)
703 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
704 return access.createMediaKeys();
705 }).then(function(mediaKeys) {
708 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
709 promises.push(create_close_exception_test(mediaKeys, 'webm', getInitData('webm')));
712 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
713 promises.push(create_close_exception_test(mediaKeys, 'cenc', getInitData('cenc')));
716 assert_not_equals(promises.length, 0);
717 return Promise.all(promises);
718 }).then(function(result) {
720 }).catch(function(error) {
721 forceTestFailureFromPromise(test, error, 'close() exception tests failed');
723 }, 'Test MediaKeySession close() exceptions.');
726 function create_close_test(mediaKeys, type, initData)
728 var mediaKeySession = mediaKeys.createSession();
729 var promise = mediaKeySession.generateRequest(type, initData).then(function(result) {
730 return mediaKeySession.close();
731 }).then(function(result) {
732 // Call close() again with an extra parameter. The extra
733 // parameter is ignored.
734 return mediaKeySession.close('extra');
739 async_test(function(test)
741 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
742 return access.createMediaKeys();
743 }).then(function(mediaKeys) {
746 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
747 promises.push(create_close_test(mediaKeys, 'webm', getInitData('webm')));
750 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
751 promises.push(create_close_test(mediaKeys, 'cenc', getInitData('cenc')));
754 assert_not_equals(promises.length, 0);
755 return Promise.all(promises);
756 }).then(function(result) {
758 }).catch(function(error) {
759 forceTestFailureFromPromise(test, error, 'close() tests failed');
761 }, 'Test MediaKeySession close().');
763 function create_remove_exception_test(mediaKeys, type, initData)
765 // remove() on an uninitialized session should fail.
766 var mediaKeySession = mediaKeys.createSession('temporary');
767 return mediaKeySession.remove().then(function(result) {
768 assert_unreached('remove() should not succeed if session uninitialized');
769 }).catch(function(error) {
770 assert_equals(error.name, 'InvalidStateError');
772 // remove() on a temporary session should fail.
773 return mediaKeySession.generateRequest(type, initData);
774 }).then(function(result) {
775 return mediaKeySession.remove();
776 }).then(function(result) {
777 assert_unreached('remove() should not succeed for temporary sessions');
778 }).catch(function(error) {
779 assert_equals(error.name, 'InvalidAccessError');
781 // remove() on a closed persistent session should also fail.
782 mediaKeySession = mediaKeys.createSession('persistent');
783 return mediaKeySession.generateRequest(type, initData);
784 }).then(function(result) {
785 return mediaKeySession.close();
786 }).then(function(result) {
787 return mediaKeySession.remove();
788 }).then(function(result) {
789 assert_unreached('remove() should not succeed for closed persistent sessions');
790 }).catch(function(error) {
791 assert_equals(error.name, 'InvalidStateError');
793 // Return something so the promise resolves.
794 return Promise.resolve();
798 async_test(function(test)
800 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
801 return access.createMediaKeys();
802 }).then(function(mediaKeys) {
805 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
806 promises.push(create_remove_exception_test(mediaKeys, 'webm', getInitData('webm')));
809 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
810 promises.push(create_remove_exception_test(mediaKeys, 'cenc', getInitData('cenc')));
813 assert_not_equals(promises.length, 0);
814 return Promise.all(promises);
815 }).then(function(result) {
817 }).catch(function(error) {
818 forceTestFailureFromPromise(test, error, 'remove() exception tests failed');
820 }, 'Test MediaKeySession remove() exceptions.');
822 function create_remove_test(mediaKeys, type, initData)
824 // ClearKey may not support persistent sessions.
827 mediaKeySession = mediaKeys.createSession('persistent');
829 // Not supported, so return a resolved promise.
830 assert_equals(error.name, 'NotSupportedError');
831 return Promise.resolve();
833 return mediaKeySession.generateRequest(type, initData).then(function(result) {
834 return mediaKeySession.remove();
838 async_test(function(test)
840 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
841 return access.createMediaKeys();
842 }).then(function(mediaKeys) {
845 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
846 promises.push(create_remove_test(mediaKeys, 'webm', getInitData('webm')));
849 if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
850 promises.push(create_remove_test(mediaKeys, 'cenc', getInitData('cenc')));
853 assert_not_equals(promises.length, 0);
854 return Promise.all(promises);
855 }).then(function(result) {
857 }).catch(function(error) {
858 forceTestFailureFromPromise(test, error, 'remove() tests failed');
860 }, 'Test MediaKeySession remove().');
862 var kSetServerCertificateExceptionsTestCases = [
863 // Too few parameters.
865 exception: 'TypeError',
866 func: function(mk) { return mk.setServerCertificate(); }
868 // Invalid parameters.
870 exception: 'TypeError',
871 func: function(mk) { return mk.setServerCertificate(''); }
874 exception: 'TypeError',
875 func: function(mk) { return mk.setServerCertificate(null); }
878 exception: 'TypeError',
879 func: function(mk) { return mk.setServerCertificate(undefined); }
882 exception: 'TypeError',
883 func: function(mk) { return mk.setServerCertificate(1); }
887 exception: 'InvalidAccessError',
888 func: function(mk) { return mk.setServerCertificate(new Uint8Array(0)); }
890 // Valid calls, but not supported by ClearKey.
892 exception: 'NotSupportedError',
893 func: function(mk) { var cert = new Uint8Array(200); assert_true(ArrayBuffer.isView(cert)); return mk.setServerCertificate(cert); }
896 // Pass in ArrayBuffer
897 exception: 'NotSupportedError',
898 func: function(mk) { var cert = new Uint8Array(200); assert_false(ArrayBuffer.isView(cert.buffer)); return mk.setServerCertificate(cert.buffer); }
902 async_test(function(test)
904 navigator.requestMediaKeySystemAccess('org.w3.clearkey').then(function(access) {
905 return access.createMediaKeys();
906 }).then(function(mediaKeys) {
907 var promises = kSetServerCertificateExceptionsTestCases.map(function(testCase) {
908 return test_exception(testCase, mediaKeys);
911 assert_not_equals(promises.length, 0);
912 return Promise.all(promises);
913 }).then(function(result) {
915 }).catch(function(error) {
916 forceTestFailureFromPromise(test, error, 'setServerCertificate() exception tests failed');
918 }, 'Test MediaKeys setServerCertificate() exceptions.');
920 // FIXME: Add test for successful setServerCertificate(). Note that
921 // ClearKey does not support it.
923 // FIXME: Add syntax checks for MediaKeys.IsTypeSupported().
924 // FIXME: Add syntax checks for MediaKeyError and MediaKeySession events.
925 // FIXME: Add HTMLMediaElement syntax checks, e.g. setMediaKeys, mediakeys, onencrypted.