Skip to content

Commit 34a4484

Browse files
committed
[YouTube] Add test for a video with a mix in related items
1 parent 50db871 commit 34a4484

8 files changed

Lines changed: 1499 additions & 0 deletions

File tree

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package org.schabi.newpipe.extractor.services.youtube.stream;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
5+
import static org.junit.jupiter.api.Assertions.assertSame;
6+
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertContains;
7+
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
8+
import static org.schabi.newpipe.extractor.ServiceList.YouTube;
9+
import static org.schabi.newpipe.extractor.services.youtube.stream.YoutubeStreamExtractorDefaultTest.YOUTUBE_LICENCE;
10+
11+
import org.junit.jupiter.api.BeforeAll;
12+
import org.junit.jupiter.api.Test;
13+
import org.schabi.newpipe.downloader.DownloaderFactory;
14+
import org.schabi.newpipe.extractor.InfoItem;
15+
import org.schabi.newpipe.extractor.NewPipe;
16+
import org.schabi.newpipe.extractor.StreamingService;
17+
import org.schabi.newpipe.extractor.playlist.PlaylistInfo.PlaylistType;
18+
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
19+
import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest;
20+
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
21+
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor;
22+
import org.schabi.newpipe.extractor.stream.StreamExtractor;
23+
import org.schabi.newpipe.extractor.stream.StreamType;
24+
25+
import java.util.Arrays;
26+
import java.util.List;
27+
import java.util.Objects;
28+
import java.util.Random;
29+
import java.util.stream.Collectors;
30+
31+
import javax.annotation.Nullable;
32+
33+
public class YoutubeStreamExtractorRelatedMixTest extends DefaultStreamExtractorTest {
34+
private static final String RESOURCE_PATH = DownloaderFactory.RESOURCE_PATH + "services/youtube/extractor/stream/";
35+
static final String ID = "K4DyBUG242c";
36+
static final String URL = YoutubeStreamExtractorDefaultTest.BASE_URL + ID;
37+
static final String TITLE = "Cartoon - On & On (feat. Daniel Levi) [NCS Release]";
38+
private static StreamExtractor extractor;
39+
40+
@BeforeAll
41+
public static void setUp() throws Exception {
42+
YoutubeParsingHelper.resetClientVersionAndKey();
43+
YoutubeParsingHelper.setNumberGenerator(new Random(1));
44+
YoutubeStreamExtractor.resetDeobfuscationCode();
45+
NewPipe.init(new DownloaderFactory().getDownloader(RESOURCE_PATH + "relatedMix"));
46+
extractor = YouTube.getStreamExtractor(URL);
47+
extractor.fetchPage();
48+
}
49+
50+
// @formatter:off
51+
@Override public StreamExtractor extractor() { return extractor; }
52+
@Override public StreamingService expectedService() { return YouTube; }
53+
@Override public String expectedName() { return TITLE; }
54+
@Override public String expectedId() { return ID; }
55+
@Override public String expectedUrlContains() { return URL; }
56+
@Override public String expectedOriginalUrlContains() { return URL; }
57+
58+
@Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
59+
@Override public String expectedUploaderName() { return "NoCopyrightSounds"; }
60+
@Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UC_aEa8K-EOJ3D6gOs7HcyNg"; }
61+
@Override public List<String> expectedDescriptionContains() {
62+
return Arrays.asList("https://www.youtube.com/user/danielleviband/", "©");
63+
}
64+
@Override public boolean expectedUploaderVerified() { return true; }
65+
@Override public long expectedLength() { return 208; }
66+
@Override public long expectedTimestamp() { return 0; }
67+
@Override public long expectedViewCountAtLeast() { return 449_000_000; }
68+
@Nullable @Override public String expectedUploadDate() { return "2015-07-09 00:00:00.000"; }
69+
@Nullable @Override public String expectedTextualUploadDate() { return "2015-07-09"; }
70+
@Override public long expectedLikeCountAtLeast() { return 6_400_000; }
71+
@Override public long expectedDislikeCountAtLeast() { return -1; }
72+
@Override public boolean expectedHasSubtitles() { return true; }
73+
@Override public int expectedStreamSegmentsCount() { return 0; }
74+
@Override public String expectedLicence() { return YOUTUBE_LICENCE; }
75+
@Override public String expectedCategory() { return "Music"; }
76+
@Override public List<String> expectedTags() {
77+
return Arrays.asList("Cartoon", "Cartoon - On & On", "Cartoon Baboon",
78+
"Cartoon NCS Release", "Cartoon On & On (feat. Daniel Levi)", "Cartoon best songs",
79+
"Copyright Free Music", "Daniel Levi", "NCS", "NCS Best Songs",
80+
"NCS Cartoon Daniel Levi", "NCS Cartoon On & On", "NCS On & On", "NCS On and On",
81+
"NCS Release", "NCS Release Daniel Levi", "NCS release Cartoon", "Official",
82+
"On & On", "On & On NCS", "On and on", "Royalty Free Cartoon", "Royalty Free Music",
83+
"electronic", "no copyright sounds", "nocopyrightsounds", "on & on lyrics",
84+
"on and on lyrics");
85+
}
86+
// @formatter:on
87+
88+
@Test
89+
@Override
90+
public void testRelatedItems() throws Exception {
91+
super.testRelatedItems();
92+
93+
final List<PlaylistInfoItem> playlists = Objects.requireNonNull(extractor.getRelatedItems())
94+
.getItems()
95+
.stream()
96+
.filter(PlaylistInfoItem.class::isInstance)
97+
.map(PlaylistInfoItem.class::cast)
98+
.collect(Collectors.toList());
99+
playlists.forEach(item -> assertNotEquals(PlaylistType.NORMAL, item.getPlaylistType(),
100+
"Unexpected normal playlist in related items"));
101+
102+
final List<PlaylistInfoItem> streamMixes = playlists.stream()
103+
.filter(item -> item.getPlaylistType().equals(PlaylistType.MIX_STREAM))
104+
.collect(Collectors.toList());
105+
assertEquals(1, streamMixes.size(), "Not found exactly one stream mix in related items");
106+
107+
final PlaylistInfoItem streamMix = streamMixes.get(0);
108+
assertSame(InfoItem.InfoType.PLAYLIST, streamMix.getInfoType());
109+
assertEquals(YouTube.getServiceId(), streamMix.getServiceId());
110+
assertContains(URL, streamMix.getUrl());
111+
assertContains("list=RD" + ID, streamMix.getUrl());
112+
assertEquals("Mix – " + TITLE, streamMix.getName());
113+
assertIsSecureUrl(streamMix.getThumbnailUrl());
114+
}
115+
}

