aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_shorts.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_shorts.py')
-rw-r--r--tests/test_shorts.py56
1 files changed, 54 insertions, 2 deletions
diff --git a/tests/test_shorts.py b/tests/test_shorts.py
index edf7d73..c5b7301 100644
--- a/tests/test_shorts.py
+++ b/tests/test_shorts.py
@@ -11,8 +11,7 @@ import pytest
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
import youtube.proto as proto
from youtube.yt_data_extract.common import (
- extract_item_info, extract_items, extract_shorts_lockup_view_model_info,
- extract_approx_int,
+ extract_item_info, extract_items,
)
@@ -58,6 +57,59 @@ class TestChannelCtokenV5:
assert t_shorts != t_streams
assert t_videos != t_streams
+ def test_include_shorts_false_adds_filter(self):
+ """Test that include_shorts=False adds the shorts filter (field 104)."""
+ # Token with shorts included (default)
+ t_with_shorts = self.channel_ctoken_v5('UCtest', '1', '3', 'videos', include_shorts=True)
+ # Token with shorts excluded
+ t_without_shorts = self.channel_ctoken_v5('UCtest', '1', '3', 'videos', include_shorts=False)
+
+ # The tokens should be different because of the shorts filter
+ assert t_with_shorts != t_without_shorts
+
+ # Decode and verify the filter is present
+ raw_with_shorts = base64.urlsafe_b64decode(t_with_shorts + '==')
+ raw_without_shorts = base64.urlsafe_b64decode(t_without_shorts + '==')
+
+ # Parse the outer protobuf structure
+ import youtube.proto as proto
+ outer_fields_with = list(proto.read_protobuf(raw_with_shorts))
+ outer_fields_without = list(proto.read_protobuf(raw_without_shorts))
+
+ # Field 80226972 contains the inner data
+ inner_with = [v for _, fn, v in outer_fields_with if fn == 80226972][0]
+ inner_without = [v for _, fn, v in outer_fields_without if fn == 80226972][0]
+
+ # Parse the inner data - field 3 contains percent-encoded base64 data
+ inner_fields_with = list(proto.read_protobuf(inner_with))
+ inner_fields_without = list(proto.read_protobuf(inner_without))
+
+ # Get field 3 data (the encoded inner which is percent-encoded base64)
+ encoded_inner_with = [v for _, fn, v in inner_fields_with if fn == 3][0]
+ encoded_inner_without = [v for _, fn, v in inner_fields_without if fn == 3][0]
+
+ # The inner without shorts should contain field 104
+ # Decode the percent-encoded base64 data
+ import urllib.parse
+ decoded_with = urllib.parse.unquote(encoded_inner_with.decode('ascii'))
+ decoded_without = urllib.parse.unquote(encoded_inner_without.decode('ascii'))
+
+ # Decode the base64 data
+ decoded_with_bytes = base64.urlsafe_b64decode(decoded_with + '==')
+ decoded_without_bytes = base64.urlsafe_b64decode(decoded_without + '==')
+
+ # Parse the decoded protobuf data
+ fields_with = list(proto.read_protobuf(decoded_with_bytes))
+ fields_without = list(proto.read_protobuf(decoded_without_bytes))
+
+ field_numbers_with = [fn for _, fn, _ in fields_with]
+ field_numbers_without = [fn for _, fn, _ in fields_without]
+
+ # The 'with' version should NOT have field 104
+ assert 104 not in field_numbers_with
+ # The 'without' version SHOULD have field 104
+ assert 104 in field_numbers_without
+
# --- shortsLockupViewModel parsing ---