Merge pull request #1092 from Stypox/channel-tabs-improvements
Channel tabs code improvements
This commit is contained in:
commit
7936987955
|
@ -43,9 +43,9 @@ public final class YoutubeChannelHelper {
|
|||
}
|
||||
|
||||
// If the URL is not a /channel URL, we need to use the navigation/resolve_url endpoint of
|
||||
// the InnerTube API to get the channel id.
|
||||
// Otherwise, we couldn't get information about the channel associated with this URL, if
|
||||
// there is one.
|
||||
// the InnerTube API to get the channel id. If this fails or if the URL is not a /channel
|
||||
// URL, then no information about the channel associated with this URL was found,
|
||||
// so the unresolved url will be returned.
|
||||
if (!channelId[0].equals("channel")) {
|
||||
final byte[] body = JsonWriter.string(
|
||||
prepareDesktopJsonBuilder(Localization.DEFAULT, ContentCountry.DEFAULT)
|
||||
|
@ -78,6 +78,7 @@ public final class YoutubeChannelHelper {
|
|||
}
|
||||
}
|
||||
|
||||
// return the unresolved URL
|
||||
return channelId[1];
|
||||
}
|
||||
|
||||
|
@ -110,11 +111,11 @@ public final class YoutubeChannelHelper {
|
|||
* Fetch a YouTube channel tab response, using the given channel ID and tab parameters.
|
||||
*
|
||||
* <p>
|
||||
* Redirections to other channels such as are supported to up to 3 redirects, which could
|
||||
* happen for instance for localized channels or auto-generated ones such as the {@code Movies
|
||||
* and Shows} (channel IDs {@code UCuJcl0Ju-gPDoksRjK1ya-w}, {@code UChBfWrfBXL9wS6tQtgjt_OQ}
|
||||
* and {@code UCok7UTQQEP1Rsctxiv3gwSQ} of this channel redirect to the
|
||||
* {@code UClgRkhTL3_hImCAmdLfDE4g} one).
|
||||
* Redirections to other channels are supported to up to 3 redirects, which could happen for
|
||||
* instance for localized channels or for auto-generated ones. For instance, there are three IDs
|
||||
* of the auto-generated "Movies and Shows" channel, i.e. {@code UCuJcl0Ju-gPDoksRjK1ya-w},
|
||||
* {@code UChBfWrfBXL9wS6tQtgjt_OQ} and {@code UCok7UTQQEP1Rsctxiv3gwSQ}, and they all redirect
|
||||
* to the {@code UClgRkhTL3_hImCAmdLfDE4g} one.
|
||||
* </p>
|
||||
*
|
||||
* @param channelId a valid YouTube channel ID
|
||||
|
@ -177,7 +178,7 @@ public final class YoutubeChannelHelper {
|
|||
}
|
||||
|
||||
if (ajaxJson == null) {
|
||||
throw new ExtractionException("Got no channel response");
|
||||
throw new ExtractionException("Got no channel response after 3 redirects");
|
||||
}
|
||||
|
||||
defaultAlertsCheck(ajaxJson);
|
||||
|
|
|
@ -57,6 +57,7 @@ import javax.annotation.Nullable;
|
|||
public class YoutubeChannelExtractor extends ChannelExtractor {
|
||||
|
||||
private JsonObject jsonResponse;
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private Optional<YoutubeChannelHelper.ChannelHeader> channelHeader;
|
||||
|
||||
|
@ -89,6 +90,7 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
"EgZ2aWRlb3PyBgQKAjoA", getExtractorLocalization(), getExtractorContentCountry());
|
||||
|
||||
jsonResponse = data.jsonResponse;
|
||||
channelHeader = YoutubeChannelHelper.getChannelHeader(jsonResponse);
|
||||
channelId = data.channelId;
|
||||
channelAgeGateRenderer = getChannelAgeGateRenderer();
|
||||
}
|
||||
|
@ -115,12 +117,8 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
}
|
||||
|
||||
@Nonnull
|
||||
private Optional<YoutubeChannelHelper.ChannelHeader> getChannelHeader() {
|
||||
//noinspection OptionalAssignedToNull
|
||||
if (channelHeader == null) {
|
||||
channelHeader = YoutubeChannelHelper.getChannelHeader(jsonResponse);
|
||||
}
|
||||
return channelHeader;
|
||||
private Optional<JsonObject> getChannelHeaderJson() {
|
||||
return channelHeader.map(it -> it.json);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -136,9 +134,9 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
@Nonnull
|
||||
@Override
|
||||
public String getId() throws ParsingException {
|
||||
return getChannelHeader()
|
||||
.flatMap(header -> Optional.ofNullable(header.json.getString("channelId"))
|
||||
.or(() -> Optional.ofNullable(header.json.getObject("navigationEndpoint")
|
||||
return getChannelHeaderJson()
|
||||
.flatMap(header -> Optional.ofNullable(header.getString("channelId"))
|
||||
.or(() -> Optional.ofNullable(header.getObject("navigationEndpoint")
|
||||
.getObject("browseEndpoint")
|
||||
.getString("browseId"))
|
||||
))
|
||||
|
@ -160,8 +158,8 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
return metadataRendererTitle;
|
||||
}
|
||||
|
||||
return getChannelHeader().flatMap(header -> {
|
||||
final Object title = header.json.get("title");
|
||||
return getChannelHeaderJson().flatMap(header -> {
|
||||
final Object title = header.get("title");
|
||||
if (title instanceof String) {
|
||||
return Optional.of((String) title);
|
||||
} else if (title instanceof JsonObject) {
|
||||
|
@ -180,7 +178,7 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
if (channelAgeGateRenderer != null) {
|
||||
avatarJsonObjectContainer = channelAgeGateRenderer;
|
||||
} else {
|
||||
avatarJsonObjectContainer = getChannelHeader().map(header -> header.json)
|
||||
avatarJsonObjectContainer = getChannelHeaderJson()
|
||||
.orElseThrow(() -> new ParsingException("Could not get avatar URL"));
|
||||
}
|
||||
|
||||
|
@ -196,8 +194,8 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
return "";
|
||||
}
|
||||
|
||||
return getChannelHeader().flatMap(header -> Optional.ofNullable(
|
||||
header.json.getObject("banner")
|
||||
return getChannelHeaderJson().flatMap(header -> Optional.ofNullable(
|
||||
header.getObject("banner")
|
||||
.getArray("thumbnails")
|
||||
.getObject(0)
|
||||
.getString("url")))
|
||||
|
@ -226,9 +224,9 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
return UNKNOWN_SUBSCRIBER_COUNT;
|
||||
}
|
||||
|
||||
final Optional<YoutubeChannelHelper.ChannelHeader> headerOpt = getChannelHeader();
|
||||
final Optional<JsonObject> headerOpt = getChannelHeaderJson();
|
||||
if (headerOpt.isPresent()) {
|
||||
final JsonObject header = headerOpt.get().json;
|
||||
final JsonObject header = headerOpt.get();
|
||||
JsonObject textObject = null;
|
||||
|
||||
if (header.has("subscriberCountText")) {
|
||||
|
@ -285,9 +283,8 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
return false;
|
||||
}
|
||||
|
||||
final Optional<YoutubeChannelHelper.ChannelHeader> headerOpt = getChannelHeader();
|
||||
if (headerOpt.isPresent()) {
|
||||
final YoutubeChannelHelper.ChannelHeader header = headerOpt.get();
|
||||
if (channelHeader.isPresent()) {
|
||||
final YoutubeChannelHelper.ChannelHeader header = channelHeader.get();
|
||||
|
||||
// The CarouselHeaderRenderer does not contain any verification badges.
|
||||
// Since it is only shown on YT-internal channels or on channels of large organizations
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.io.IOException;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.schabi.newpipe.extractor.services.youtube.YoutubeChannelHelper.getChannelResponse;
|
||||
import static org.schabi.newpipe.extractor.services.youtube.YoutubeChannelHelper.resolveChannelId;
|
||||
|
@ -299,20 +298,20 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
.getObject("content");
|
||||
|
||||
if (richItem.has("videoRenderer")) {
|
||||
getCommitVideoConsumer(collector, timeAgoParser, channelIds).accept(
|
||||
getCommitVideoConsumer(collector, timeAgoParser, channelIds,
|
||||
richItem.getObject("videoRenderer"));
|
||||
} else if (richItem.has("reelItemRenderer")) {
|
||||
getCommitReelItemConsumer(collector, timeAgoParser, channelIds).accept(
|
||||
getCommitReelItemConsumer(collector, timeAgoParser, channelIds,
|
||||
richItem.getObject("reelItemRenderer"));
|
||||
} else if (richItem.has("playlistRenderer")) {
|
||||
getCommitPlaylistConsumer(collector, channelIds).accept(
|
||||
getCommitPlaylistConsumer(collector, channelIds,
|
||||
item.getObject("playlistRenderer"));
|
||||
}
|
||||
} else if (item.has("gridVideoRenderer")) {
|
||||
getCommitVideoConsumer(collector, timeAgoParser, channelIds).accept(
|
||||
getCommitVideoConsumer(collector, timeAgoParser, channelIds,
|
||||
item.getObject("gridVideoRenderer"));
|
||||
} else if (item.has("gridPlaylistRenderer")) {
|
||||
getCommitPlaylistConsumer(collector, channelIds).accept(
|
||||
getCommitPlaylistConsumer(collector, channelIds,
|
||||
item.getObject("gridPlaylistRenderer"));
|
||||
} else if (item.has("gridChannelRenderer")) {
|
||||
collector.commit(new YoutubeChannelInfoItemExtractor(
|
||||
|
@ -336,13 +335,12 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Consumer<JsonObject> getCommitVideoConsumer(
|
||||
@Nonnull final MultiInfoItemsCollector collector,
|
||||
@Nonnull final TimeAgoParser timeAgoParser,
|
||||
@Nonnull final List<String> channelIds) {
|
||||
return videoRenderer -> collector.commit(
|
||||
new YoutubeStreamInfoItemExtractor(videoRenderer, timeAgoParser) {
|
||||
private void getCommitVideoConsumer(@Nonnull final MultiInfoItemsCollector collector,
|
||||
@Nonnull final TimeAgoParser timeAgoParser,
|
||||
@Nonnull final List<String> channelIds,
|
||||
@Nonnull final JsonObject jsonObject) {
|
||||
collector.commit(
|
||||
new YoutubeStreamInfoItemExtractor(jsonObject, timeAgoParser) {
|
||||
@Override
|
||||
public String getUploaderName() throws ParsingException {
|
||||
if (channelIds.size() >= 2) {
|
||||
|
@ -361,13 +359,12 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
});
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Consumer<JsonObject> getCommitReelItemConsumer(
|
||||
@Nonnull final MultiInfoItemsCollector collector,
|
||||
@Nonnull final TimeAgoParser timeAgoParser,
|
||||
@Nonnull final List<String> channelIds) {
|
||||
return reelItemRenderer -> collector.commit(
|
||||
new YoutubeReelInfoItemExtractor(reelItemRenderer, timeAgoParser) {
|
||||
private void getCommitReelItemConsumer(@Nonnull final MultiInfoItemsCollector collector,
|
||||
@Nonnull final TimeAgoParser timeAgoParser,
|
||||
@Nonnull final List<String> channelIds,
|
||||
@Nonnull final JsonObject jsonObject) {
|
||||
collector.commit(
|
||||
new YoutubeReelInfoItemExtractor(jsonObject, timeAgoParser) {
|
||||
@Override
|
||||
public String getUploaderName() throws ParsingException {
|
||||
if (channelIds.size() >= 2) {
|
||||
|
@ -386,12 +383,11 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
});
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Consumer<JsonObject> getCommitPlaylistConsumer(
|
||||
@Nonnull final MultiInfoItemsCollector collector,
|
||||
@Nonnull final List<String> channelIds) {
|
||||
return playlistRenderer -> collector.commit(
|
||||
new YoutubePlaylistInfoItemExtractor(playlistRenderer) {
|
||||
private void getCommitPlaylistConsumer(@Nonnull final MultiInfoItemsCollector collector,
|
||||
@Nonnull final List<String> channelIds,
|
||||
@Nonnull final JsonObject jsonObject) {
|
||||
collector.commit(
|
||||
new YoutubePlaylistInfoItemExtractor(jsonObject) {
|
||||
@Override
|
||||
public String getUploaderName() throws ParsingException {
|
||||
if (channelIds.size() >= 2) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.schabi.newpipe.extractor.services.youtube.extractors;
|
||||
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
|
||||
import org.schabi.newpipe.extractor.Page;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
|
||||
|
@ -12,14 +13,11 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
|||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubePlaylistLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* A {@link ChannelTabExtractor} for YouTube system playlists using a
|
||||
|
@ -74,35 +72,19 @@ public class YoutubeChannelTabPlaylistExtractor extends ChannelTabExtractor {
|
|||
|
||||
@Nonnull
|
||||
@Override
|
||||
public InfoItemsPage<InfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||
public InfoItemsPage getInitialPage() throws IOException, ExtractionException {
|
||||
if (!playlistExisting) {
|
||||
return InfoItemsPage.emptyPage();
|
||||
}
|
||||
|
||||
final InfoItemsPage<StreamInfoItem> playlistInitialPage =
|
||||
playlistExtractorInstance.getInitialPage();
|
||||
|
||||
// We can't provide the playlist page as it is due to a type conflict, we need to wrap the
|
||||
// page items and provide a new InfoItemsPage
|
||||
final List<InfoItem> infoItems = new ArrayList<>(playlistInitialPage.getItems());
|
||||
return new InfoItemsPage<>(infoItems, playlistInitialPage.getNextPage(),
|
||||
playlistInitialPage.getErrors());
|
||||
return playlistExtractorInstance.getInitialPage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<InfoItem> getPage(final Page page)
|
||||
throws IOException, ExtractionException {
|
||||
public InfoItemsPage getPage(final Page page) throws IOException, ExtractionException {
|
||||
if (!playlistExisting) {
|
||||
return InfoItemsPage.emptyPage();
|
||||
}
|
||||
|
||||
final InfoItemsPage<StreamInfoItem> playlistPage = playlistExtractorInstance.getPage(page);
|
||||
|
||||
// We can't provide the playlist page as it is due to a type conflict, we need to wrap the
|
||||
// page items and provide a new InfoItemsPage
|
||||
final List<InfoItem> infoItems = new ArrayList<>(playlistPage.getItems());
|
||||
return new InfoItemsPage<>(infoItems, playlistPage.getNextPage(),
|
||||
playlistPage.getErrors());
|
||||
return playlistExtractorInstance.getPage(page);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -151,8 +151,8 @@ public class ExtractorAsserts {
|
|||
"'" + shouldBeContained + "' should be contained inside '" + container + "'");
|
||||
}
|
||||
|
||||
public static void assertTabsContained(@Nonnull final List<ListLinkHandler> tabs,
|
||||
@Nonnull final String... expectedTabs) {
|
||||
public static void assertTabsContain(@Nonnull final List<ListLinkHandler> tabs,
|
||||
@Nonnull final String... expectedTabs) {
|
||||
final Set<String> tabSet = tabs.stream()
|
||||
.map(linkHandler -> linkHandler.getContentFilters().get(0))
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
|
|
|
@ -11,7 +11,7 @@ import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
|||
import org.schabi.newpipe.extractor.services.BaseChannelExtractorTest;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertTabsContained;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertTabsContain;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.Bandcamp;
|
||||
|
||||
public class BandcampChannelExtractorTest implements BaseChannelExtractorTest {
|
||||
|
@ -84,7 +84,7 @@ public class BandcampChannelExtractorTest implements BaseChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.ALBUMS);
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.ALBUMS);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -3,22 +3,27 @@ package org.schabi.newpipe.extractor.services.bandcamp;
|
|||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.schabi.newpipe.downloader.DownloaderTestImpl;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.BaseListExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.DefaultListExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampChannelTabExtractor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.Bandcamp;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestRelatedItems;
|
||||
|
||||
class BandcampChannelTabExtractorTest {
|
||||
|
||||
static class Tracks implements BaseListExtractorTest {
|
||||
static class Tracks extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static BandcampChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -29,50 +34,17 @@ class BandcampChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() throws Exception {
|
||||
assertEquals(Bandcamp.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.TRACKS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("2464198920", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://wintergatan.bandcamp.com/track", extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://wintergatan.bandcamp.com/track", extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
// Bandcamp only return a single page
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return Bandcamp; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.TRACKS; }
|
||||
@Override public String expectedId() throws Exception { return "2464198920"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://wintergatan.bandcamp.com/track"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://wintergatan.bandcamp.com/track"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; }
|
||||
@Override public boolean expectedHasMoreItems() { return false; }
|
||||
}
|
||||
|
||||
static class Albums implements BaseListExtractorTest {
|
||||
static class Albums extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static BandcampChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -83,46 +55,13 @@ class BandcampChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(Bandcamp.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.ALBUMS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("2450875064", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://toupie.bandcamp.com/album", extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://toupie.bandcamp.com/album", extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
// Bandcamp only return a single page
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return Bandcamp; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.ALBUMS; }
|
||||
@Override public String expectedId() throws Exception { return "2450875064"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://toupie.bandcamp.com/album"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://toupie.bandcamp.com/album"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.PLAYLIST; }
|
||||
@Override public boolean expectedHasMoreItems() { return false; }
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertTabsContained;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertTabsContain;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
|
||||
/**
|
||||
|
@ -103,7 +103,7 @@ public class PeertubeAccountExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.CHANNELS);
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.CHANNELS);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -192,7 +192,7 @@ public class PeertubeAccountExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.CHANNELS);
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.CHANNELS);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -3,10 +3,14 @@ package org.schabi.newpipe.extractor.services.peertube;
|
|||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.schabi.newpipe.downloader.DownloaderTestImpl;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.BaseListExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.DefaultListExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeChannelTabExtractor;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
@ -16,7 +20,7 @@ import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestRela
|
|||
|
||||
class PeertubeAccountTabExtractorTest {
|
||||
|
||||
static class Videos implements BaseListExtractorTest {
|
||||
static class Videos extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static PeertubeChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -29,60 +33,17 @@ class PeertubeAccountTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Extractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(PeerTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws ParsingException {
|
||||
assertEquals(ChannelTabs.VIDEOS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("accounts/framasoft", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://framatube.org/accounts/framasoft/videos",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws ParsingException {
|
||||
assertEquals("https://framatube.org/accounts/framasoft/videos",
|
||||
extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// ListExtractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return PeerTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.VIDEOS; }
|
||||
@Override public String expectedId() throws Exception { return "accounts/framasoft"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://framatube.org/accounts/framasoft/videos"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://framatube.org/accounts/framasoft/videos"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
|
||||
static class Channels implements BaseListExtractorTest {
|
||||
static class Channels extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static PeertubeChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -95,56 +56,13 @@ class PeertubeAccountTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Extractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(PeerTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws ParsingException {
|
||||
assertEquals(ChannelTabs.CHANNELS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("accounts/framasoft", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://framatube.org/accounts/framasoft/video-channels",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws ParsingException {
|
||||
assertEquals("https://framatube.org/accounts/framasoft/video-channels",
|
||||
extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// ListExtractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return PeerTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.CHANNELS; }
|
||||
@Override public String expectedId() throws Exception { return "accounts/framasoft"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://framatube.org/accounts/framasoft/video-channels"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://framatube.org/accounts/framasoft/video-channels"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.CHANNEL; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertTabsContained;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertTabsContain;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
|
||||
/**
|
||||
|
@ -118,7 +118,7 @@ public class PeertubeChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS);
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -223,7 +223,7 @@ public class PeertubeChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS);
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestGetPageInNewExtractor;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.schabi.newpipe.downloader.DownloaderTestImpl;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.BaseListExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.DefaultListExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeChannelTabExtractor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.*;
|
||||
|
||||
class PeertubeChannelTabExtractorTest {
|
||||
|
||||
static class Videos implements BaseListExtractorTest {
|
||||
static class Videos extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static PeertubeChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -32,61 +32,14 @@ class PeertubeChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Extractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(PeerTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws ParsingException {
|
||||
assertEquals(ChannelTabs.VIDEOS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("video-channels/lqdn_channel@video.lqdn.fr", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://framatube.org/video-channels/lqdn_channel@video.lqdn.fr/videos",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws ParsingException {
|
||||
assertEquals("https://framatube.org/video-channels/lqdn_channel@video.lqdn.fr/videos",
|
||||
extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// ListExtractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Additional Testing
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return PeerTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.VIDEOS; }
|
||||
@Override public String expectedId() throws Exception { return "video-channels/lqdn_channel@video.lqdn.fr"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://framatube.org/video-channels/lqdn_channel@video.lqdn.fr/videos"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://framatube.org/video-channels/lqdn_channel@video.lqdn.fr/videos"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
|
||||
@Test
|
||||
void testGetPageInNewExtractor() throws Exception {
|
||||
|
@ -96,7 +49,7 @@ class PeertubeChannelTabExtractorTest {
|
|||
}
|
||||
}
|
||||
|
||||
static class Playlists implements BaseListExtractorTest {
|
||||
static class Playlists extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static PeertubeChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -109,51 +62,17 @@ class PeertubeChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(PeerTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.PLAYLISTS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("video-channels/lqdn_channel@video.lqdn.fr", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://framatube.org/video-channels/lqdn_channel@video.lqdn.fr/video-playlists",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://framatube.org/video-channels/lqdn_channel@video.lqdn.fr/video-playlists",
|
||||
extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return PeerTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.PLAYLISTS; }
|
||||
@Override public String expectedId() throws Exception { return "video-channels/lqdn_channel@video.lqdn.fr"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://framatube.org/video-channels/lqdn_channel@video.lqdn.fr/video-playlists"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://framatube.org/video-channels/lqdn_channel@video.lqdn.fr/video-playlists"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.PLAYLIST; }
|
||||
@Override public boolean expectedHasMoreItems() { return false; }
|
||||
}
|
||||
|
||||
static class Channels implements BaseListExtractorTest {
|
||||
static class Channels extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static PeertubeChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -165,48 +84,13 @@ class PeertubeChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(PeerTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.CHANNELS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("accounts/framasoft", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://framatube.org/accounts/framasoft/video-channels",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://framatube.org/accounts/framasoft/video-channels",
|
||||
extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return PeerTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.CHANNELS; }
|
||||
@Override public String expectedId() throws Exception { return "accounts/framasoft"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://framatube.org/accounts/framasoft/video-channels"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://framatube.org/accounts/framasoft/video-channels"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.CHANNEL; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudCha
|
|||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertEmpty;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertTabsContained;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertTabsContain;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
|
||||
|
||||
/**
|
||||
|
@ -96,7 +96,7 @@ public class SoundcloudChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.TRACKS, ChannelTabs.PLAYLISTS,
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.TRACKS, ChannelTabs.PLAYLISTS,
|
||||
ChannelTabs.ALBUMS);
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ public class SoundcloudChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.TRACKS, ChannelTabs.PLAYLISTS,
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.TRACKS, ChannelTabs.PLAYLISTS,
|
||||
ChannelTabs.ALBUMS);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,17 +3,21 @@ package org.schabi.newpipe.extractor.services.soundcloud;
|
|||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.schabi.newpipe.downloader.DownloaderTestImpl;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.BaseListExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.DefaultListExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChannelTabExtractor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestGetPageInNewExtractor;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestMoreItems;
|
||||
|
@ -21,7 +25,7 @@ import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestRela
|
|||
|
||||
class SoundcloudChannelTabExtractorTest {
|
||||
|
||||
static class Tracks implements BaseListExtractorTest {
|
||||
static class Tracks extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static SoundcloudChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -32,51 +36,14 @@ class SoundcloudChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() throws Exception {
|
||||
assertEquals(SoundCloud.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.TRACKS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws Exception {
|
||||
assertEquals("10494998", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws Exception {
|
||||
assertEquals("https://soundcloud.com/liluzivert/tracks", extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://soundcloud.com/liluzivert/tracks", extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Additional Testing
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return SoundCloud; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.TRACKS; }
|
||||
@Override public String expectedId() throws Exception { return "10494998"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://soundcloud.com/liluzivert/tracks"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://soundcloud.com/liluzivert/tracks"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
|
||||
@Test
|
||||
void testGetPageInNewExtractor() throws Exception {
|
||||
|
@ -86,7 +53,7 @@ class SoundcloudChannelTabExtractorTest {
|
|||
}
|
||||
}
|
||||
|
||||
static class Playlists implements BaseListExtractorTest {
|
||||
static class Playlists extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static SoundcloudChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -97,50 +64,17 @@ class SoundcloudChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(SoundCloud.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.PLAYLISTS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("323371733", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://soundcloud.com/trackaholic/sets", extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://soundcloud.com/trackaholic/sets", extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return SoundCloud; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.PLAYLISTS; }
|
||||
@Override public String expectedId() throws Exception { return "323371733"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://soundcloud.com/trackaholic/sets"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://soundcloud.com/trackaholic/sets"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.PLAYLIST; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
|
||||
static class Albums implements BaseListExtractorTest {
|
||||
static class Albums extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static SoundcloudChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -151,46 +85,13 @@ class SoundcloudChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(SoundCloud.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.ALBUMS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("4803918", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://soundcloud.com/bigsean-1/albums", extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://soundcloud.com/bigsean-1/albums", extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return SoundCloud; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.ALBUMS; }
|
||||
@Override public String expectedId() throws Exception { return "4803918"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://soundcloud.com/bigsean-1/albums"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://soundcloud.com/bigsean-1/albums"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.PLAYLIST; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
|||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertContains;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertTabsContained;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertTabsContain;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.YouTube;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestGetPageInNewExtractor;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
|
@ -233,8 +233,11 @@ public class YoutubeChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.VIDEOS,
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS,
|
||||
ChannelTabs.LIVESTREAMS, ChannelTabs.PLAYLISTS, ChannelTabs.CHANNELS);
|
||||
assertTrue(extractor.getTabs().stream()
|
||||
.filter(it -> ChannelTabs.VIDEOS.equals(it.getContentFilters().get(0)))
|
||||
.allMatch(ReadyChannelTabListLinkHandler.class::isInstance));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -327,8 +330,11 @@ public class YoutubeChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.LIVESTREAMS,
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.LIVESTREAMS,
|
||||
ChannelTabs.SHORTS, ChannelTabs.PLAYLISTS, ChannelTabs.CHANNELS);
|
||||
assertTrue(extractor.getTabs().stream()
|
||||
.filter(it -> ChannelTabs.VIDEOS.equals(it.getContentFilters().get(0)))
|
||||
.allMatch(ReadyChannelTabListLinkHandler.class::isInstance));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -424,8 +430,11 @@ public class YoutubeChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.SHORTS,
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.SHORTS,
|
||||
ChannelTabs.PLAYLISTS, ChannelTabs.CHANNELS);
|
||||
assertTrue(extractor.getTabs().stream()
|
||||
.filter(it -> ChannelTabs.VIDEOS.equals(it.getContentFilters().get(0)))
|
||||
.allMatch(ReadyChannelTabListLinkHandler.class::isInstance));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -545,8 +554,11 @@ public class YoutubeChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS,
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS,
|
||||
ChannelTabs.CHANNELS);
|
||||
assertTrue(extractor.getTabs().stream()
|
||||
.filter(it -> ChannelTabs.VIDEOS.equals(it.getContentFilters().get(0)))
|
||||
.allMatch(ReadyChannelTabListLinkHandler.class::isInstance));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -639,8 +651,11 @@ public class YoutubeChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS,
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS,
|
||||
ChannelTabs.CHANNELS);
|
||||
assertTrue(extractor.getTabs().stream()
|
||||
.filter(it -> ChannelTabs.VIDEOS.equals(it.getContentFilters().get(0)))
|
||||
.allMatch(ReadyChannelTabListLinkHandler.class::isInstance));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -730,8 +745,11 @@ public class YoutubeChannelExtractorTest {
|
|||
@Test
|
||||
@Override
|
||||
public void testTabs() throws Exception {
|
||||
assertTabsContained(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.SHORTS,
|
||||
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.SHORTS,
|
||||
ChannelTabs.LIVESTREAMS, ChannelTabs.PLAYLISTS, ChannelTabs.CHANNELS);
|
||||
assertTrue(extractor.getTabs().stream()
|
||||
.filter(it -> ChannelTabs.VIDEOS.equals(it.getContentFilters().get(0)))
|
||||
.allMatch(ReadyChannelTabListLinkHandler.class::isInstance));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -846,7 +864,7 @@ public class YoutubeChannelExtractorTest {
|
|||
public void testTabs() throws Exception {
|
||||
// Channel tabs which may be available and which will be extracted from channel system
|
||||
// uploads playlists
|
||||
assertTabsContained(extractor.getTabs(),
|
||||
assertTabsContain(extractor.getTabs(),
|
||||
ChannelTabs.VIDEOS, ChannelTabs.SHORTS, ChannelTabs.LIVESTREAMS);
|
||||
|
||||
// Check if all tabs are not classic tabs, so that link handlers are of the appropriate
|
||||
|
|
|
@ -1,34 +1,30 @@
|
|||
package org.schabi.newpipe.extractor.services.youtube;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.YouTube;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.schabi.newpipe.downloader.DownloaderFactory;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.BaseListExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.DefaultListExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeChannelTabExtractor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.YouTube;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestMoreItems;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestRelatedItems;
|
||||
|
||||
class YoutubeChannelTabExtractorTest {
|
||||
|
||||
private static final String RESOURCE_PATH = DownloaderFactory.RESOURCE_PATH
|
||||
+ "services/youtube/extractor/channelTabs/";
|
||||
|
||||
static class Videos implements BaseListExtractorTest {
|
||||
static class Videos extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static YoutubeChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -40,52 +36,17 @@ class YoutubeChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(YouTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.VIDEOS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("UCTwECeGqMZee77BjdoYtI2Q", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://www.youtube.com/channel/UCTwECeGqMZee77BjdoYtI2Q/videos",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://www.youtube.com/user/creativecommons/videos",
|
||||
extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return YouTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.VIDEOS; }
|
||||
@Override public String expectedId() throws Exception { return "UCTwECeGqMZee77BjdoYtI2Q"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://www.youtube.com/channel/UCTwECeGqMZee77BjdoYtI2Q/videos"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://www.youtube.com/user/creativecommons/videos"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
|
||||
static class Playlists implements BaseListExtractorTest {
|
||||
static class Playlists extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static YoutubeChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -97,52 +58,17 @@ class YoutubeChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(YouTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.PLAYLISTS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("UC2DjFE7Xf11URZqWBigcVOQ", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ/playlists",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://www.youtube.com/@EEVblog/playlists",
|
||||
extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return YouTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.PLAYLISTS; }
|
||||
@Override public String expectedId() throws Exception { return "UC2DjFE7Xf11URZqWBigcVOQ"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ/playlists"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://www.youtube.com/@EEVblog/playlists"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.PLAYLIST; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
|
||||
static class Channels implements BaseListExtractorTest {
|
||||
static class Channels extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static YoutubeChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -154,52 +80,17 @@ class YoutubeChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(YouTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.CHANNELS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("UC2DjFE7Xf11URZqWBigcVOQ", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ/channels",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ/channels",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return YouTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.CHANNELS; }
|
||||
@Override public String expectedId() throws Exception { return "UC2DjFE7Xf11URZqWBigcVOQ"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ/channels"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ/channels"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.CHANNEL; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
|
||||
static class Livestreams implements BaseListExtractorTest {
|
||||
static class Livestreams extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static YoutubeChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -211,52 +102,17 @@ class YoutubeChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(YouTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.LIVESTREAMS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("UCR-DXc1voovS8nhAvccRZhg", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://www.youtube.com/channel/UCR-DXc1voovS8nhAvccRZhg/streams",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://www.youtube.com/c/JeffGeerling/streams",
|
||||
extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return YouTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.LIVESTREAMS; }
|
||||
@Override public String expectedId() throws Exception { return "UCR-DXc1voovS8nhAvccRZhg"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://www.youtube.com/channel/UCR-DXc1voovS8nhAvccRZhg/streams"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://www.youtube.com/c/JeffGeerling/streams"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
|
||||
static class Shorts implements BaseListExtractorTest {
|
||||
static class Shorts extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static YoutubeChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -268,130 +124,80 @@ class YoutubeChannelTabExtractorTest {
|
|||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(YouTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.SHORTS, extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("UCh8gHdtzO2tXd593_bjErWg", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://www.youtube.com/channel/UCh8gHdtzO2tXd593_bjErWg/shorts",
|
||||
extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://www.youtube.com/channel/UCh8gHdtzO2tXd593_bjErWg/shorts",
|
||||
extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor);
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return YouTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.SHORTS; }
|
||||
@Override public String expectedId() throws Exception { return "UCh8gHdtzO2tXd593_bjErWg"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://www.youtube.com/channel/UCh8gHdtzO2tXd593_bjErWg/shorts"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://www.youtube.com/channel/UCh8gHdtzO2tXd593_bjErWg/shorts"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
|
||||
static class AgeRestrictedTabs implements BaseListExtractorTest {
|
||||
private static ChannelTabExtractor videosTabExtractor;
|
||||
private static ChannelTabExtractor shortsTabExtractor;
|
||||
|
||||
// TESTS FOR TABS OF AGE RESTRICTED CHANNELS
|
||||
// Fetching the tabs individually would use the standard tabs without fallback to
|
||||
// system playlists for stream tabs, we need to fetch the channel extractor to get the
|
||||
// channel playlist tabs
|
||||
// TODO: implement system playlists fallback in YoutubeChannelTabExtractor for stream
|
||||
// tabs
|
||||
|
||||
static class AgeRestrictedTabsVideos extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static ChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
static void setUp() throws IOException, ExtractionException {
|
||||
YoutubeTestsUtils.ensureStateless();
|
||||
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "ageRestricted"));
|
||||
final ChannelExtractor extractor = YouTube.getChannelExtractor(
|
||||
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "ageRestrictedTabsVideos"));
|
||||
final ChannelExtractor channelExtractor = YouTube.getChannelExtractor(
|
||||
"https://www.youtube.com/channel/UCbfnHqxXs_K3kvaH-WlNlig");
|
||||
channelExtractor.fetchPage();
|
||||
|
||||
// the videos tab is the first one
|
||||
extractor = YouTube.getChannelTabExtractor(channelExtractor.getTabs().get(0));
|
||||
extractor.fetchPage();
|
||||
|
||||
// Fetching the tabs individually would use the standard tabs without fallback to
|
||||
// system playlists for stream tabs, we need to fetch the channel extractor to get the
|
||||
// channel playlist tabs
|
||||
// TODO: implement system playlists fallback in YoutubeChannelTabExtractor for stream
|
||||
// tabs
|
||||
final List<ListLinkHandler> tabs = extractor.getTabs();
|
||||
videosTabExtractor = YouTube.getChannelTabExtractor(tabs.get(0));
|
||||
videosTabExtractor.fetchPage();
|
||||
shortsTabExtractor = YouTube.getChannelTabExtractor(tabs.get(1));
|
||||
shortsTabExtractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testServiceId() {
|
||||
assertEquals(YouTube.getServiceId(), videosTabExtractor.getServiceId());
|
||||
assertEquals(YouTube.getServiceId(), shortsTabExtractor.getServiceId());
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return YouTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.VIDEOS; }
|
||||
@Override public String expectedId() throws Exception { return "UCbfnHqxXs_K3kvaH-WlNlig"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://www.youtube.com/channel/UCbfnHqxXs_K3kvaH-WlNlig/videos"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://www.youtube.com/channel/UCbfnHqxXs_K3kvaH-WlNlig/videos"; }
|
||||
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; }
|
||||
@Override public boolean expectedHasMoreItems() { return true; }
|
||||
}
|
||||
|
||||
static class AgeRestrictedTabsShorts extends DefaultListExtractorTest<ChannelTabExtractor> {
|
||||
private static ChannelTabExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
static void setUp() throws IOException, ExtractionException {
|
||||
YoutubeTestsUtils.ensureStateless();
|
||||
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "ageRestrictedTabsShorts"));
|
||||
final ChannelExtractor channelExtractor = YouTube.getChannelExtractor(
|
||||
"https://www.youtube.com/channel/UCbfnHqxXs_K3kvaH-WlNlig");
|
||||
channelExtractor.fetchPage();
|
||||
|
||||
// the shorts tab is the second one
|
||||
extractor = YouTube.getChannelTabExtractor(channelExtractor.getTabs().get(1));
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testName() throws Exception {
|
||||
assertEquals(ChannelTabs.VIDEOS, videosTabExtractor.getName());
|
||||
assertEquals(ChannelTabs.SHORTS, shortsTabExtractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("UCbfnHqxXs_K3kvaH-WlNlig", videosTabExtractor.getId());
|
||||
assertEquals("UCbfnHqxXs_K3kvaH-WlNlig", shortsTabExtractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://www.youtube.com/channel/UCbfnHqxXs_K3kvaH-WlNlig/videos",
|
||||
videosTabExtractor.getUrl());
|
||||
assertEquals("https://www.youtube.com/channel/UCbfnHqxXs_K3kvaH-WlNlig/shorts",
|
||||
shortsTabExtractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testOriginalUrl() throws Exception {
|
||||
assertEquals("https://www.youtube.com/channel/UCbfnHqxXs_K3kvaH-WlNlig/videos",
|
||||
videosTabExtractor.getOriginalUrl());
|
||||
assertEquals("https://www.youtube.com/channel/UCbfnHqxXs_K3kvaH-WlNlig/shorts",
|
||||
shortsTabExtractor.getOriginalUrl());
|
||||
}
|
||||
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
|
||||
@Override public StreamingService expectedService() throws Exception { return YouTube; }
|
||||
@Override public String expectedName() throws Exception { return ChannelTabs.SHORTS; }
|
||||
@Override public String expectedId() throws Exception { return "UCbfnHqxXs_K3kvaH-WlNlig"; }
|
||||
@Override public String expectedUrlContains() throws Exception { return "https://www.youtube.com/channel/UCbfnHqxXs_K3kvaH-WlNlig/shorts"; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "https://www.youtube.com/channel/UCbfnHqxXs_K3kvaH-WlNlig/shorts"; }
|
||||
@Override public boolean expectedHasMoreItems() { return false; }
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(videosTabExtractor);
|
||||
// No shorts on this channel, the channel tab playlist extractor should return no
|
||||
// streams
|
||||
assertTrue(shortsTabExtractor.getInitialPage().getItems().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(videosTabExtractor);
|
||||
// No shorts on this channel, the channel tab playlist extractor should return no
|
||||
// streams
|
||||
assertFalse(shortsTabExtractor.getInitialPage().hasNextPage());
|
||||
// this channel has no shorts, so an empty page is returned by the playlist extractor
|
||||
assertTrue(extractor.getInitialPage().getItems().isEmpty());
|
||||
assertTrue(extractor.getInitialPage().getErrors().isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,88 @@
|
|||
{
|
||||
"request": {
|
||||
"httpMethod": "GET",
|
||||
"url": "https://www.youtube.com/sw.js",
|
||||
"headers": {
|
||||
"Origin": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"Referer": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"Accept-Language": [
|
||||
"en-GB, en;q\u003d0.9"
|
||||
]
|
||||
},
|
||||
"localization": {
|
||||
"languageCode": "en",
|
||||
"countryCode": "GB"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"responseCode": 200,
|
||||
"responseMessage": "",
|
||||
"responseHeaders": {
|
||||
"access-control-allow-credentials": [
|
||||
"true"
|
||||
],
|
||||
"access-control-allow-origin": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"alt-svc": [
|
||||
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000"
|
||||
],
|
||||
"cache-control": [
|
||||
"private, max-age\u003d0"
|
||||
],
|
||||
"content-security-policy-report-only": [
|
||||
"require-trusted-types-for \u0027script\u0027;report-uri /cspreport"
|
||||
],
|
||||
"content-type": [
|
||||
"text/javascript; charset\u003dutf-8"
|
||||
],
|
||||
"cross-origin-opener-policy": [
|
||||
"same-origin; report-to\u003d\"youtube_main\""
|
||||
],
|
||||
"date": [
|
||||
"Sun, 06 Aug 2023 11:54:54 GMT"
|
||||
],
|
||||
"expires": [
|
||||
"Sun, 06 Aug 2023 11:54:54 GMT"
|
||||
],
|
||||
"origin-trial": [
|
||||
"AvC9UlR6RDk2crliDsFl66RWLnTbHrDbp+DiY6AYz/PNQ4G4tdUTjrHYr2sghbkhGQAVxb7jaPTHpEVBz0uzQwkAAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTcxOTUzMjc5OSwiaXNTdWJkb21haW4iOnRydWV9"
|
||||
],
|
||||
"p3p": [
|
||||
"CP\u003d\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl\u003den-GB for more info.\""
|
||||
],
|
||||
"permissions-policy": [
|
||||
"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-wow64\u003d*, ch-ua-form-factor\u003d*, ch-ua-platform\u003d*, ch-ua-platform-version\u003d*"
|
||||
],
|
||||
"report-to": [
|
||||
"{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}"
|
||||
],
|
||||
"server": [
|
||||
"ESF"
|
||||
],
|
||||
"set-cookie": [
|
||||
"YSC\u003dIXSPROQ-CH8; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 09-Nov-2020 11:54:54 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"CONSENT\u003dPENDING+942; expires\u003dTue, 05-Aug-2025 11:54:54 GMT; path\u003d/; domain\u003d.youtube.com; Secure"
|
||||
],
|
||||
"strict-transport-security": [
|
||||
"max-age\u003d31536000"
|
||||
],
|
||||
"x-content-type-options": [
|
||||
"nosniff"
|
||||
],
|
||||
"x-frame-options": [
|
||||
"SAMEORIGIN"
|
||||
],
|
||||
"x-xss-protection": [
|
||||
"0"
|
||||
]
|
||||
},
|
||||
"responseBody": "\n self.addEventListener(\u0027install\u0027, event \u003d\u003e {\n event.waitUntil(self.skipWaiting());\n });\n self.addEventListener(\u0027activate\u0027, event \u003d\u003e {\n event.waitUntil(\n self.clients.claim().then(() \u003d\u003e self.registration.unregister()));\n });\n ",
|
||||
"latestUrl": "https://www.youtube.com/sw.js"
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -41,10 +41,10 @@
|
|||
"same-origin; report-to\u003d\"youtube_main\""
|
||||
],
|
||||
"date": [
|
||||
"Mon, 17 Jul 2023 20:14:18 GMT"
|
||||
"Sun, 06 Aug 2023 11:55:07 GMT"
|
||||
],
|
||||
"expires": [
|
||||
"Mon, 17 Jul 2023 20:14:18 GMT"
|
||||
"Sun, 06 Aug 2023 11:55:07 GMT"
|
||||
],
|
||||
"origin-trial": [
|
||||
"AvC9UlR6RDk2crliDsFl66RWLnTbHrDbp+DiY6AYz/PNQ4G4tdUTjrHYr2sghbkhGQAVxb7jaPTHpEVBz0uzQwkAAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTcxOTUzMjc5OSwiaXNTdWJkb21haW4iOnRydWV9"
|
||||
|
@ -62,9 +62,9 @@
|
|||
"ESF"
|
||||
],
|
||||
"set-cookie": [
|
||||
"YSC\u003dgtpu5gh6Su4; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dTue, 20-Oct-2020 20:14:18 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"CONSENT\u003dPENDING+016; expires\u003dWed, 16-Jul-2025 20:14:18 GMT; path\u003d/; domain\u003d.youtube.com; Secure"
|
||||
"YSC\u003dqCdA3bmpLFQ; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 09-Nov-2020 11:55:07 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"CONSENT\u003dPENDING+717; expires\u003dTue, 05-Aug-2025 11:55:07 GMT; path\u003d/; domain\u003d.youtube.com; Secure"
|
||||
],
|
||||
"strict-transport-security": [
|
||||
"max-age\u003d31536000"
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue