| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Test EME syntax</title> |
| <script src="encrypted-media-utils.js"></script> |
| <script src="../../resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| </head> |
| <body> |
| <script> |
| // Since promises catch any exception and convert it into a |
| // rejected Promise, there is no current way to have the W3C |
| // test framework report a failed test. For now, simply force |
| // a timeout to indicate failure. |
| // FIXME: Once W3C test framework handles Promises, fix this. |
| |
| // This function checks that calling |testCase.func| returns a |
| // rejected Promise with the error.name equal to |
| // |testCase.exception|. |
| function test_exception(testCase /*...*/) |
| { |
| var func = testCase.func; |
| var exception = testCase.exception; |
| var args = Array.prototype.slice.call(arguments, 1); |
| |
| // Currently blink throws for TypeErrors rather than returning |
| // a rejected promise (http://crbug.com/359386). |
| // FIXME: Remove try/catch once they become failed promises. |
| try { |
| return func.apply(null, args).then( |
| function(result) |
| { |
| assert_unreached(format_value(func)); |
| }, |
| function(error) |
| { |
| assert_equals(error.name, exception, format_value(func)); |
| assert_not_equals(error.message, "", format_value(func)); |
| } |
| ); |
| } catch (e) { |
| // Only allow 'TypeError' exceptions to be thrown. |
| // Everything else should be a failed promise. |
| assert_equals('TypeError', exception, format_value(func)); |
| assert_equals(e.name, exception, format_value(func)); |
| } |
| } |
| |
| var kRequestMediaKeySystemAccessExceptionsTestCases = [ |
| // Too few parameters. |
| { |
| exception: 'TypeError', |
| func: function() { return navigator.requestMediaKeySystemAccess(); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey'); } |
| }, |
| // Invalid key systems. Note that JavaScript converts all these |
| // values into strings by calling toString(), so they fail due |
| // to the key system not being supported, not due to the type. |
| { |
| exception: 'NotSupportedError', |
| func: function() { return navigator.requestMediaKeySystemAccess(null, [{}]); } |
| }, |
| { |
| exception: 'NotSupportedError', |
| func: function() { return navigator.requestMediaKeySystemAccess(undefined, [{}]); } |
| }, |
| { |
| exception: 'NotSupportedError', |
| func: function() { return navigator.requestMediaKeySystemAccess(1, [{}]); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function() { return navigator.requestMediaKeySystemAccess(new Uint8Array(0), [{}]); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function() { return navigator.requestMediaKeySystemAccess('', [{}]); } |
| }, |
| { |
| exception: 'NotSupportedError', |
| func: function() { return navigator.requestMediaKeySystemAccess('unsupported', [{}]); } |
| }, |
| // Non-ASCII names. |
| { |
| exception: 'NotSupportedError', |
| func: function() { return navigator.requestMediaKeySystemAccess('org.w3\u263A.clearkey', [{}]); } |
| }, |
| // Empty sequence of MediaKeySystemConfiguration. |
| { |
| exception: 'TypeError', |
| func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey', []); } |
| }, |
| // Invalid sequences of MediaKeySystemConfigurations. |
| { |
| exception: 'TypeError', |
| func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey', {}); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey', "invalid"); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{}, 6]); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function() { return navigator.requestMediaKeySystemAccess('org.w3.clearkey', ["invalid", "upsupported"]); } |
| } |
| ]; |
| |
| async_test(function(test) |
| { |
| var createPromises = kRequestMediaKeySystemAccessExceptionsTestCases.map(function(testCase) { |
| return test_exception(testCase); |
| }); |
| |
| Promise.all(createPromises).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'requestMediaKeySystemAccess() tests failed'); |
| }); |
| }, 'Test Navigator.requestMediaKeySystemAccess() exceptions.'); |
| |
| async_test(function(test) |
| { |
| assert_equals(typeof navigator.requestMediaKeySystemAccess, 'function'); |
| navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) { |
| assert_not_equals(access, null); |
| assert_equals(typeof access, 'object'); |
| assert_equals(access.keySystem, 'org.w3.clearkey'); |
| assert_equals(typeof access.getConfiguration, 'function'); |
| assert_equals(typeof access.createMediaKeys, 'function'); |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'requestMediaKeySystemAccess() tests failed'); |
| }); |
| }, 'Test Navigator.requestMediaKeySystemAccess().'); |
| |
| async_test(function(test) |
| { |
| var access; |
| |
| navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(result) { |
| access = result; |
| assert_equals(access.keySystem, 'org.w3.clearkey'); |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| assert_not_equals(mediaKeys, null); |
| assert_equals(typeof mediaKeys, 'object'); |
| assert_equals(typeof mediaKeys.createSession, 'function'); |
| assert_equals(typeof mediaKeys.setServerCertificate, 'function'); |
| |
| // Test creation of a second MediaKeys. |
| // The extra parameter is ignored. |
| return access.createMediaKeys('extra'); |
| }).then(function(mediaKeys) { |
| assert_not_equals(mediaKeys, null); |
| assert_equals(typeof mediaKeys, 'object'); |
| assert_equals(typeof mediaKeys.createSession, 'function'); |
| assert_equals(typeof mediaKeys.setServerCertificate, 'function'); |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'create() tests failed'); |
| }); |
| }, 'Test MediaKeySystemAccess createMediaKeys().'); |
| |
| var kCreateSessionExceptionsTestCases = [ |
| // Tests in this set use a shortened parameter name due to |
| // format_value() only returning the first 60 characters as the |
| // result. With a longer name the first 60 characters is not |
| // enough to determine which test failed. |
| |
| // Invalid parameters. |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.createSession(); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.createSession(''); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.createSession(null); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.createSession(undefined); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.createSession(1); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.createSession(new Uint8Array(0)); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.createSession('TEMPORARY'); } |
| } |
| ]; |
| |
| // This function checks that calling createSession() with an |
| // unsupported session type doesn't create a MediaKeySession object. |
| // Since requestMediaKeySystemAccess() is called without specifying |
| // persistent sessions, only temporary sessions will be allowed. |
| function test_unsupported_sessionType(mediaKeys) |
| { |
| var mediaKeySession = 'test'; |
| |
| try { |
| mediaKeySession = mediaKeys.createSession('persistent-license'); |
| assert_unreached('Session should not be created.'); |
| } catch (error) { |
| assert_equals(error.name, 'NotSupportedError'); |
| assert_not_equals(error.message, ""); |
| |
| // Since createSession() failed, |mediaKeySession| is not |
| // touched. |
| assert_equals(mediaKeySession, 'test'); |
| } |
| } |
| |
| async_test(function(test) |
| { |
| navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var sessionPromises = kCreateSessionExceptionsTestCases.map(function(testCase) { |
| return test_exception(testCase, mediaKeys); |
| }); |
| sessionPromises = sessionPromises.concat(test_unsupported_sessionType(mediaKeys)); |
| |
| assert_not_equals(sessionPromises.length, 0); |
| return Promise.all(sessionPromises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'createSession() tests failed'); |
| }); |
| }, 'Test MediaKeys createSession() exceptions.'); |
| |
| var kGenerateRequestExceptionsTestCases = [ |
| // Tests in this set use a shortened parameter name due to |
| // format_value() only returning the first 60 characters as the |
| // result. With a longer name the first 60 characters is not |
| // enough to determine which test failed. Even with the |
| // shortened name, the error message for the last couple of |
| // tests is the same. |
| // Too few parameters. |
| { |
| exception: 'TypeError', |
| func: function(mk1) { return mk1.createSession().generateRequest(); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk2) { return mk2.createSession().generateRequest(''); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk3) { return mk3.createSession().generateRequest(null); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk4) { return mk4.createSession().generateRequest(undefined); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk5) { return mk5.createSession().generateRequest(1); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk6) { return mk6.createSession().generateRequest(new Uint8Array(0)); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk7, _, initData) { return mk7.createSession().generateRequest(initData); } |
| }, |
| // Invalid parameters. |
| { |
| exception: 'TypeError', |
| func: function(mk8, _, initData) { return mk8.createSession().generateRequest('', initData); } |
| }, |
| // Not supported initDataTypes. |
| { |
| exception: 'NotSupportedError', |
| func: function(mk9, _, initData) { return mk9.createSession().generateRequest(null, initData); } |
| }, |
| { |
| exception: 'NotSupportedError', |
| func: function(mk10, _, initData) { return mk10.createSession().generateRequest(undefined, initData); } |
| }, |
| { |
| exception: 'NotSupportedError', |
| func: function(mk11, _, initData) { return mk11.createSession().generateRequest(1, initData); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk12, _, initData) { return mk12.createSession().generateRequest(new Uint8Array(0), initData); } |
| }, |
| { |
| exception: 'NotSupportedError', |
| func: function(mk13, _, initData) { return mk13.createSession().generateRequest('unsupported', initData); } |
| }, |
| { |
| exception: 'NotSupportedError', |
| func: function(mk14, _, initData) { return mk14.createSession().generateRequest('video/webm', initData); } |
| }, |
| { |
| exception: 'NotSupportedError', |
| func: function(mk15, _, initData) { return mk15.createSession().generateRequest('video/mp4', initData); } |
| }, |
| { |
| exception: 'NotSupportedError', |
| func: function(mk16, _, initData) { return mk16.createSession().generateRequest('video/cenc', initData); } |
| }, |
| { |
| exception: 'NotSupportedError', |
| func: function(mk17, _, initData) { return mk17.createSession().generateRequest('web\u263A', initData); } |
| } |
| ]; |
| |
| var kTypeSpecificGenerateRequestExceptionsTestCases = [ |
| // Tests in this set use a shortened parameter name due to |
| // format_value() only returning the first 60 characters as the |
| // result. With a longer name the first 60 characters is not |
| // enough to determine which test failed. Even with the |
| // shortened name, the error message for the last couple of |
| // tests is the same. |
| |
| // Too few parameters. |
| { |
| exception: 'TypeError', |
| func: function(mk1, type) { return mk1.createSession().generateRequest(type); } |
| }, |
| // Invalid parameters. |
| { |
| exception: 'TypeError', |
| func: function(mk2, type) { return mk2.createSession().generateRequest(type, ''); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk3, type) { return mk3.createSession().generateRequest(type, null); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk4, type) { return mk4.createSession().generateRequest(type, undefined); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk5, type) { return mk5.createSession().generateRequest(type, 1); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk6, type) { return mk6.createSession().generateRequest(type, new Uint8Array(0)); } |
| } |
| ]; |
| |
| async_test(function(test) |
| { |
| var isWebmSupported; |
| var isCencSupported; |
| |
| isInitDataTypeSupported('webm').then(function(result) { |
| isWebmSupported = result; |
| return isInitDataTypeSupported('cenc'); |
| }).then(function(result) { |
| isCencSupported = result; |
| return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()); |
| }).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var initData = stringToUint8Array('init data'); |
| var sessionPromises = kGenerateRequestExceptionsTestCases.map(function(testCase) { |
| return test_exception(testCase, mediaKeys, '', initData); |
| }); |
| |
| // Test that WebM sessions generate the expected error, if |
| // supported. |
| if (isWebmSupported) { |
| var WebmSessionPromises = kTypeSpecificGenerateRequestExceptionsTestCases.map(function(testCase) { |
| return test_exception(testCase, mediaKeys, 'webm', getInitData('webm')); |
| }); |
| sessionPromises = sessionPromises.concat(WebmSessionPromises); |
| } |
| |
| // Repeat for MP4, if supported. |
| if (isCencSupported) { |
| var mp4SessionPromises = kTypeSpecificGenerateRequestExceptionsTestCases.map(function(testCase) { |
| return test_exception(testCase, mediaKeys, 'cenc', getInitData('cenc')); |
| }); |
| sessionPromises = sessionPromises.concat(mp4SessionPromises); |
| } |
| |
| assert_not_equals(sessionPromises.length, 0); |
| return Promise.all(sessionPromises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'generateRequest() tests failed'); |
| }); |
| }, 'Test MediaKeys generateRequest() exceptions.'); |
| |
| var kLoadExceptionsTestCases = [ |
| // Too few parameters. |
| { |
| exception: 'TypeError', |
| func: function(mk1) { return mk1.createSession('temporary').load(); } |
| }, |
| // 'temporary' sessions are never allowed, so always return |
| // 'TypeError'. |
| { |
| exception: 'TypeError', |
| func: function(mk3) { return mk3.createSession('temporary').load(''); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk4) { return mk4.createSession('temporary').load(1); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk5) { return mk5.createSession('temporary').load('!@#$%^&*()'); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk6) { return mk6.createSession('temporary').load('1234'); } |
| } |
| ]; |
| |
| async_test(function(test) |
| { |
| navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var initData = stringToUint8Array('init data'); |
| var sessionPromises = kLoadExceptionsTestCases.map(function(testCase) { |
| return test_exception(testCase, mediaKeys); |
| }); |
| |
| assert_not_equals(sessionPromises.length, 0); |
| return Promise.all(sessionPromises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'load() tests failed'); |
| }); |
| }, 'Test MediaKeys load() exceptions.'); |
| |
| // All calls to |func| in this group are supposed to succeed. |
| // However, the spec notes that some things are optional for |
| // Clear Key. In particular, support for persistent sessions |
| // is optional. Since some implementations won't support some |
| // features, a NotSupportedError is treated as a success |
| // if |isNotSupportedAllowed| is true. |
| var kCreateSessionTestCases = [ |
| // Use the default sessionType. |
| { |
| func: function(mk) { return mk.createSession(); }, |
| isNotSupportedAllowed: false |
| }, |
| // Try variations of sessionType. |
| { |
| func: function(mk) { return mk.createSession('temporary'); }, |
| isNotSupportedAllowed: false |
| }, |
| { |
| func: function(mk) { return mk.createSession(undefined); }, |
| isNotSupportedAllowed: false |
| }, |
| { |
| // Since this is optional, some Clear Key implementations |
| // will succeed, others will return a "NotSupportedError". |
| // Both are allowed results. |
| func: function(mk) { return mk.createSession('persistent-license'); }, |
| isNotSupportedAllowed: true |
| }, |
| // Try additional parameter, which should be ignored. |
| { |
| func: function(mk) { return mk.createSession('temporary', 'extra'); }, |
| isNotSupportedAllowed: false |
| } |
| ]; |
| |
| // This function checks that calling |testCase.func| creates a |
| // MediaKeySession object with some default values. It also |
| // allows for an NotSupportedError to be generated and treated as a |
| // success, if allowed. See comment above kCreateSessionTestCases. |
| function test_createSession(testCase, mediaKeys) |
| { |
| var mediaKeySession; |
| try { |
| mediaKeySession = testCase.func.call(null, mediaKeys); |
| } catch (e) { |
| assert_true(testCase.isNotSupportedAllowed); |
| return; |
| } |
| |
| assert_equals(typeof mediaKeySession, 'object'); |
| assert_equals(typeof mediaKeySession.addEventListener, 'function'); |
| assert_equals(typeof mediaKeySession.sessionId, 'string'); |
| assert_equals(typeof mediaKeySession.expiration, 'number'); |
| assert_equals(typeof mediaKeySession.closed, 'object'); |
| assert_equals(typeof mediaKeySession.keyStatuses, 'object'); |
| assert_equals(typeof mediaKeySession.onkeystatuseschange, 'object'); |
| assert_equals(typeof mediaKeySession.onmessage, 'object'); |
| assert_equals(typeof mediaKeySession.generateRequest, 'function'); |
| assert_equals(typeof mediaKeySession.load, 'function'); |
| assert_equals(typeof mediaKeySession.update, 'function'); |
| assert_equals(typeof mediaKeySession.close, 'function'); |
| assert_equals(typeof mediaKeySession.remove, 'function'); |
| assert_equals(mediaKeySession.sessionId, ''); |
| } |
| |
| async_test(function(test) |
| { |
| navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| kCreateSessionTestCases.map(function(testCase) { |
| test_createSession(testCase, mediaKeys); |
| }); |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'createSession() tests failed'); |
| }); |
| }, 'Test MediaKeys createSession().'); |
| |
| // This function checks that calling generateRequest() works for |
| // various sessions. |testCase.func| creates a MediaKeySession |
| // object, and then generateRequest() is called on that object. It |
| // allows for an NotSupportedError to be generated and treated as a |
| // success, if allowed. See comment above kCreateSessionTestCases. |
| function test_generateRequest(testCase, mediaKeys, type, initData) |
| { |
| try { |
| var mediaKeySession = testCase.func.call(null, mediaKeys); |
| return mediaKeySession.generateRequest(type, initData); |
| } catch (e) { |
| assert_true(testCase.isNotSupportedAllowed); |
| } |
| } |
| |
| async_test(function(test) |
| { |
| var isWebmSupported; |
| var isCencSupported; |
| |
| isInitDataTypeSupported('webm').then(function(result) { |
| isWebmSupported = result; |
| return isInitDataTypeSupported('cenc'); |
| }).then(function(result) { |
| isCencSupported = result; |
| return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()); |
| }).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var sessionPromises = []; |
| |
| // Test that WebM sessions generate the expected error, if |
| // supported. |
| if (isWebmSupported) { |
| var WebmSessionPromises = kCreateSessionTestCases.map(function(testCase) { |
| return test_generateRequest(testCase, mediaKeys, 'webm', getInitData('webm')); |
| }); |
| sessionPromises = sessionPromises.concat(WebmSessionPromises); |
| } |
| |
| // Repeat for MP4, if supported. |
| if (isCencSupported) { |
| var mp4SessionPromises = kCreateSessionTestCases.map(function(testCase) { |
| return test_generateRequest(testCase, mediaKeys, 'cenc', getInitData('cenc')); |
| }); |
| sessionPromises = sessionPromises.concat(mp4SessionPromises); |
| } |
| |
| assert_not_equals(sessionPromises.length, 0); |
| return Promise.all(sessionPromises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'generateRequest() tests failed'); |
| }); |
| }, 'Test MediaKeys generateRequest().'); |
| |
| var kUpdateSessionExceptionsTestCases = [ |
| // Tests in this set use a shortened parameter name due to |
| // format_value() only returning the first 60 characters as the |
| // result. With a longer name (mediaKeySession) the first 60 |
| // characters is not enough to determine which test failed. |
| |
| // Too few parameters. |
| { |
| exception: 'TypeError', |
| func: function(s) { return s.update(); } |
| }, |
| // Invalid parameters. |
| { |
| exception: 'TypeError', |
| func: function(s) { return s.update(''); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(s) { return s.update(null); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(s) { return s.update(undefined); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(s) { return s.update(1); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(s) { return s.update(new Uint8Array(0)); } |
| } |
| ]; |
| |
| async_test(function(test) |
| { |
| var isWebmSupported; |
| var isCencSupported; |
| |
| isInitDataTypeSupported('webm').then(function(result) { |
| isWebmSupported = result; |
| return isInitDataTypeSupported('cenc'); |
| }).then(function(result) { |
| isCencSupported = result; |
| return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()); |
| }).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var promises = []; |
| |
| if (isWebmSupported) { |
| var WebmSessionPromises = kUpdateSessionExceptionsTestCases.map(function(testCase) { |
| var mediaKeySession = mediaKeys.createSession(); |
| return mediaKeySession.generateRequest('webm', getInitData('webm')).then(function(result) { |
| return test_exception(testCase, mediaKeySession); |
| }); |
| }); |
| promises = promises.concat(WebmSessionPromises); |
| } |
| |
| if (isCencSupported) { |
| var mp4SessionPromises = kUpdateSessionExceptionsTestCases.map(function(testCase) { |
| var mediaKeySession = mediaKeys.createSession(); |
| return mediaKeySession.generateRequest('cenc', getInitData('cenc')).then(function(result) { |
| return test_exception(testCase, mediaKeySession); |
| }); |
| }); |
| promises = promises.concat(mp4SessionPromises); |
| } |
| |
| assert_not_equals(promises.length, 0); |
| return Promise.all(promises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'update() tests failed'); |
| }); |
| }, 'Test MediaKeySession update() exceptions.'); |
| |
| function create_update_test(mediaKeys, type, initData) |
| { |
| var mediaKeySession = mediaKeys.createSession(); |
| var promise = mediaKeySession.generateRequest(type, initData).then(function(result) { |
| var validLicense = stringToUint8Array(createJWKSet(createJWK(stringToUint8Array('123'), stringToUint8Array('1234567890abcdef')))); |
| return mediaKeySession.update(validLicense); |
| }).then(function(result) { |
| // Call update() with a different license and an extra |
| // parameter. The extra parameter is ignored. |
| var validLicense = stringToUint8Array(createJWKSet(createJWK(stringToUint8Array('4567890'), stringToUint8Array('01234567890abcde')))); |
| return mediaKeySession.update(validLicense, 'extra'); |
| }); |
| return promise; |
| } |
| |
| async_test(function(test) |
| { |
| var isWebmSupported; |
| var isCencSupported; |
| |
| isInitDataTypeSupported('webm').then(function(result) { |
| isWebmSupported = result; |
| return isInitDataTypeSupported('cenc'); |
| }).then(function(result) { |
| isCencSupported = result; |
| return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()); |
| }).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var promises = []; |
| |
| if (isWebmSupported) { |
| promises.push(create_update_test(mediaKeys, 'webm', getInitData('webm'))); |
| } |
| |
| if (isCencSupported) { |
| promises.push(create_update_test(mediaKeys, 'cenc', getInitData('cenc'))); |
| } |
| |
| assert_not_equals(promises.length, 0); |
| return Promise.all(promises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'update() tests failed'); |
| }); |
| }, 'Test MediaKeySession update().'); |
| |
| function create_close_exception_test(mediaKeys, type, initData) |
| { |
| var mediaKeySession = mediaKeys.createSession(); |
| return mediaKeySession.close().then(function(result) { |
| assert_unreached('close() should not succeed if session uninitialized'); |
| }).catch(function(error) { |
| assert_equals(error.name, 'InvalidStateError'); |
| // Return something so the promise resolves. |
| return Promise.resolve(); |
| }); |
| } |
| |
| async_test(function(test) |
| { |
| var isWebmSupported; |
| var isCencSupported; |
| |
| isInitDataTypeSupported('webm').then(function(result) { |
| isWebmSupported = result; |
| return isInitDataTypeSupported('cenc'); |
| }).then(function(result) { |
| isCencSupported = result; |
| return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()); |
| }).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var promises = []; |
| |
| if (isWebmSupported) { |
| promises.push(create_close_exception_test(mediaKeys, 'webm', getInitData('webm'))); |
| } |
| |
| if (isCencSupported) { |
| promises.push(create_close_exception_test(mediaKeys, 'cenc', getInitData('cenc'))); |
| } |
| |
| assert_not_equals(promises.length, 0); |
| return Promise.all(promises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'close() exception tests failed'); |
| }); |
| }, 'Test MediaKeySession close() exceptions.'); |
| |
| |
| function create_close_test(mediaKeys, type, initData) |
| { |
| var mediaKeySession = mediaKeys.createSession(); |
| var promise = mediaKeySession.generateRequest(type, initData).then(function(result) { |
| return mediaKeySession.close(); |
| }).then(function(result) { |
| // Call close() again with an extra parameter. The extra |
| // parameter is ignored. |
| return mediaKeySession.close('extra'); |
| }); |
| return promise; |
| } |
| |
| async_test(function(test) |
| { |
| var isWebmSupported; |
| var isCencSupported; |
| |
| isInitDataTypeSupported('webm').then(function(result) { |
| isWebmSupported = result; |
| return isInitDataTypeSupported('cenc'); |
| }).then(function(result) { |
| isCencSupported = result; |
| return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()); |
| }).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var promises = []; |
| |
| if (isWebmSupported) { |
| promises.push(create_close_test(mediaKeys, 'webm', getInitData('webm'))); |
| } |
| |
| if (isCencSupported) { |
| promises.push(create_close_test(mediaKeys, 'cenc', getInitData('cenc'))); |
| } |
| |
| assert_not_equals(promises.length, 0); |
| return Promise.all(promises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'close() tests failed'); |
| }); |
| }, 'Test MediaKeySession close().'); |
| |
| function create_remove_exception_test(mediaKeys, type, initData) |
| { |
| // remove() on an uninitialized session should fail. |
| var mediaKeySession = mediaKeys.createSession('temporary'); |
| return mediaKeySession.remove().then(function(result) { |
| assert_unreached('remove() should not succeed if session uninitialized'); |
| }, function(error) { |
| assert_equals(error.name, 'InvalidStateError'); |
| }); |
| } |
| |
| async_test(function(test) |
| { |
| var isWebmSupported; |
| var isCencSupported; |
| |
| isInitDataTypeSupported('webm').then(function(result) { |
| isWebmSupported = result; |
| return isInitDataTypeSupported('cenc'); |
| }).then(function(result) { |
| isCencSupported = result; |
| return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()); |
| }).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var promises = []; |
| |
| if (isWebmSupported) { |
| promises.push(create_remove_exception_test(mediaKeys, 'webm', getInitData('webm'))); |
| } |
| |
| if (isCencSupported) { |
| promises.push(create_remove_exception_test(mediaKeys, 'cenc', getInitData('cenc'))); |
| } |
| |
| assert_not_equals(promises.length, 0); |
| return Promise.all(promises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'remove() exception tests failed'); |
| }); |
| }, 'Test MediaKeySession remove() exceptions.'); |
| |
| function create_remove_test(mediaKeys, type, initData) |
| { |
| var mediaKeySession = mediaKeys.createSession(); |
| var promise = mediaKeySession.generateRequest(type, initData).then(function(result) { |
| return mediaKeySession.remove(); |
| }).then(function() { |
| // remove() doesn't close the session, so must call close(). |
| return mediaKeySession.close(); |
| }).then(function() { |
| try { |
| // Clear Key may not support persistent-license sessions. |
| mediaKeySession = mediaKeys.createSession('persistent-license'); |
| return mediaKeySession.generateRequest(type, initData).then(function(result) { |
| return mediaKeySession.remove(); |
| }).then(function() { |
| return mediaKeySession.close(); |
| }); |
| } catch (error) { |
| // Not supported, so return a resolved promise. |
| assert_equals(error.name, 'NotSupportedError'); |
| return Promise.resolve(); |
| } |
| }); |
| } |
| |
| async_test(function(test) |
| { |
| var isWebmSupported; |
| var isCencSupported; |
| |
| isInitDataTypeSupported('webm').then(function(result) { |
| isWebmSupported = result; |
| return isInitDataTypeSupported('cenc'); |
| }).then(function(result) { |
| isCencSupported = result; |
| return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()); |
| }).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var promises = []; |
| |
| if (isWebmSupported) { |
| promises.push(create_remove_test(mediaKeys, 'webm', getInitData('webm'))); |
| } |
| |
| if (isCencSupported) { |
| promises.push(create_remove_test(mediaKeys, 'cenc', getInitData('cenc'))); |
| } |
| |
| assert_not_equals(promises.length, 0); |
| return Promise.all(promises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'remove() tests failed'); |
| }); |
| }, 'Test MediaKeySession remove().'); |
| |
| var kSetServerCertificateExceptionsTestCases = [ |
| // Too few parameters. |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.setServerCertificate(); } |
| }, |
| // Invalid parameters. |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.setServerCertificate(''); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.setServerCertificate(null); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.setServerCertificate(undefined); } |
| }, |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.setServerCertificate(1); } |
| }, |
| // Empty array. |
| { |
| exception: 'TypeError', |
| func: function(mk) { return mk.setServerCertificate(new Uint8Array(0)); } |
| } |
| ]; |
| |
| async_test(function(test) |
| { |
| navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var promises = kSetServerCertificateExceptionsTestCases.map(function(testCase) { |
| return test_exception(testCase, mediaKeys); |
| }); |
| |
| assert_not_equals(promises.length, 0); |
| return Promise.all(promises); |
| }).then(function(result) { |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'setServerCertificate() exception tests failed'); |
| }); |
| }, 'Test MediaKeys setServerCertificate() exceptions.'); |
| |
| // All calls to |func| in this group are expected to resolve. |
| var kSetServerCertificateTestCases = [ |
| { |
| // Pass in ArrayBufferView |
| func: function(mk) { |
| var cert = new Uint8Array(200); |
| assert_true(ArrayBuffer.isView(cert)); |
| return mk.setServerCertificate(cert); |
| }, |
| expected: false, |
| }, |
| { |
| // Pass in ArrayBuffer |
| func: function(mk) { |
| var buffer = new ArrayBuffer(200); |
| assert_false(ArrayBuffer.isView(buffer)); |
| return mk.setServerCertificate(buffer); |
| }, |
| expected: false, |
| } |
| ]; |
| |
| async_test(function(test) |
| { |
| var expected_result; |
| navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration()).then(function(access) { |
| return access.createMediaKeys(); |
| }).then(function(mediaKeys) { |
| var promises = kSetServerCertificateTestCases.map(function(testCase) { |
| return testCase.func.call(null, mediaKeys); |
| }); |
| expected_result = kSetServerCertificateTestCases.map(function(testCase) { |
| return testCase.expected; |
| }); |
| |
| assert_not_equals(promises.length, 0); |
| return Promise.all(promises); |
| }).then(function(result) { |
| assert_array_equals(result, expected_result); |
| test.done(); |
| }).catch(function(error) { |
| forceTestFailureFromPromise(test, error, 'setServerCertificate() test failed'); |
| }); |
| }, 'Test MediaKeys setServerCertificate().'); |
| |
| function test_valid_message_type(message_type) |
| { |
| var event = new MediaKeyMessageEvent('eventType', { messageType: message_type, message: new ArrayBuffer(0) } ); |
| assert_equals(event.messageType, message_type); |
| } |
| |
| test(function(test) |
| { |
| // Valid MediaKeyMessageType values. |
| test_valid_message_type('license-request'); |
| test_valid_message_type('license-renewal'); |
| test_valid_message_type('license-release'); |
| // TODO(jrummell): Add 'individualization-request' if the final |
| // spec includes it. http://crbug.com/628437. |
| |
| // Invalid MediaKeyMessageType values should throw a TypeError. |
| assert_throws_js(TypeError, function() { |
| new MediaKeyMessageEvent('eventType', { messageType: 'something-else', message: new ArrayBuffer(0) } ); |
| }); |
| |
| // Missing required values should throw a TypeError. |
| assert_throws_js(TypeError, function() { |
| new MediaKeyMessageEvent('eventType', { message: new ArrayBuffer(0) } ); |
| }); |
| assert_throws_js(TypeError, function() { |
| new MediaKeyMessageEvent('eventType', { messageType: 'license-request' } ); |
| }); |
| }, 'Test MediaKeyMessageEvent.'); |
| |
| // FIXME: Add syntax checks for MediaKeys.IsTypeSupported(). |
| // FIXME: Add syntax checks for MediaKeyError and MediaKeySession events. |
| // FIXME: Add HTMLMediaElement syntax checks, e.g. setMediaKeys, mediakeys, onencrypted. |
| </script> |
| </body> |
| </html> |