aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/helper.py8
-rw-r--r--test/test_cache.py14
-rw-r--r--test/test_jsinterp.py63
-rw-r--r--test/test_traversal.py190
-rw-r--r--test/test_utils.py46
-rw-r--r--test/test_youtube_signature.py68
6 files changed, 336 insertions, 53 deletions
diff --git a/test/helper.py b/test/helper.py
index 6f2129eff..fac069d25 100644
--- a/test/helper.py
+++ b/test/helper.py
@@ -85,10 +85,10 @@ class FakeYDL(YoutubeDL):
# Silence an expected warning matching a regex
old_report_warning = self.report_warning
- def report_warning(self, message):
+ def report_warning(self, message, *args, **kwargs):
if re.match(regex, message):
return
- old_report_warning(message)
+ old_report_warning(message, *args, **kwargs)
self.report_warning = types.MethodType(report_warning, self)
@@ -265,11 +265,11 @@ def assertRegexpMatches(self, text, regexp, msg=None):
def expect_warnings(ydl, warnings_re):
real_warning = ydl.report_warning
- def _report_warning(w):
+ def _report_warning(self, w, *args, **kwargs):
if not any(re.search(w_re, w) for w_re in warnings_re):
real_warning(w)
- ydl.report_warning = _report_warning
+ ydl.report_warning = types.MethodType(_report_warning, ydl)
def http_server_port(httpd):
diff --git a/test/test_cache.py b/test/test_cache.py
index 931074aa1..0431f4f15 100644
--- a/test/test_cache.py
+++ b/test/test_cache.py
@@ -63,9 +63,21 @@ class TestCache(unittest.TestCase):
obj = {'x': 1, 'y': ['รค', '\\a', True]}
c.store('test_cache', 'k.', obj)
self.assertEqual(c.load('test_cache', 'k.', min_ver='1970.01.01'), obj)
- new_version = '.'.join(('%d' % ((v + 1) if i == 0 else v, )) for i, v in enumerate(version_tuple(__version__)))
+ new_version = '.'.join(('%0.2d' % ((v + 1) if i == 0 else v, )) for i, v in enumerate(version_tuple(__version__)))
self.assertIs(c.load('test_cache', 'k.', min_ver=new_version), None)
+ def test_cache_clear(self):
+ ydl = FakeYDL({
+ 'cachedir': self.test_dir,
+ })
+ c = Cache(ydl)
+ c.store('test_cache', 'k.', 'kay')
+ c.store('test_cache', 'l.', 'ell')
+ self.assertEqual(c.load('test_cache', 'k.'), 'kay')
+ c.clear('test_cache', 'k.')
+ self.assertEqual(c.load('test_cache', 'k.'), None)
+ self.assertEqual(c.load('test_cache', 'l.'), 'ell')
+
if __name__ == '__main__':
unittest.main()
diff --git a/test/test_jsinterp.py b/test/test_jsinterp.py
index 3c9650ab6..479cb43a0 100644
--- a/test/test_jsinterp.py
+++ b/test/test_jsinterp.py
@@ -7,6 +7,7 @@ from __future__ import unicode_literals
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import math
@@ -146,6 +147,25 @@ class TestJSInterpreter(unittest.TestCase):
# https://github.com/ytdl-org/youtube-dl/issues/32815
self._test('function f(){return 0 - 7 * - 6;}', 42)
+ def test_bitwise_operators_typecast(self):
+ # madness
+ self._test('function f(){return null << 5}', 0)
+ self._test('function f(){return undefined >> 5}', 0)
+ self._test('function f(){return 42 << NaN}', 42)
+ self._test('function f(){return 42 << Infinity}', 42)
+ self._test('function f(){return 0.0 << null}', 0)
+ self._test('function f(){return NaN << 42}', 0)
+ self._test('function f(){return "21.9" << 1}', 42)
+ self._test('function f(){return true << "5";}', 32)
+ self._test('function f(){return true << true;}', 2)
+ self._test('function f(){return "19" & "21.9";}', 17)
+ self._test('function f(){return "19" & false;}', 0)
+ self._test('function f(){return "11.0" >> "2.1";}', 2)
+ self._test('function f(){return 5 ^ 9;}', 12)
+ self._test('function f(){return 0.0 << NaN}', 0)
+ self._test('function f(){return null << undefined}', 0)
+ self._test('function f(){return 21 << 4294967297}', 42)
+
def test_array_access(self):
self._test('function f(){var x = [1,2,3]; x[0] = 4; x[0] = 5; x[2.0] = 7; return x;}', [5, 2, 7])
@@ -160,6 +180,7 @@ class TestJSInterpreter(unittest.TestCase):
self._test('function f(){var x = 20; x = 30 + 1; return x;}', 31)
self._test('function f(){var x = 20; x += 30 + 1; return x;}', 51)
self._test('function f(){var x = 20; x -= 30 + 1; return x;}', -11)
+ self._test('function f(){var x = 2; var y = ["a", "b"]; y[x%y["length"]]="z"; return y}', ['z', 'b'])
def test_comments(self):
self._test('''
@@ -351,6 +372,13 @@ class TestJSInterpreter(unittest.TestCase):
self._test('function f() { a=5; return (a -= 1, a+=3, a); }', 7)
self._test('function f() { return (l=[0,1,2,3], function(a, b){return a+b})((l[1], l[2]), l[3]) }', 5)
+ def test_not(self):
+ self._test('function f() { return ! undefined; }', True)
+ self._test('function f() { return !0; }', True)
+ self._test('function f() { return !!0; }', False)
+ self._test('function f() { return ![]; }', False)
+ self._test('function f() { return !0 !== false; }', True)
+
def test_void(self):
self._test('function f() { return void 42; }', JS_Undefined)
@@ -435,6 +463,7 @@ class TestJSInterpreter(unittest.TestCase):
def test_regex(self):
self._test('function f() { let a=/,,[/,913,/](,)}/; }', None)
+ self._test('function f() { let a=/,,[/,913,/](,)}/; return a.source; }', ',,[/,913,/](,)}')
jsi = JSInterpreter('''
function x() { let a=/,,[/,913,/](,)}/; "".replace(a, ""); return a; }
@@ -482,25 +511,6 @@ class TestJSInterpreter(unittest.TestCase):
self._test('function f(){return -524999584 << 5}', 379882496)
self._test('function f(){return 1236566549 << 5}', 915423904)
- def test_bitwise_operators_typecast(self):
- # madness
- self._test('function f(){return null << 5}', 0)
- self._test('function f(){return undefined >> 5}', 0)
- self._test('function f(){return 42 << NaN}', 42)
- self._test('function f(){return 42 << Infinity}', 42)
- self._test('function f(){return 0.0 << null}', 0)
- self._test('function f(){return NaN << 42}', 0)
- self._test('function f(){return "21.9" << 1}', 42)
- self._test('function f(){return 21 << 4294967297}', 42)
- self._test('function f(){return true << "5";}', 32)
- self._test('function f(){return true << true;}', 2)
- self._test('function f(){return "19" & "21.9";}', 17)
- self._test('function f(){return "19" & false;}', 0)
- self._test('function f(){return "11.0" >> "2.1";}', 2)
- self._test('function f(){return 5 ^ 9;}', 12)
- self._test('function f(){return 0.0 << NaN}', 0)
- self._test('function f(){return null << undefined}', 0)
-
def test_negative(self):
self._test('function f(){return 2 * -2.0 ;}', -4)
self._test('function f(){return 2 - - -2 ;}', 0)
@@ -543,6 +553,8 @@ class TestJSInterpreter(unittest.TestCase):
test_result = list('test')
tests = [
'function f(a, b){return a.split(b)}',
+ 'function f(a, b){return a["split"](b)}',
+ 'function f(a, b){let x = ["split"]; return a[x[0]](b)}',
'function f(a, b){return String.prototype.split.call(a, b)}',
'function f(a, b){return String.prototype.split.apply(a, [b])}',
]
@@ -593,6 +605,9 @@ class TestJSInterpreter(unittest.TestCase):
self._test('function f(){return "012345678".slice(-1, 1)}', '')
self._test('function f(){return "012345678".slice(-3, -1)}', '67')
+ def test_splice(self):
+ self._test('function f(){var T = ["0", "1", "2"]; T["splice"](2, 1, "0")[0]; return T }', ['0', '1', '0'])
+
def test_pop(self):
# pop
self._test('function f(){var a = [0, 1, 2, 3, 4, 5, 6, 7, 8]; return [a.pop(), a]}',
@@ -627,6 +642,16 @@ class TestJSInterpreter(unittest.TestCase):
'return [ret.length, ret[0][0], ret[1][1], ret[0][2]]}',
[2, 4, 1, [4, 2]])
+ def test_extract_function(self):
+ jsi = JSInterpreter('function a(b) { return b + 1; }')
+ func = jsi.extract_function('a')
+ self.assertEqual(func([2]), 3)
+
+ def test_extract_function_with_global_stack(self):
+ jsi = JSInterpreter('function c(d) { return d + e + f + g; }')
+ func = jsi.extract_function('c', {'e': 10}, {'f': 100, 'g': 1000})
+ self.assertEqual(func([1]), 1111)
+
if __name__ == '__main__':
unittest.main()
diff --git a/test/test_traversal.py b/test/test_traversal.py
index 00a428edb..504cdee37 100644
--- a/test/test_traversal.py
+++ b/test/test_traversal.py
@@ -9,21 +9,32 @@ import unittest
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+import itertools
import re
from youtube_dl.traversal import (
dict_get,
get_first,
+ require,
+ subs_list_to_dict,
T,
traverse_obj,
+ unpack,
+ value,
)
from youtube_dl.compat import (
+ compat_chr as chr,
compat_etree_fromstring,
compat_http_cookies,
+ compat_map as map,
compat_str,
+ compat_zip as zip,
)
from youtube_dl.utils import (
+ determine_ext,
+ ExtractorError,
int_or_none,
+ join_nonempty,
str_or_none,
)
@@ -446,42 +457,164 @@ class TestTraversal(_TestCase):
msg='`any` should allow further branching')
def test_traversal_morsel(self):
- values = {
- 'expires': 'a',
- 'path': 'b',
- 'comment': 'c',
- 'domain': 'd',
- 'max-age': 'e',
- 'secure': 'f',
- 'httponly': 'g',
- 'version': 'h',
- 'samesite': 'i',
- }
- # SameSite added in Py3.8, breaks .update for 3.5-3.7
- if sys.version_info < (3, 8):
- del values['samesite']
morsel = compat_http_cookies.Morsel()
+ # SameSite added in Py3.8, breaks .update for 3.5-3.7
+ # Similarly Partitioned, Py3.14, thx Grub4k
+ values = dict(zip(morsel, map(chr, itertools.count(ord('a')))))
morsel.set(str('item_key'), 'item_value', 'coded_value')
morsel.update(values)
- values['key'] = str('item_key')
- values['value'] = 'item_value'
+ values.update({
+ 'key': str('item_key'),
+ 'value': 'item_value',
+ }),
values = dict((str(k), v) for k, v in values.items())
- # make test pass even without ordered dict
- value_set = set(values.values())
- for key, value in values.items():
- self.assertEqual(traverse_obj(morsel, key), value,
+ for key, val in values.items():
+ self.assertEqual(traverse_obj(morsel, key), val,
msg='Morsel should provide access to all values')
- self.assertEqual(set(traverse_obj(morsel, Ellipsis)), value_set,
- msg='`...` should yield all values')
- self.assertEqual(set(traverse_obj(morsel, lambda k, v: True)), value_set,
- msg='function key should yield all values')
+ values = list(values.values())
+ self.assertMaybeCountEqual(traverse_obj(morsel, Ellipsis), values,
+ msg='`...` should yield all values')
+ self.assertMaybeCountEqual(traverse_obj(morsel, lambda k, v: True), values,
+ msg='function key should yield all values')
self.assertIs(traverse_obj(morsel, [(None,), any]), morsel,
msg='Morsel should not be implicitly changed to dict on usage')
- def test_get_first(self):
- self.assertEqual(get_first([{'a': None}, {'a': 'spam'}], 'a'), 'spam')
-
+ def test_traversal_filter(self):
+ data = [None, False, True, 0, 1, 0.0, 1.1, '', 'str', {}, {0: 0}, [], [1]]
+
+ self.assertEqual(
+ traverse_obj(data, (Ellipsis, filter)),
+ [True, 1, 1.1, 'str', {0: 0}, [1]],
+ '`filter` should filter falsy values')
+
+
+class TestTraversalHelpers(_TestCase):
+ def test_traversal_require(self):
+ with self.assertRaises(ExtractorError, msg='Missing `value` should raise'):
+ traverse_obj(_TEST_DATA, ('None', T(require('value'))))
+ self.assertEqual(
+ traverse_obj(_TEST_DATA, ('str', T(require('value')))), 'str',
+ '`require` should pass through non-`None` values')
+
+ def test_subs_list_to_dict(self):
+ self.assertEqual(traverse_obj([
+ {'name': 'de', 'url': 'https://example.com/subs/de.vtt'},
+ {'name': 'en', 'url': 'https://example.com/subs/en1.ass'},
+ {'name': 'en', 'url': 'https://example.com/subs/en2.ass'},
+ ], [Ellipsis, {
+ 'id': 'name',
+ 'url': 'url',
+ }, all, T(subs_list_to_dict)]), {
+ 'de': [{'url': 'https://example.com/subs/de.vtt'}],
+ 'en': [
+ {'url': 'https://example.com/subs/en1.ass'},
+ {'url': 'https://example.com/subs/en2.ass'},
+ ],
+ }, 'function should build subtitle dict from list of subtitles')
+ self.assertEqual(traverse_obj([
+ {'name': 'de', 'url': 'https://example.com/subs/de.ass'},
+ {'name': 'de'},
+ {'name': 'en', 'content': 'content'},
+ {'url': 'https://example.com/subs/en'},
+ ], [Ellipsis, {
+ 'id': 'name',
+ 'data': 'content',
+ 'url': 'url',
+ }, all, T(subs_list_to_dict(lang=None))]), {
+ 'de': [{'url': 'https://example.com/subs/de.ass'}],
+ 'en': [{'data': 'content'}],
+ }, 'subs with mandatory items missing should be filtered')
+ self.assertEqual(traverse_obj([
+ {'url': 'https://example.com/subs/de.ass', 'name': 'de'},
+ {'url': 'https://example.com/subs/en', 'name': 'en'},
+ ], [Ellipsis, {
+ 'id': 'name',
+ 'ext': ['url', T(determine_ext(default_ext=None))],
+ 'url': 'url',
+ }, all, T(subs_list_to_dict(ext='ext'))]), {
+ 'de': [{'url': 'https://example.com/subs/de.ass', 'ext': 'ass'}],
+ 'en': [{'url': 'https://example.com/subs/en', 'ext': 'ext'}],
+ }, '`ext` should set default ext but leave existing value untouched')
+ self.assertEqual(traverse_obj([
+ {'name': 'en', 'url': 'https://example.com/subs/en2', 'prio': True},
+ {'name': 'en', 'url': 'https://example.com/subs/en1', 'prio': False},
+ ], [Ellipsis, {
+ 'id': 'name',
+ 'quality': ['prio', T(int)],
+ 'url': 'url',
+ }, all, T(subs_list_to_dict(ext='ext'))]), {'en': [
+ {'url': 'https://example.com/subs/en1', 'ext': 'ext'},
+ {'url': 'https://example.com/subs/en2', 'ext': 'ext'},
+ ]}, '`quality` key should sort subtitle list accordingly')
+ self.assertEqual(traverse_obj([
+ {'name': 'de', 'url': 'https://example.com/subs/de.ass'},
+ {'name': 'de'},
+ {'name': 'en', 'content': 'content'},
+ {'url': 'https://example.com/subs/en'},
+ ], [Ellipsis, {
+ 'id': 'name',
+ 'url': 'url',
+ 'data': 'content',
+ }, all, T(subs_list_to_dict(lang='en'))]), {
+ 'de': [{'url': 'https://example.com/subs/de.ass'}],
+ 'en': [
+ {'data': 'content'},
+ {'url': 'https://example.com/subs/en'},
+ ],
+ }, 'optionally provided lang should be used if no id available')
+ self.assertEqual(traverse_obj([
+ {'name': 1, 'url': 'https://example.com/subs/de1'},
+ {'name': {}, 'url': 'https://example.com/subs/de2'},
+ {'name': 'de', 'ext': 1, 'url': 'https://example.com/subs/de3'},
+ {'name': 'de', 'ext': {}, 'url': 'https://example.com/subs/de4'},
+ ], [Ellipsis, {
+ 'id': 'name',
+ 'url': 'url',
+ 'ext': 'ext',
+ }, all, T(subs_list_to_dict(lang=None))]), {
+ 'de': [
+ {'url': 'https://example.com/subs/de3'},
+ {'url': 'https://example.com/subs/de4'},
+ ],
+ }, 'non str types should be ignored for id and ext')
+ self.assertEqual(traverse_obj([
+ {'name': 1, 'url': 'https://example.com/subs/de1'},
+ {'name': {}, 'url': 'https://example.com/subs/de2'},
+ {'name': 'de', 'ext': 1, 'url': 'https://example.com/subs/de3'},
+ {'name': 'de', 'ext': {}, 'url': 'https://example.com/subs/de4'},
+ ], [Ellipsis, {
+ 'id': 'name',
+ 'url': 'url',
+ 'ext': 'ext',
+ }, all, T(subs_list_to_dict(lang='de'))]), {
+ 'de': [
+ {'url': 'https://example.com/subs/de1'},
+ {'url': 'https://example.com/subs/de2'},
+ {'url': 'https://example.com/subs/de3'},
+ {'url': 'https://example.com/subs/de4'},
+ ],
+ }, 'non str types should be replaced by default id')
+
+ def test_unpack(self):
+ self.assertEqual(
+ unpack(lambda *x: ''.join(map(compat_str, x)))([1, 2, 3]), '123')
+ self.assertEqual(
+ unpack(join_nonempty)([1, 2, 3]), '1-2-3')
+ self.assertEqual(
+ unpack(join_nonempty, delim=' ')([1, 2, 3]), '1 2 3')
+ with self.assertRaises(TypeError):
+ unpack(join_nonempty)()
+ with self.assertRaises(TypeError):
+ unpack()
+
+ def test_value(self):
+ self.assertEqual(
+ traverse_obj(_TEST_DATA, ('str', T(value('other')))), 'other',
+ '`value` should substitute specified value')
+
+
+class TestDictGet(_TestCase):
def test_dict_get(self):
FALSE_VALUES = {
'none': None,
@@ -504,6 +637,9 @@ class TestTraversal(_TestCase):
self.assertEqual(dict_get(d, ('b', 'c', key, )), None)
self.assertEqual(dict_get(d, ('b', 'c', key, ), skip_false_values=False), false_value)
+ def test_get_first(self):
+ self.assertEqual(get_first([{'a': None}, {'a': 'spam'}], 'a'), 'spam')
+
if __name__ == '__main__':
unittest.main()
diff --git a/test/test_utils.py b/test/test_utils.py
index 2947cce7e..1106f2819 100644
--- a/test/test_utils.py
+++ b/test/test_utils.py
@@ -69,6 +69,7 @@ from youtube_dl.utils import (
parse_iso8601,
parse_resolution,
parse_qs,
+ partial_application,
pkcs1pad,
prepend_extension,
read_batch_urls,
@@ -664,6 +665,8 @@ class TestUtil(unittest.TestCase):
self.assertEqual(parse_duration('3h 11m 53s'), 11513)
self.assertEqual(parse_duration('3 hours 11 minutes 53 seconds'), 11513)
self.assertEqual(parse_duration('3 hours 11 mins 53 secs'), 11513)
+ self.assertEqual(parse_duration('3 hours, 11 minutes, 53 seconds'), 11513)
+ self.assertEqual(parse_duration('3 hours, 11 mins, 53 secs'), 11513)
self.assertEqual(parse_duration('62m45s'), 3765)
self.assertEqual(parse_duration('6m59s'), 419)
self.assertEqual(parse_duration('49s'), 49)
@@ -682,6 +685,10 @@ class TestUtil(unittest.TestCase):
self.assertEqual(parse_duration('PT1H0.040S'), 3600.04)
self.assertEqual(parse_duration('PT00H03M30SZ'), 210)
self.assertEqual(parse_duration('P0Y0M0DT0H4M20.880S'), 260.88)
+ self.assertEqual(parse_duration('01:02:03:050'), 3723.05)
+ self.assertEqual(parse_duration('103:050'), 103.05)
+ self.assertEqual(parse_duration('1HR 3MIN'), 3780)
+ self.assertEqual(parse_duration('2hrs 3mins'), 7380)
def test_fix_xml_ampersands(self):
self.assertEqual(
@@ -895,6 +902,30 @@ class TestUtil(unittest.TestCase):
'vcodec': 'av01.0.05M.08',
'acodec': 'none',
})
+ self.assertEqual(parse_codecs('vp9.2'), {
+ 'vcodec': 'vp9.2',
+ 'acodec': 'none',
+ 'dynamic_range': 'HDR10',
+ })
+ self.assertEqual(parse_codecs('vp09.02.50.10.01.09.18.09.00'), {
+ 'vcodec': 'vp09.02.50.10.01.09.18.09.00',
+ 'acodec': 'none',
+ 'dynamic_range': 'HDR10',
+ })
+ self.assertEqual(parse_codecs('av01.0.12M.10.0.110.09.16.09.0'), {
+ 'vcodec': 'av01.0.12M.10.0.110.09.16.09.0',
+ 'acodec': 'none',
+ 'dynamic_range': 'HDR10',
+ })
+ self.assertEqual(parse_codecs('dvhe'), {
+ 'vcodec': 'dvhe',
+ 'acodec': 'none',
+ 'dynamic_range': 'DV',
+ })
+ self.assertEqual(parse_codecs('fLaC'), {
+ 'vcodec': 'none',
+ 'acodec': 'flac',
+ })
self.assertEqual(parse_codecs('theora, vorbis'), {
'vcodec': 'theora',
'acodec': 'vorbis',
@@ -1723,6 +1754,21 @@ Line 1
'a', 'b', 'c', 'd',
from_dict={'a': 'c', 'c': [], 'b': 'd', 'd': None}), 'c-d')
+ def test_partial_application(self):
+ test_fn = partial_application(lambda x, kwarg=None: '{0}, kwarg={1!r}'.format(x, kwarg))
+ self.assertTrue(
+ callable(test_fn(kwarg=10)),
+ 'missing positional parameter should apply partially')
+ self.assertEqual(
+ test_fn(10, kwarg=42), '10, kwarg=42',
+ 'positionally passed argument should call function')
+ self.assertEqual(
+ test_fn(x=10), '10, kwarg=None',
+ 'keyword passed positional should call function')
+ self.assertEqual(
+ test_fn(kwarg=42)(10), '10, kwarg=42',
+ 'call after partial application should call the function')
+
if __name__ == '__main__':
unittest.main()
diff --git a/test/test_youtube_signature.py b/test/test_youtube_signature.py
index 8fdcce8d4..98221b9c2 100644
--- a/test/test_youtube_signature.py
+++ b/test/test_youtube_signature.py
@@ -95,10 +95,50 @@ _SIG_TESTS = [
'0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpz2ICs6EVdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
),
(
+ 'https://www.youtube.com/s/player/363db69b/player_ias_tce.vflset/en_US/base.js',
+ '2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
+ '0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpz2ICs6EVdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
+ ),
+ (
'https://www.youtube.com/s/player/4fcd6e4a/player_ias.vflset/en_US/base.js',
'2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
'wAOAOq0QJ8ARAIgXmPlOPSBkkUs1bYFYlJCfe29xx8q7v1pDL0QwbdV96sCIEzpWqMGkFR20CFOg51Tp-7vj_EMu-m37KtXJoOySqa0',
),
+ (
+ 'https://www.youtube.com/s/player/4fcd6e4a/player_ias_tce.vflset/en_US/base.js',
+ '2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
+ 'wAOAOq0QJ8ARAIgXmPlOPSBkkUs1bYFYlJCfe29xx8q7v1pDL0QwbdV96sCIEzpWqMGkFR20CFOg51Tp-7vj_EMu-m37KtXJoOySqa0',
+ ),
+ (
+ 'https://www.youtube.com/s/player/20830619/player_ias.vflset/en_US/base.js',
+ '2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
+ '7AOq0QJ8wRAIgXmPlOPSBkkAs1bYFYlJCfe29xx8jOv1pDL0Q2bdV96sCIEzpWqMGkFR20CFOg51Tp-7vj_EMu-m37KtXJoOySqa0qaw',
+ ),
+ (
+ 'https://www.youtube.com/s/player/20830619/player_ias_tce.vflset/en_US/base.js',
+ '2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
+ '7AOq0QJ8wRAIgXmPlOPSBkkAs1bYFYlJCfe29xx8jOv1pDL0Q2bdV96sCIEzpWqMGkFR20CFOg51Tp-7vj_EMu-m37KtXJoOySqa0qaw',
+ ),
+ (
+ 'https://www.youtube.com/s/player/20830619/player-plasma-ias-phone-en_US.vflset/base.js',
+ '2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
+ '7AOq0QJ8wRAIgXmPlOPSBkkAs1bYFYlJCfe29xx8jOv1pDL0Q2bdV96sCIEzpWqMGkFR20CFOg51Tp-7vj_EMu-m37KtXJoOySqa0qaw',
+ ),
+ (
+ 'https://www.youtube.com/s/player/20830619/player-plasma-ias-tablet-en_US.vflset/base.js',
+ '2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
+ '7AOq0QJ8wRAIgXmPlOPSBkkAs1bYFYlJCfe29xx8jOv1pDL0Q2bdV96sCIEzpWqMGkFR20CFOg51Tp-7vj_EMu-m37KtXJoOySqa0qaw',
+ ),
+ (
+ 'https://www.youtube.com/s/player/8a8ac953/player_ias_tce.vflset/en_US/base.js',
+ '2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
+ 'IAOAOq0QJ8wRAAgXmPlOPSBkkUs1bYFYlJCfe29xx8j7v1pDL0QwbdV96sCIEzpWqMGkFR20CFOg51Tp-7vj_E2u-m37KtXJoOySqa0',
+ ),
+ (
+ 'https://www.youtube.com/s/player/8a8ac953/tv-player-es6.vflset/tv-player-es6.js',
+ '2aq0aqSyOoJXtK73m-uME_jv7-pT15gOFC02RFkGMqWpzEICs69VdbwQ0LDp1v7j8xx92efCJlYFYb1sUkkBSPOlPmXgIARw8JQ0qOAOAA',
+ 'IAOAOq0QJ8wRAAgXmPlOPSBkkUs1bYFYlJCfe29xx8j7v1pDL0QwbdV96sCIEzpWqMGkFR20CFOg51Tp-7vj_E2u-m37KtXJoOySqa0',
+ ),
]
_NSIG_TESTS = [
@@ -272,7 +312,7 @@ _NSIG_TESTS = [
),
(
'https://www.youtube.com/s/player/643afba4/player_ias.vflset/en_US/base.js',
- 'W9HJZKktxuYoDTqW', 'larxUlagTRAcSw',
+ 'ir9-V6cdbCiyKxhr', '2PL7ZDYAALMfmA',
),
(
'https://www.youtube.com/s/player/363db69b/player_ias.vflset/en_US/base.js',
@@ -286,6 +326,30 @@ _NSIG_TESTS = [
'https://www.youtube.com/s/player/4fcd6e4a/tv-player-ias.vflset/tv-player-ias.js',
'o_L251jm8yhZkWtBW', 'lXoxI3XvToqn6A',
),
+ (
+ 'https://www.youtube.com/s/player/20830619/tv-player-ias.vflset/tv-player-ias.js',
+ 'ir9-V6cdbCiyKxhr', '9YE85kNjZiS4',
+ ),
+ (
+ 'https://www.youtube.com/s/player/20830619/player-plasma-ias-phone-en_US.vflset/base.js',
+ 'ir9-V6cdbCiyKxhr', '9YE85kNjZiS4',
+ ),
+ (
+ 'https://www.youtube.com/s/player/20830619/player-plasma-ias-tablet-en_US.vflset/base.js',
+ 'ir9-V6cdbCiyKxhr', '9YE85kNjZiS4',
+ ),
+ (
+ 'https://www.youtube.com/s/player/8a8ac953/player_ias_tce.vflset/en_US/base.js',
+ 'MiBYeXx_vRREbiCCmh', 'RtZYMVvmkE0JE',
+ ),
+ (
+ 'https://www.youtube.com/s/player/8a8ac953/tv-player-es6.vflset/tv-player-es6.js',
+ 'MiBYeXx_vRREbiCCmh', 'RtZYMVvmkE0JE',
+ ),
+ (
+ 'https://www.youtube.com/s/player/aa3fc80b/player_ias.vflset/en_US/base.js',
+ '0qY9dal2uzOnOGwa-48hha', 'VSh1KDfQMk-eag',
+ ),
]
@@ -335,7 +399,7 @@ def t_factory(name, sig_func, url_pattern):
test_id = re.sub(r'[/.-]', '_', m.group('id') or m.group('compat_id'))
def test_func(self):
- basename = 'player-{0}-{1}.js'.format(name, test_id)
+ basename = 'player-{0}.js'.format(test_id)
fn = os.path.join(self.TESTDATA_DIR, basename)
if not os.path.exists(fn):