Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / LayoutTests / media / encrypted-media / encrypted-media-v2-syntax.html
1 <!DOCTYPE html>
2 <html>
3     <head>
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>
8     </head>
9     <body>
10         <div id="log"></div>
11         <script>
12             // This function checks that calling |testCase.func| returns a
13             // rejected Promise with the error.name equal to
14             // |testCase.exception|.
15             function test_exception(testCase /*...*/)
16             {
17                 var func = testCase.func;
18                 var exception = testCase.exception;
19                 var args = Array.prototype.slice.call(arguments, 1);
20
21                 // Currently blink throws for TypeErrors rather than returning
22                 // a rejected promise (http://crbug.com/359386).
23                 // FIXME: Remove try/catch once they become failed promises.
24                 try {
25                     return func.apply(null, args).then(
26                         function(result)
27                         {
28                             assert_unreached(format_value(func));
29                         },
30                         function(error)
31                         {
32                             assert_equals(error.name, exception, format_value(func));
33                             assert_not_equals(error.message, "", format_value(func));
34                         }
35                     );
36                 } catch (e) {
37                     // Only allow 'TypeError' exceptions to be thrown.
38                     // Everything else should be a failed promise.
39                     assert_equals('TypeError', exception, format_value(func));
40                     assert_equals(e.name, exception, format_value(func));
41                 }
42             }
43
44             var kCreateMediaKeysExceptionsTestCases = [
45                 // Too few parameters.
46                 {
47                     exception: 'TypeError',
48                     func: function() { return MediaKeys.create(); }
49                 },
50                 // Invalid parameters.
51                 {
52                     exception: 'InvalidAccessError',
53                     func: function() { return MediaKeys.create(''); }
54                 },
55                 // Invalid key systems.
56                 {
57                     exception: 'NotSupportedError',
58                     func: function() { return MediaKeys.create(null); }
59                 },
60                 {
61                     exception: 'NotSupportedError',
62                     func: function() { return MediaKeys.create(undefined); }
63                 },
64                 {
65                     exception: 'NotSupportedError',
66                     func: function() { return MediaKeys.create(1); }
67                 },
68                 {
69                     exception: 'NotSupportedError',
70                     func: function() { return MediaKeys.create(new Uint8Array(0)); }
71                 },
72                 {
73                     exception: 'NotSupportedError',
74                     func: function() { return MediaKeys.create('unsupported'); }
75                 },
76                 // Non-ASCII names.
77                 {
78                     exception: 'NotSupportedError',
79                     func: function() { return MediaKeys.create('org.w3\u263A.clearkey'); }
80                 }
81             ];
82
83             async_test(function(test)
84             {
85                 // Since promises catch any exception and convert it into a
86                 // rejected Promise, there is no current way to have the W3C
87                 // test framework report a failed test. For now, simply force
88                 // a timeout to indicate failure.
89                 // FIXME: Once W3C test framework handles Promises, fix this.
90
91                 var createPromises = kCreateMediaKeysExceptionsTestCases.map(function(testCase) {
92                     return test_exception(testCase);
93                 });
94
95                 Promise.all(createPromises).then(function(result) {
96                     test.done();
97                 }).catch(function(error) {
98                     forceTestFailureFromPromise(test, error, 'create() tests failed');
99                 });
100             }, 'Test MediaKeys create() exceptions.');
101
102             async_test(function(test)
103             {
104                 assert_equals(typeof window.MediaKeys, 'function');
105                 MediaKeys.create('org.w3.clearkey').then(function(mediaKeys) {
106                     assert_not_equals(mediaKeys, null);
107
108                     // Test creation of a second MediaKeys.
109                     // The extra parameter is ignored.
110                     return MediaKeys.create('org.w3.clearkey', 'extra');
111                 }).then(function(mediaKeys) {
112                     assert_not_equals(mediaKeys, null);
113                     assert_equals(typeof mediaKeys, 'object');
114                     assert_equals(mediaKeys.keySystem, 'org.w3.clearkey');
115                     assert_equals(typeof mediaKeys.createSession, 'function');
116                     assert_equals(typeof mediaKeys.addEventListener, 'undefined');
117                     test.done();
118                 }).catch(function(error) {
119                     forceTestFailureFromPromise(test, error, 'create() tests failed');
120                 });
121             }, 'Test MediaKeys create().');
122
123             var kCreateSessionExceptionsTestCases = [
124                 // Tests in this set use a shortened parameter name due to
125                 // format_value() only returning the first 60 characters as the
126                 // result. With a longer name the first 60 characters is not
127                 // enough to determine which test failed.
128
129                 // Invalid parameters.
130                 {
131                     exception: 'TypeError',
132                     func: function(mk) { return mk.createSession(); }
133                 },
134                 {
135                     exception: 'TypeError',
136                     func: function(mk) { return mk.createSession(''); }
137                 },
138                 {
139                     exception: 'TypeError',
140                     func: function(mk) { return mk.createSession(null); }
141                 },
142                 {
143                     exception: 'TypeError',
144                     func: function(mk) { return mk.createSession(undefined); }
145                 },
146                 {
147                     exception: 'TypeError',
148                     func: function(mk) { return mk.createSession(1); }
149                 },
150                 {
151                     exception: 'TypeError',
152                     func: function(mk) { return mk.createSession(new Uint8Array(0)); }
153                 },
154                 {
155                     exception: 'TypeError',
156                     func: function(mk) { return mk.createSession('TEMPORARY'); }
157                 }
158             ];
159
160             async_test(function(test)
161             {
162                 MediaKeys.create('org.w3.clearkey').then(function(mediaKeys) {
163                     var sessionPromises = kCreateSessionExceptionsTestCases.map(function(testCase) {
164                         return test_exception(testCase, mediaKeys);
165                     });
166
167                     assert_not_equals(sessionPromises.length, 0);
168                     return Promise.all(sessionPromises);
169                 }).then(function(result) {
170                     test.done();
171                 }).catch(function(error) {
172                     forceTestFailureFromPromise(test, error, 'createSession() tests failed');
173                 });
174             }, 'Test MediaKeys createSession() exceptions.');
175
176             var kGenerateRequestExceptionsTestCases = [
177                 // Tests in this set use a shortened parameter name due to
178                 // format_value() only returning the first 60 characters as the
179                 // result. With a longer name the first 60 characters is not
180                 // enough to determine which test failed. Even with the
181                 // shortened name, the error message for the last couple of
182                 // tests is the same.
183                 // Too few parameters.
184                 {
185                     exception: 'TypeError',
186                     func: function(mk1) { return mk1.createSession().generateRequest(); }
187                 },
188                 {
189                     exception: 'TypeError',
190                     func: function(mk2) { return mk2.createSession().generateRequest(''); }
191                 },
192                 {
193                     exception: 'TypeError',
194                     func: function(mk3) { return mk3.createSession().generateRequest(null); }
195                 },
196                 {
197                     exception: 'TypeError',
198                     func: function(mk4) { return mk4.createSession().generateRequest(undefined); }
199                 },
200                 {
201                     exception: 'TypeError',
202                     func: function(mk5) { return mk5.createSession().generateRequest(1); }
203                 },
204                 {
205                     exception: 'TypeError',
206                     func: function(mk6) { return mk6.createSession().generateRequest(new Uint8Array(0)); }
207                 },
208                 {
209                     exception: 'TypeError',
210                     func: function(mk7, _, initData) { return mk7.createSession().generateRequest(initData); }
211                 },
212                 // Invalid parameters.
213                 {
214                     exception: 'InvalidAccessError',
215                     func: function(mk8, _, initData) { return mk8.createSession().generateRequest('', initData); }
216                 },
217                 // Not supported initDataTypes.
218                 {
219                     exception: 'NotSupportedError',
220                     func: function(mk9, _, initData) { return mk9.createSession().generateRequest(null, initData); }
221                 },
222                 {
223                     exception: 'NotSupportedError',
224                     func: function(mk10, _, initData) { return mk10.createSession().generateRequest(undefined, initData); }
225                 },
226                 {
227                     exception: 'NotSupportedError',
228                     func: function(mk11, _, initData) { return mk11.createSession().generateRequest(1, initData); }
229                 },
230                 {
231                     exception: 'NotSupportedError',
232                     func: function(mk12, _, initData) { return mk12.createSession().generateRequest(new Uint8Array(0), initData); }
233                 },
234                 {
235                     exception: 'NotSupportedError',
236                     func: function(mk13, _, initData) { return mk13.createSession().generateRequest('unsupported', initData); }
237                 },
238                 {
239                     exception: 'NotSupportedError',
240                     func: function(mk14, _, initData) { return mk14.createSession().generateRequest('video/foo', initData); }
241                 },
242                 {
243                     exception: 'NotSupportedError',
244                     func: function(mk15, _, initData) { return mk15.createSession().generateRequest('text/webm', initData); }
245                 }
246                 // FIXME: Enable when switching to initDataType from MIME type.
247                 // http://crbug.com/385874.
248                 // {
249                 //     exception: 'NotSupportedError',
250                 //     func: function(mk16, _, initData) { return mk16.createSession('video/webm', initData); }
251                 // }
252             ];
253
254             var kTypeSpecificGenerateRequestExceptionsTestCases = [
255                 // Tests in this set use a shortened parameter name due to
256                 // format_value() only returning the first 60 characters as the
257                 // result. With a longer name the first 60 characters is not
258                 // enough to determine which test failed. Even with the
259                 // shortened name, the error message for the last couple of
260                 // tests is the same.
261
262                 // Too few parameters.
263                 {
264                     exception: 'TypeError',
265                     func: function(mk1, type) { return mk1.createSession().generateRequest(type); }
266                 },
267                 // Invalid parameters.
268                 {
269                     exception: 'TypeError',
270                     func: function(mk2, type) { return mk2.createSession().generateRequest(type, ''); }
271                 },
272                 {
273                     exception: 'TypeError',
274                     func: function(mk3, type) { return mk3.createSession().generateRequest(type, null); }
275                 },
276                 {
277                     exception: 'TypeError',
278                     func: function(mk4, type) { return mk4.createSession().generateRequest(type, undefined); }
279                 },
280                 {
281                     exception: 'TypeError',
282                     func: function(mk5, type) { return mk5.createSession().generateRequest(type, 1); }
283                 },
284                 {
285                     exception: 'InvalidAccessError',
286                     func: function(mk6, type) { return mk6.createSession().generateRequest(type, new Uint8Array(0)); }
287                 }
288             ];
289
290             async_test(function(test)
291             {
292                 MediaKeys.create('org.w3.clearkey').then(function(mediaKeys) {
293                     // FIXME: Remove "video/" from the calls to isTypeSupported() once it is updated.
294                     // http://crbug.com/405731.
295                     var initData = stringToUint8Array('init data');
296                     var sessionPromises = kGenerateRequestExceptionsTestCases.map(function(testCase) {
297                         return test_exception(testCase, mediaKeys, '', initData);
298                     });
299
300                     // Test that WebM sessions generate the expected error, if
301                     // supported.
302                     if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
303                         var WebmSessionPromises = kTypeSpecificGenerateRequestExceptionsTestCases.map(function(testCase) {
304                             return test_exception(testCase, mediaKeys, 'webm', getInitData('webm'));
305                         });
306                         sessionPromises = sessionPromises.concat(WebmSessionPromises);
307                     }
308
309                     // Repeat for MP4, if supported.
310                     if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
311                         var mp4SessionPromises = kTypeSpecificGenerateRequestExceptionsTestCases.map(function(testCase) {
312                             return test_exception(testCase, mediaKeys, 'cenc', getInitData('cenc'));
313                         });
314                         sessionPromises = sessionPromises.concat(mp4SessionPromises);
315                     }
316
317                     assert_not_equals(sessionPromises.length, 0);
318                     return Promise.all(sessionPromises);
319                 }).then(function(result) {
320                     test.done();
321                 }).catch(function(error) {
322                     forceTestFailureFromPromise(test, error, 'generateRequest() tests failed');
323                 });
324             }, 'Test MediaKeys generateRequest() exceptions.');
325
326             // All calls to |func| in this group are supposed to succeed.
327             // However, the spec notes that some things are optional for
328             // Clear Key. In particular, support for persistent sessions
329             // is optional. Since some implementations won't support some
330             // features, a NotSupportedError is treated as a success
331             // if |isNotSupportedAllowed| is true.
332             var kCreateSessionTestCases = [
333                 // Use the default sessionType.
334                 {
335                     func: function(mk) { return mk.createSession(); },
336                     isNotSupportedAllowed: false
337                 },
338                 // Try variations of sessionType.
339                 {
340                     func: function(mk) { return mk.createSession('temporary'); },
341                     isNotSupportedAllowed: false
342                 },
343                 {
344                     func: function(mk) { return mk.createSession(undefined); },
345                     isNotSupportedAllowed: false
346                 },
347                 {
348                     // Since this is optional, some Clear Key implementations
349                     // will succeed, others will return a "NotSupportedError".
350                     // Both are allowed results.
351                     func: function(mk) { return mk.createSession('persistent'); },
352                     isNotSupportedAllowed: true
353                 },
354                 // Try additional parameter, which should be ignored.
355                 {
356                     func: function(mk) { return mk.createSession('temporary', 'extra'); },
357                     isNotSupportedAllowed: false
358                 }
359             ];
360
361             // This function checks that calling |testCase.func| creates a
362             // MediaKeySession object with some default values. It also
363             // allows for an NotSupportedError to be generated and treated as a
364             // success, if allowed. See comment above kCreateSessionTestCases.
365             function test_createSession(testCase, mediaKeys)
366             {
367                 var mediaKeySession;
368                 try {
369                     mediaKeySession = testCase.func.call(null, mediaKeys);
370                 } catch (e) {
371                     assert_true(testCase.isNotSupportedAllowed);
372                     return;
373                 }
374
375                 // FIXME: Update this set of tests when done
376                 // implementing the latest spec.
377                 assert_equals(typeof mediaKeySession, 'object');
378                 assert_equals(typeof mediaKeySession.addEventListener, 'function');
379                 assert_equals(typeof mediaKeySession.generateRequest, 'function');
380                 assert_equals(typeof mediaKeySession.update, 'function');
381                 assert_equals(typeof mediaKeySession.release, 'function');
382                 assert_equals(mediaKeySession.error, null);
383                 assert_equals(mediaKeySession.sessionId, '');
384                 assert_equals(typeof mediaKeySession.sessionId, 'string');
385                 assert_equals(typeof mediaKeySession.onopen, 'undefined');
386                 assert_equals(typeof mediaKeySession.onmessage, 'undefined');
387                 assert_equals(typeof mediaKeySession.onclose, 'undefined');
388                 assert_equals(typeof mediaKeySession.onerror, 'undefined');
389             }
390
391             async_test(function(test)
392             {
393                 MediaKeys.create('org.w3.clearkey').then(function(mediaKeys) {
394                     kCreateSessionTestCases.map(function(testCase) {
395                         test_createSession(testCase, mediaKeys);
396                     });
397                     test.done();
398                 }).catch(function(error) {
399                     forceTestFailureFromPromise(test, error, 'createSession() tests failed');
400                 });
401             }, 'Test MediaKeys createSession().');
402
403             // This function checks that calling generateRequest() works for
404             // various sessions. |testCase.func| creates a MediaKeySession
405             // object, and then generateRequest() is called on that object. It
406             // allows for an NotSupportedError to be generated and treated as a
407             // success, if allowed. See comment above kCreateSessionTestCases.
408             function test_generateRequest(testCase, mediaKeys, type, initData)
409             {
410                 var mediaKeySession;
411                 try {
412                     mediaKeySession = testCase.func.call(null, mediaKeys);
413                 } catch (e) {
414                     assert_true(testCase.isNotSupportedAllowed);
415                     return new Promise(new Promise(function() {}));
416                 }
417                 return mediaKeySession.generateRequest(type, initData);
418             }
419
420             async_test(function(test)
421             {
422                 MediaKeys.create('org.w3.clearkey').then(function(mediaKeys) {
423                     var sessionPromises = [];
424
425                     // Test that WebM sessions generate the expected error, if
426                     // supported.
427                     if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
428                         var WebmSessionPromises = kCreateSessionTestCases.map(function(testCase) {
429                             return test_generateRequest(testCase, mediaKeys, 'webm', getInitData('webm'));
430                         });
431                         sessionPromises = sessionPromises.concat(WebmSessionPromises);
432                     }
433
434                     // Repeat for MP4, if supported.
435                     if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
436                         var mp4SessionPromises = kCreateSessionTestCases.map(function(testCase) {
437                             return test_generateRequest(testCase, mediaKeys, 'cenc', getInitData('cenc'));
438                         });
439                         sessionPromises = sessionPromises.concat(mp4SessionPromises);
440                     }
441
442                     assert_not_equals(sessionPromises.length, 0);
443                     return Promise.all(sessionPromises);
444                 }).then(function(result) {
445                     test.done();
446                 }).catch(function(error) {
447                     forceTestFailureFromPromise(test, error, 'generateRequest() tests failed');
448                 });
449             }, 'Test MediaKeys generateRequest().');
450
451             var kUpdateSessionExceptionsTestCases = [
452                 // Tests in this set use a shortened parameter name due to
453                 // format_value() only returning the first 60 characters as the
454                 // result. With a longer name (mediaKeySession) the first 60
455                 // characters is not enough to determine which test failed.
456
457                 // Too few parameters.
458                 {
459                     exception: 'TypeError',
460                     func: function(s) { return s.update(); }
461                 },
462                 // Invalid parameters.
463                 {
464                     exception: 'TypeError',
465                     func: function(s) { return s.update(''); }
466                 },
467                 {
468                     exception: 'TypeError',
469                     func: function(s) { return s.update(null); }
470                 },
471                 {
472                     exception: 'TypeError',
473                     func: function(s) { return s.update(undefined); }
474                 },
475                 {
476                     exception: 'TypeError',
477                     func: function(s) { return s.update(1); }
478                 },
479                 {
480                     exception: 'InvalidAccessError',
481                     func: function(s) { return s.update(new Uint8Array(0)); }
482                 }
483             ];
484
485             async_test(function(test)
486             {
487                 MediaKeys.create('org.w3.clearkey').then(function(mediaKeys) {
488                     var promises = [];
489
490                     if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
491                         var WebmSessionPromises = kUpdateSessionExceptionsTestCases.map(function(testCase) {
492                             var mediaKeySession = mediaKeys.createSession();
493                             return mediaKeySession.generateRequest('webm', getInitData('webm')).then(function(result) {
494                                 return test_exception(testCase, mediaKeySession);
495                             });
496                         });
497                         promises = promises.concat(WebmSessionPromises);
498                     }
499
500                     if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
501                         var mp4SessionPromises = kUpdateSessionExceptionsTestCases.map(function(testCase) {
502                           var mediaKeySession = mediaKeys.createSession();
503                           return mediaKeySession.generateRequest('cenc', getInitData('cenc')).then(function(result) {
504                               return test_exception(testCase, mediaKeySession);
505                           });
506                       });
507                       promises = promises.concat(mp4SessionPromises);
508                     }
509
510                     assert_not_equals(promises.length, 0);
511                     return Promise.all(promises);
512                 }).then(function(result) {
513                     test.done();
514                 }).catch(function(error) {
515                     forceTestFailureFromPromise(test, error, 'update() tests failed');
516                 });
517             }, 'Test MediaKeySession update() exceptions.');
518
519             function create_update_test(mediaKeys, type, initData)
520             {
521                 var mediaKeySession = mediaKeys.createSession();
522                 var promise = mediaKeySession.generateRequest(type, initData).then(function(result) {
523                     var validLicense = stringToUint8Array(createJWKSet(createJWK(stringToUint8Array('123'), stringToUint8Array('1234567890abcdef'))));
524                     return mediaKeySession.update(validLicense);
525                 }).then(function(result) {
526                     // Call update() with a different license and an extra
527                     // parameter. The extra parameter is ignored.
528                     var validLicense = stringToUint8Array(createJWKSet(createJWK(stringToUint8Array('4567890'), stringToUint8Array('01234567890abcde'))));
529                     return mediaKeySession.update(validLicense, 'extra');
530                 });
531                 return promise;
532             }
533
534             async_test(function(test)
535             {
536                 MediaKeys.create('org.w3.clearkey').then(function(mediaKeys) {
537                   var promises = [];
538
539                   if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
540                       promises.push(create_update_test(mediaKeys, 'webm', getInitData('webm')));
541                   }
542
543                   if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
544                       promises.push(create_update_test(mediaKeys, 'cenc', getInitData('cenc')));
545                   }
546
547                   assert_not_equals(promises.length, 0);
548                   return Promise.all(promises);
549                 }).then(function(result) {
550                     test.done();
551                 }).catch(function(error) {
552                     forceTestFailureFromPromise(test, error, 'update() tests failed');
553                 });
554             }, 'Test MediaKeySession update().');
555
556             function create_release_test(mediaKeys, type, initData)
557             {
558                 var mediaKeySession = mediaKeys.createSession();
559                 var promise = mediaKeySession.generateRequest(type, initData).then(function(result) {
560                     return mediaKeySession.release();
561                 // FIXME: Uncomment once the code supports multiple release() calls.
562 //              }).then(function(result) {
563 //                  // Call release() again with an extra parameter. The extra
564 //                  // parameter is ignored.
565 //                  return mediaKeySession.release('extra');
566                 });
567                 return promise;
568             }
569
570             async_test(function(test)
571             {
572                 MediaKeys.create('org.w3.clearkey').then(function(mediaKeys) {
573                     var promises = [];
574
575                     if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/webm')) {
576                         promises.push(create_release_test(mediaKeys, 'webm', getInitData('webm')));
577                     }
578
579                     if (MediaKeys.isTypeSupported('org.w3.clearkey', 'video/mp4')) {
580                         promises.push(create_release_test(mediaKeys, 'cenc', getInitData('cenc')));
581                     }
582
583                     assert_not_equals(promises.length, 0);
584                     return Promise.all(promises);
585                 }).then(function(result) {
586                     test.done();
587                 }).catch(function(error) {
588                     forceTestFailureFromPromise(test, error, 'release() tests failed');
589                 });
590             }, 'Test MediaKeySession release().');
591
592             // FIXME: Add syntax checks for MediaKeys.IsTypeSupported().
593             // FIXME: Add syntax checks for MediaKeyError and MediaKeySession events.
594             // FIXME: Add HTMLMediaElement syntax checks, e.g. setMediaKeys, mediakeys, onneedkey.
595         </script>
596     </body>
597 </html>