extractor/src/test/resources/org/schabi/newpipe/extractor/services/youtube/extractor/stream/relatedMix/generated_mock_0.json

Lines changed: 226 additions & 0 deletions
Large diffs are not rendered by default.

extractor/src/test/resources/org/schabi/newpipe/extractor/services/youtube/extractor/stream/relatedMix/generated_mock_1.json

Lines changed: 237 additions & 0 deletions
Large diffs are not rendered by default.

extractor/src/test/resources/org/schabi/newpipe/extractor/services/youtube/extractor/stream/relatedMix/generated_mock_2.json

Lines changed: 237 additions & 0 deletions
Large diffs are not rendered by default.

extractor/src/test/resources/org/schabi/newpipe/extractor/services/youtube/extractor/stream/relatedMix/generated_mock_3.json

Lines changed: 227 additions & 0 deletions
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
{
2+
"request": {
3+
"httpMethod": "GET",
4+
"url": "https://www.youtube.com/iframe_api",
5+
"headers": {
6+
"Accept-Language": [
7+
"en-GB, en;q\u003d0.9"
8+
]
9+
},
10+
"localization": {
11+
"languageCode": "en",
12+
"countryCode": "GB"
13+
}
14+
},
15+
"response": {
16+
"responseCode": 200,
17+
"responseMessage": "",
18+
"responseHeaders": {
19+
"alt-svc": [
20+
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000,h3-Q050\u003d\":443\"; ma\u003d2592000,h3-Q046\u003d\":443\"; ma\u003d2592000,h3-Q043\u003d\":443\"; ma\u003d2592000,quic\u003d\":443\"; ma\u003d2592000; v\u003d\"46,43\""
21+
],
22+
"cache-control": [
23+
"private, max-age\u003d0"
24+
],
25+
"content-type": [
26+
"text/javascript; charset\u003dutf-8"
27+
],
28+
"cross-origin-opener-policy-report-only": [
29+
"same-origin; report-to\u003d\"ATmXEA_XZXH6CdbrmjUzyTbVgxu22C8KYH7NsxKbRt94\""
30+
],
31+
"cross-origin-resource-policy": [
32+
"cross-origin"
33+
],
34+
"date": [
35+
"Mon, 28 Feb 2022 18:18:09 GMT"
36+
],
37+
"expires": [
38+
"Mon, 28 Feb 2022 18:18:09 GMT"
39+
],
40+
"p3p": [
41+
"CP\u003d\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl\u003den-GB for more info.\""
42+
],
43+
"permissions-policy": [
44+
"ch-ua-arch\u003d*, ch-ua-bitness\u003d*, ch-ua-full-version\u003d*, ch-ua-full-version-list\u003d*, ch-ua-model\u003d*, ch-ua-platform\u003d*, ch-ua-platform-version\u003d*"
45+
],
46+
"report-to": [
47+
"{\"group\":\"ATmXEA_XZXH6CdbrmjUzyTbVgxu22C8KYH7NsxKbRt94\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/encsid_ATmXEA_XZXH6CdbrmjUzyTbVgxu22C8KYH7NsxKbRt94\"}]}"
48+
],
49+
"server": [
50+
"ESF"
51+
],
52+
"set-cookie": [
53+
"YSC\u003dXQZxEN8iFpc; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
54+
"VISITOR_INFO1_LIVE\u003dPdecpxhX70w; Domain\u003d.youtube.com; Expires\u003dSat, 27-Aug-2022 18:18:09 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
55+
"CONSENT\u003dPENDING+810; expires\u003dWed, 28-Feb-2024 18:18:09 GMT; path\u003d/; domain\u003d.youtube.com; Secure"
56+
],
57+
"strict-transport-security": [
58+
"max-age\u003d31536000"
59+
],
60+
"x-content-type-options": [
61+
"nosniff"
62+
],
63+
"x-frame-options": [
64+
"SAMEORIGIN"
65+
],
66+
"x-xss-protection": [
67+
"0"
68+
]
69+
},
70+
"responseBody": "var scriptUrl \u003d \u0027https:\\/\\/www.youtube.com\\/s\\/player\\/450209b9\\/www-widgetapi.vflset\\/www-widgetapi.js\u0027;try{var ttPolicy\u003dwindow.trustedTypes.createPolicy(\"youtube-widget-api\",{createScriptURL:function(x){return x}});scriptUrl\u003dttPolicy.createScriptURL(scriptUrl)}catch(e){}if(!window[\"YT\"])var YT\u003d{loading:0,loaded:0};if(!window[\"YTConfig\"])var YTConfig\u003d{\"host\":\"https://www.youtube.com\"};\nif(!YT.loading){YT.loading\u003d1;(function(){var l\u003d[];YT.ready\u003dfunction(f){if(YT.loaded)f();else l.push(f)};window.onYTReady\u003dfunction(){YT.loaded\u003d1;for(var i\u003d0;i\u003cl.length;i++)try{l[i]()}catch(e$0){}};YT.setConfig\u003dfunction(c){for(var k in c)if(c.hasOwnProperty(k))YTConfig[k]\u003dc[k]};var a\u003ddocument.createElement(\"script\");a.type\u003d\"text/javascript\";a.id\u003d\"www-widgetapi-script\";a.src\u003dscriptUrl;a.async\u003dtrue;var c\u003ddocument.currentScript;if(c){var n\u003dc.nonce||c.getAttribute(\"nonce\");if(n)a.setAttribute(\"nonce\",n)}var b\u003d\ndocument.getElementsByTagName(\"script\")[0];b.parentNode.insertBefore(a,b)})()};\n",
71+
"latestUrl": "https://www.youtube.com/iframe_api"
72+
}
73+
}

extractor/src/test/resources/org/schabi/newpipe/extractor/services/youtube/extractor/stream/relatedMix/generated_mock_5.json

Lines changed: 71 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)