Merge pull request #309 from Stypox/improve-stream-tests

Improve stream extractor tests & various fixes
This commit is contained in:
Tobias Groza 2020-10-25 18:49:53 +01:00 committed by GitHub
commit 14c0c37d64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 1396 additions and 1417 deletions

View File

@ -13,6 +13,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
import org.schabi.newpipe.extractor.services.media_ccc.extractors.infoItems.MediaCCCStreamInfoItemExtractor; import org.schabi.newpipe.extractor.services.media_ccc.extractors.infoItems.MediaCCCStreamInfoItemExtractor;
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCConferenceLinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
@ -71,8 +72,8 @@ public class MediaCCCConferenceExtractor extends ChannelExtractor {
@Nonnull @Nonnull
@Override @Override
public InfoItemsPage<StreamInfoItem> getInitialPage() { public InfoItemsPage<StreamInfoItem> getInitialPage() {
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
JsonArray events = conferenceData.getArray("events"); final JsonArray events = conferenceData.getArray("events");
for (int i = 0; i < events.size(); i++) { for (int i = 0; i < events.size(); i++) {
collector.commit(new MediaCCCStreamInfoItemExtractor(events.getObject(i))); collector.commit(new MediaCCCStreamInfoItemExtractor(events.getObject(i)));
} }
@ -87,10 +88,11 @@ public class MediaCCCConferenceExtractor extends ChannelExtractor {
@Override @Override
public void onFetchPage(@Nonnull final Downloader downloader) public void onFetchPage(@Nonnull final Downloader downloader)
throws IOException, ExtractionException { throws IOException, ExtractionException {
final String conferenceUrl = MediaCCCConferenceLinkHandlerFactory.CONFERENCE_API_ENDPOINT + getId();
try { try {
conferenceData = JsonParser.object().from(downloader.get(getUrl()).responseBody()); conferenceData = JsonParser.object().from(downloader.get(conferenceUrl).responseBody());
} catch (JsonParserException jpe) { } catch (JsonParserException jpe) {
throw new ExtractionException("Could not parse json returnd by url: " + getUrl()); throw new ExtractionException("Could not parse json returnd by url: " + conferenceUrl);
} }
} }
@ -99,10 +101,4 @@ public class MediaCCCConferenceExtractor extends ChannelExtractor {
public String getName() throws ParsingException { public String getName() throws ParsingException {
return conferenceData.getString("title"); return conferenceData.getString("title");
} }
@Nonnull
@Override
public String getOriginalUrl() {
return "https://media.ccc.de/c/" + conferenceData.getString("acronym");
}
} }

View File

@ -6,14 +6,17 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.TimeZone;
public final class MediaCCCParsingHelper { public final class MediaCCCParsingHelper {
private MediaCCCParsingHelper() { } private MediaCCCParsingHelper() { }
public static Calendar parseDateFrom(final String textualUploadDate) throws ParsingException { public static Calendar parseDateFrom(final String textualUploadDate) throws ParsingException {
Date date; final Date date;
try { try {
date = new SimpleDateFormat("yyyy-MM-dd").parse(textualUploadDate); final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
date = sdf.parse(textualUploadDate);
} catch (ParseException e) { } catch (ParseException e) {
throw new ParsingException("Could not parse date: \"" + textualUploadDate + "\"", e); throw new ParsingException("Could not parse date: \"" + textualUploadDate + "\"", e);
} }

View File

@ -19,14 +19,18 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.stream.SubtitlesStream; import org.schabi.newpipe.extractor.stream.SubtitlesStream;
import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCConferenceLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCStreamLinkHandlerFactory;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class MediaCCCStreamExtractor extends StreamExtractor { public class MediaCCCStreamExtractor extends StreamExtractor {
private JsonObject data; private JsonObject data;
@ -93,7 +97,7 @@ public class MediaCCCStreamExtractor extends StreamExtractor {
@Nonnull @Nonnull
@Override @Override
public String getUploaderUrl() { public String getUploaderUrl() {
return data.getString("conference_url"); return MediaCCCConferenceLinkHandlerFactory.CONFERENCE_PATH + getUploaderName();
} }
@Nonnull @Nonnull
@ -111,25 +115,25 @@ public class MediaCCCStreamExtractor extends StreamExtractor {
@Nonnull @Nonnull
@Override @Override
public String getSubChannelUrl() throws ParsingException { public String getSubChannelUrl() {
return ""; return "";
} }
@Nonnull @Nonnull
@Override @Override
public String getSubChannelName() throws ParsingException { public String getSubChannelName() {
return ""; return "";
} }
@Nonnull @Nonnull
@Override @Override
public String getSubChannelAvatarUrl() throws ParsingException { public String getSubChannelAvatarUrl() {
return ""; return "";
} }
@Nonnull @Nonnull
@Override @Override
public String getDashMpdUrl() throws ParsingException { public String getDashMpdUrl() {
return ""; return "";
} }
@ -194,7 +198,7 @@ public class MediaCCCStreamExtractor extends StreamExtractor {
@Override @Override
public List<VideoStream> getVideoOnlyStreams() { public List<VideoStream> getVideoOnlyStreams() {
return null; return Collections.emptyList();
} }
@Nonnull @Nonnull
@ -214,9 +218,10 @@ public class MediaCCCStreamExtractor extends StreamExtractor {
return StreamType.VIDEO_STREAM; return StreamType.VIDEO_STREAM;
} }
@Nullable
@Override @Override
public StreamInfoItemsCollector getRelatedStreams() { public StreamInfoItemsCollector getRelatedStreams() {
return new StreamInfoItemsCollector(getServiceId()); return null;
} }
@Override @Override
@ -227,14 +232,13 @@ public class MediaCCCStreamExtractor extends StreamExtractor {
@Override @Override
public void onFetchPage(@Nonnull final Downloader downloader) public void onFetchPage(@Nonnull final Downloader downloader)
throws IOException, ExtractionException { throws IOException, ExtractionException {
final String videoUrl = MediaCCCStreamLinkHandlerFactory.VIDEO_API_ENDPOINT + getId();
try { try {
data = JsonParser.object().from( data = JsonParser.object().from(downloader.get(videoUrl).responseBody());
downloader.get(getLinkHandler().getUrl()).responseBody());
conferenceData = JsonParser.object() conferenceData = JsonParser.object()
.from(downloader.get(getUploaderUrl()).responseBody()); .from(downloader.get(data.getString("conference_url")).responseBody());
} catch (JsonParserException jpe) { } catch (JsonParserException jpe) {
throw new ExtractionException("Could not parse json returned by url: " throw new ExtractionException("Could not parse json returned by url: " + videoUrl, jpe);
+ getLinkHandler().getUrl(), jpe);
} }
} }
@ -250,21 +254,25 @@ public class MediaCCCStreamExtractor extends StreamExtractor {
return data.getString("frontend_link"); return data.getString("frontend_link");
} }
@Nonnull
@Override @Override
public String getHost() { public String getHost() {
return ""; return "";
} }
@Nonnull
@Override @Override
public String getPrivacy() { public String getPrivacy() {
return ""; return "";
} }
@Nonnull
@Override @Override
public String getCategory() { public String getCategory() {
return ""; return "";
} }
@Nonnull
@Override @Override
public String getLicence() { public String getLicence() {
return ""; return "";
@ -278,7 +286,7 @@ public class MediaCCCStreamExtractor extends StreamExtractor {
@Nonnull @Nonnull
@Override @Override
public List<String> getTags() { public List<String> getTags() {
return new ArrayList<>(); return Arrays.asList(data.getArray("tags").toArray(new String[0]));
} }
@Nonnull @Nonnull

View File

@ -7,30 +7,26 @@ import org.schabi.newpipe.extractor.utils.Parser;
import java.util.List; import java.util.List;
public class MediaCCCConferenceLinkHandlerFactory extends ListLinkHandlerFactory { public class MediaCCCConferenceLinkHandlerFactory extends ListLinkHandlerFactory {
public static final String CONFERENCE_API_ENDPOINT = "https://api.media.ccc.de/public/conferences/";
public static final String CONFERENCE_PATH = "https://media.ccc.de/c/";
private static final String ID_PATTERN = "(?:(?:(?:api\\.)?media\\.ccc\\.de/public/conferences/)|(?:media\\.ccc\\.de/[bc]/))([^/?&#]*)";
@Override @Override
public String getUrl(final String id, final List<String> contentFilter, final String sortFilter) public String getUrl(final String id,
throws ParsingException { final List<String> contentFilter,
return "https://media.ccc.de/public/conferences/" + id; final String sortFilter) throws ParsingException {
return CONFERENCE_PATH + id;
} }
@Override @Override
public String getId(final String url) throws ParsingException { public String getId(final String url) throws ParsingException {
if (url.startsWith("https://media.ccc.de/public/conferences/") return Parser.matchGroup1(ID_PATTERN, url);
|| url.startsWith("https://api.media.ccc.de/public/conferences/")) {
return url.replaceFirst("https://(api\\.)?media\\.ccc\\.de/public/conferences/", "");
} else if (url.startsWith("https://media.ccc.de/c/")) {
return Parser.matchGroup1("https://media.ccc.de/c/([^?#]*)", url);
} else if (url.startsWith("https://media.ccc.de/b/")) {
return Parser.matchGroup1("https://media.ccc.de/b/([^?#]*)", url);
}
throw new ParsingException("Could not get id from url: " + url);
} }
@Override @Override
public boolean onAcceptUrl(final String url) { public boolean onAcceptUrl(final String url) {
try { try {
getId(url); return getId(url) != null;
return true;
} catch (ParsingException e) { } catch (ParsingException e) {
return false; return false;
} }

View File

@ -2,54 +2,27 @@ package org.schabi.newpipe.extractor.services.media_ccc.linkHandler;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory; import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.extractor.utils.Parser;
import java.net.MalformedURLException;
import java.net.URL;
public class MediaCCCStreamLinkHandlerFactory extends LinkHandlerFactory { public class MediaCCCStreamLinkHandlerFactory extends LinkHandlerFactory {
public static final String VIDEO_API_ENDPOINT = "https://api.media.ccc.de/public/events/";
private static final String VIDEO_PATH = "https://media.ccc.de/v/";
private static final String ID_PATTERN = "(?:(?:(?:api\\.)?media\\.ccc\\.de/public/events/)|(?:media\\.ccc\\.de/v/))([^/?&#]*)";
@Override @Override
public String getId(final String urlString) throws ParsingException { public String getId(final String url) throws ParsingException {
if (urlString.startsWith("https://media.ccc.de/public/events/") return Parser.matchGroup1(ID_PATTERN, url);
&& !urlString.contains("?q=")) {
return urlString.substring(35); //remove /public/events part
}
if (urlString.startsWith("https://api.media.ccc.de/public/events/")
&& !urlString.contains("?q=")) {
return urlString.substring(39); //remove api/public/events part
}
URL url;
try {
url = Utils.stringToURL(urlString);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("The given URL is not valid");
}
String path = url.getPath();
// remove leading "/" of URL-path if URL-path is given
if (!path.isEmpty()) {
path = path.substring(1);
}
if (path.startsWith("v/")) {
return path.substring(2);
}
throw new ParsingException("Could not get id from url: " + url);
} }
@Override @Override
public String getUrl(final String id) throws ParsingException { public String getUrl(final String id) throws ParsingException {
return "https://media.ccc.de/public/events/" + id; return VIDEO_PATH + id;
} }
@Override @Override
public boolean onAcceptUrl(final String url) { public boolean onAcceptUrl(final String url) {
try { try {
getId(url); return getId(url) != null;
return true;
} catch (ParsingException e) { } catch (ParsingException e) {
return false; return false;
} }

View File

@ -13,6 +13,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper; import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.JsonUtils;
@ -20,6 +21,8 @@ import org.schabi.newpipe.extractor.utils.Utils;
import java.io.IOException; import java.io.IOException;
import javax.annotation.Nonnull;
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY;
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE;
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY;
@ -85,14 +88,16 @@ public class PeertubeAccountExtractor extends ChannelExtractor {
return ""; return "";
} }
@Nonnull
@Override @Override
public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException { public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException {
final String pageUrl = getUrl() + "/videos?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE; return getPage(new Page(
return getPage(new Page(pageUrl)); getUrl() + "/videos?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE));
} }
@Override @Override
public InfoItemsPage<StreamInfoItem> getPage(final Page page) throws IOException, ExtractionException { public InfoItemsPage<StreamInfoItem> getPage(final Page page)
throws IOException, ExtractionException {
if (page == null || isNullOrEmpty(page.getUrl())) { if (page == null || isNullOrEmpty(page.getUrl())) {
throw new IllegalArgumentException("Page doesn't contain an URL"); throw new IllegalArgumentException("Page doesn't contain an URL");
} }
@ -122,8 +127,16 @@ public class PeertubeAccountExtractor extends ChannelExtractor {
} }
@Override @Override
public void onFetchPage(final Downloader downloader) throws IOException, ExtractionException { public void onFetchPage(@Nonnull final Downloader downloader)
final Response response = downloader.get(getUrl()); throws IOException, ExtractionException {
String accountUrl = baseUrl + PeertubeChannelLinkHandlerFactory.API_ENDPOINT;
if (getId().contains("accounts/")) {
accountUrl += getId();
} else {
accountUrl += "accounts/" + getId();
}
final Response response = downloader.get(accountUrl);
if (response != null && response.responseBody() != null) { if (response != null && response.responseBody() != null) {
setInitialData(response.responseBody()); setInitialData(response.responseBody());
} else { } else {
@ -140,13 +153,9 @@ public class PeertubeAccountExtractor extends ChannelExtractor {
if (json == null) throw new ExtractionException("Unable to extract PeerTube account data"); if (json == null) throw new ExtractionException("Unable to extract PeerTube account data");
} }
@Nonnull
@Override @Override
public String getName() throws ParsingException { public String getName() throws ParsingException {
return JsonUtils.getString(json, "displayName"); return JsonUtils.getString(json, "displayName");
} }
@Override
public String getOriginalUrl() throws ParsingException {
return baseUrl + "/" + getId();
}
} }

View File

@ -13,6 +13,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper; import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.JsonUtils;
@ -20,6 +21,8 @@ import org.schabi.newpipe.extractor.utils.Utils;
import java.io.IOException; import java.io.IOException;
import javax.annotation.Nonnull;
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY;
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE;
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY;
@ -92,10 +95,11 @@ public class PeertubeChannelExtractor extends ChannelExtractor {
return baseUrl + value; return baseUrl + value;
} }
@Nonnull
@Override @Override
public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException { public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException {
final String pageUrl = getUrl() + "/videos?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE; return getPage(new Page(
return getPage(new Page(pageUrl)); getUrl() + "/videos?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE));
} }
@Override @Override
@ -130,7 +134,8 @@ public class PeertubeChannelExtractor extends ChannelExtractor {
@Override @Override
public void onFetchPage(final Downloader downloader) throws IOException, ExtractionException { public void onFetchPage(final Downloader downloader) throws IOException, ExtractionException {
final Response response = downloader.get(getUrl()); final Response response = downloader.get(
baseUrl + PeertubeChannelLinkHandlerFactory.API_ENDPOINT + getId());
if (response != null && response.responseBody() != null) { if (response != null && response.responseBody() != null) {
setInitialData(response.responseBody()); setInitialData(response.responseBody());
} else { } else {
@ -147,13 +152,9 @@ public class PeertubeChannelExtractor extends ChannelExtractor {
if (json == null) throw new ExtractionException("Unable to extract PeerTube channel data"); if (json == null) throw new ExtractionException("Unable to extract PeerTube channel data");
} }
@Nonnull
@Override @Override
public String getName() throws ParsingException { public String getName() throws ParsingException {
return JsonUtils.getString(json, "displayName"); return JsonUtils.getString(json, "displayName");
} }
@Override
public String getOriginalUrl() throws ParsingException {
return baseUrl + "/" + getId();
}
} }

View File

@ -17,6 +17,7 @@ import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
import org.schabi.newpipe.extractor.localization.DateWrapper; import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper; import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeSearchQueryHandlerFactory; import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeSearchQueryHandlerFactory;
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeStreamLinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.extractor.stream.Stream; import org.schabi.newpipe.extractor.stream.Stream;
@ -37,11 +38,12 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class PeertubeStreamExtractor extends StreamExtractor { public class PeertubeStreamExtractor extends StreamExtractor {
private final String baseUrl; private final String baseUrl;
private JsonObject json; private JsonObject json;
private List<SubtitlesStream> subtitles = new ArrayList<>(); private final List<SubtitlesStream> subtitles = new ArrayList<>();
public PeertubeStreamExtractor(final StreamingService service, final LinkHandler linkHandler) throws ParsingException { public PeertubeStreamExtractor(final StreamingService service, final LinkHandler linkHandler) throws ParsingException {
super(service, linkHandler); super(service, linkHandler);
@ -64,11 +66,13 @@ public class PeertubeStreamExtractor extends StreamExtractor {
return new DateWrapper(PeertubeParsingHelper.parseDateFrom(textualUploadDate)); return new DateWrapper(PeertubeParsingHelper.parseDateFrom(textualUploadDate));
} }
@Nonnull
@Override @Override
public String getThumbnailUrl() throws ParsingException { public String getThumbnailUrl() throws ParsingException {
return baseUrl + JsonUtils.getString(json, "previewPath"); return baseUrl + JsonUtils.getString(json, "previewPath");
} }
@Nonnull
@Override @Override
public Description getDescription() throws ParsingException { public Description getDescription() throws ParsingException {
String text; String text;
@ -81,7 +85,9 @@ public class PeertubeStreamExtractor extends StreamExtractor {
//if description is shortened, get full description //if description is shortened, get full description
final Downloader dl = NewPipe.getDownloader(); final Downloader dl = NewPipe.getDownloader();
try { try {
final Response response = dl.get(getUrl() + "/description"); final Response response = dl.get(baseUrl
+ PeertubeStreamLinkHandlerFactory.VIDEO_API_ENDPOINT
+ getId() + "/description");
final JsonObject jsonObject = JsonParser.object().from(response.responseBody()); final JsonObject jsonObject = JsonParser.object().from(response.responseBody());
text = JsonUtils.getString(jsonObject, "description"); text = JsonUtils.getString(jsonObject, "description");
} catch (ReCaptchaException | IOException | JsonParserException e) { } catch (ReCaptchaException | IOException | JsonParserException e) {
@ -107,9 +113,16 @@ public class PeertubeStreamExtractor extends StreamExtractor {
} }
@Override @Override
public long getTimeStamp() { public long getTimeStamp() throws ParsingException {
//TODO fetch timestamp from url if present; final long timestamp =
return 0; getTimestampSeconds("((#|&|\\?)start=\\d{0,3}h?\\d{0,3}m?\\d{1,3}s?)");
if (timestamp == -2) {
// regex for timestamp was not found
return 0;
} else {
return timestamp;
}
} }
@Override @Override
@ -127,6 +140,7 @@ public class PeertubeStreamExtractor extends StreamExtractor {
return json.getLong("dislikes"); return json.getLong("dislikes");
} }
@Nonnull
@Override @Override
public String getUploaderUrl() throws ParsingException { public String getUploaderUrl() throws ParsingException {
final String name = JsonUtils.getString(json, "account.name"); final String name = JsonUtils.getString(json, "account.name");
@ -134,11 +148,13 @@ public class PeertubeStreamExtractor extends StreamExtractor {
return getService().getChannelLHFactory().fromId("accounts/" + name + "@" + host, baseUrl).getUrl(); return getService().getChannelLHFactory().fromId("accounts/" + name + "@" + host, baseUrl).getUrl();
} }
@Nonnull
@Override @Override
public String getUploaderName() throws ParsingException { public String getUploaderName() throws ParsingException {
return JsonUtils.getString(json, "account.displayName"); return JsonUtils.getString(json, "account.displayName");
} }
@Nonnull
@Override @Override
public String getUploaderAvatarUrl() { public String getUploaderAvatarUrl() {
String value; String value;
@ -150,6 +166,7 @@ public class PeertubeStreamExtractor extends StreamExtractor {
return baseUrl + value; return baseUrl + value;
} }
@Nonnull
@Override @Override
public String getSubChannelUrl() throws ParsingException { public String getSubChannelUrl() throws ParsingException {
return JsonUtils.getString(json, "channel.url"); return JsonUtils.getString(json, "channel.url");
@ -173,11 +190,13 @@ public class PeertubeStreamExtractor extends StreamExtractor {
return baseUrl + value; return baseUrl + value;
} }
@Nonnull
@Override @Override
public String getDashMpdUrl() { public String getDashMpdUrl() {
return ""; return "";
} }
@Nonnull
@Override @Override
public String getHlsUrl() { public String getHlsUrl() {
return ""; return "";
@ -185,7 +204,7 @@ public class PeertubeStreamExtractor extends StreamExtractor {
@Override @Override
public List<AudioStream> getAudioStreams() { public List<AudioStream> getAudioStreams() {
return null; return Collections.emptyList();
} }
@Override @Override
@ -220,11 +239,13 @@ public class PeertubeStreamExtractor extends StreamExtractor {
return Collections.emptyList(); return Collections.emptyList();
} }
@Nonnull
@Override @Override
public List<SubtitlesStream> getSubtitlesDefault() { public List<SubtitlesStream> getSubtitlesDefault() {
return subtitles; return subtitles;
} }
@Nonnull
@Override @Override
public List<SubtitlesStream> getSubtitles(final MediaFormat format) { public List<SubtitlesStream> getSubtitles(final MediaFormat format) {
final List<SubtitlesStream> filteredSubs = new ArrayList<>(); final List<SubtitlesStream> filteredSubs = new ArrayList<>();
@ -241,21 +262,27 @@ public class PeertubeStreamExtractor extends StreamExtractor {
return StreamType.VIDEO_STREAM; return StreamType.VIDEO_STREAM;
} }
@Nullable
@Override @Override
public StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException { public StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException {
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
final List<String> tags = getTags(); final List<String> tags = getTags();
final String apiUrl; final String apiUrl;
if (!tags.isEmpty()) { if (tags.isEmpty()) {
apiUrl = getRelatedStreamsUrl(tags);
} else {
apiUrl = getUploaderUrl() + "/videos?start=0&count=8"; apiUrl = getUploaderUrl() + "/videos?start=0&count=8";
} else {
apiUrl = getRelatedStreamsUrl(tags);
}
if (Utils.isBlank(apiUrl)) {
return null;
} else {
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
getStreamsFromApi(collector, apiUrl);
return collector;
} }
if (!Utils.isBlank(apiUrl)) getStreamsFromApi(collector, apiUrl);
return collector;
} }
@Nonnull
@Override @Override
public List<String> getTags() { public List<String> getTags() {
try { try {
@ -327,7 +354,7 @@ public class PeertubeStreamExtractor extends StreamExtractor {
@Override @Override
public void onFetchPage(final Downloader downloader) throws IOException, ExtractionException { public void onFetchPage(final Downloader downloader) throws IOException, ExtractionException {
final Response response = downloader.get(getUrl()); final Response response = downloader.get(baseUrl + PeertubeStreamLinkHandlerFactory.VIDEO_API_ENDPOINT + getId());
if (response != null && response.responseBody() != null) { if (response != null && response.responseBody() != null) {
setInitialData(response.responseBody()); setInitialData(response.responseBody());
} else { } else {
@ -343,14 +370,18 @@ public class PeertubeStreamExtractor extends StreamExtractor {
} catch (JsonParserException e) { } catch (JsonParserException e) {
throw new ExtractionException("Unable to extract PeerTube stream data", e); throw new ExtractionException("Unable to extract PeerTube stream data", e);
} }
if (json == null) throw new ExtractionException("Unable to extract PeerTube stream data"); if (json == null) {
throw new ExtractionException("Unable to extract PeerTube stream data");
}
PeertubeParsingHelper.validate(json); PeertubeParsingHelper.validate(json);
} }
private void loadSubtitles() { private void loadSubtitles() {
if (subtitles.isEmpty()) { if (subtitles.isEmpty()) {
try { try {
final Response response = getDownloader().get(getUrl() + "/captions"); final Response response = getDownloader().get(baseUrl
+ PeertubeStreamLinkHandlerFactory.VIDEO_API_ENDPOINT
+ getId() + "/captions");
final JsonObject captionsJson = JsonParser.object().from(response.responseBody()); final JsonObject captionsJson = JsonParser.object().from(response.responseBody());
final JsonArray captions = JsonUtils.getArray(captionsJson, "data"); final JsonArray captions = JsonUtils.getArray(captionsJson, "data");
for (final Object c : captions) { for (final Object c : captions) {
@ -370,31 +401,31 @@ public class PeertubeStreamExtractor extends StreamExtractor {
} }
} }
@Nonnull
@Override @Override
public String getName() throws ParsingException { public String getName() throws ParsingException {
return JsonUtils.getString(json, "name"); return JsonUtils.getString(json, "name");
} }
@Override @Nonnull
public String getOriginalUrl() throws ParsingException {
return baseUrl + "/videos/watch/" + getId();
}
@Override @Override
public String getHost() throws ParsingException { public String getHost() throws ParsingException {
return JsonUtils.getString(json, "account.host"); return JsonUtils.getString(json, "account.host");
} }
@Nonnull
@Override @Override
public String getPrivacy() throws ParsingException { public String getPrivacy() throws ParsingException {
return JsonUtils.getString(json, "privacy.label"); return JsonUtils.getString(json, "privacy.label");
} }
@Nonnull
@Override @Override
public String getCategory() throws ParsingException { public String getCategory() throws ParsingException {
return JsonUtils.getString(json, "category.label"); return JsonUtils.getString(json, "category.label");
} }
@Nonnull
@Override @Override
public String getLicence() throws ParsingException { public String getLicence() throws ParsingException {
return JsonUtils.getString(json, "licence.label"); return JsonUtils.getString(json, "licence.label");

View File

@ -27,8 +27,7 @@ public class PeertubeStreamInfoItemExtractor implements StreamInfoItemExtractor
@Override @Override
public String getThumbnailUrl() throws ParsingException { public String getThumbnailUrl() throws ParsingException {
final String value = JsonUtils.getString(item, "thumbnailPath"); return baseUrl + JsonUtils.getString(item, "thumbnailPath");
return baseUrl + value;
} }
@Override @Override
@ -51,7 +50,8 @@ public class PeertubeStreamInfoItemExtractor implements StreamInfoItemExtractor
final String name = JsonUtils.getString(item, "account.name"); final String name = JsonUtils.getString(item, "account.name");
final String host = JsonUtils.getString(item, "account.host"); final String host = JsonUtils.getString(item, "account.host");
return ServiceList.PeerTube.getChannelLHFactory().fromId("accounts/" + name + "@" + host, baseUrl).getUrl(); return ServiceList.PeerTube.getChannelLHFactory()
.fromId("accounts/" + name + "@" + host, baseUrl).getUrl();
} }
@Override @Override

View File

@ -11,7 +11,7 @@ public class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFactory {
private static final PeertubeChannelLinkHandlerFactory instance = new PeertubeChannelLinkHandlerFactory(); private static final PeertubeChannelLinkHandlerFactory instance = new PeertubeChannelLinkHandlerFactory();
private static final String ID_PATTERN = "(accounts|video-channels)/([^/?&#]*)"; private static final String ID_PATTERN = "(accounts|video-channels)/([^/?&#]*)";
private static final String API_ENDPOINT = "/api/v1/"; public static final String API_ENDPOINT = "/api/v1/";
public static PeertubeChannelLinkHandlerFactory getInstance() { public static PeertubeChannelLinkHandlerFactory getInstance() {
return instance; return instance;
@ -24,19 +24,17 @@ public class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFactory {
@Override @Override
public String getUrl(String id, List<String> contentFilters, String searchFilter) throws ParsingException { public String getUrl(String id, List<String> contentFilters, String searchFilter) throws ParsingException {
String baseUrl = ServiceList.PeerTube.getBaseUrl(); return getUrl(id, contentFilters, searchFilter, ServiceList.PeerTube.getBaseUrl());
return getUrl(id, contentFilters, searchFilter, baseUrl);
} }
@Override @Override
public String getUrl(String id, List<String> contentFilter, String sortFilter, String baseUrl) public String getUrl(String id, List<String> contentFilter, String sortFilter, String baseUrl)
throws ParsingException { throws ParsingException {
if (id.matches(ID_PATTERN)) { if (id.matches(ID_PATTERN)) {
return baseUrl + API_ENDPOINT + id; return baseUrl + "/" + id;
} else { } else {
// This is needed for compatibility with older versions were we didn't support video channels yet // This is needed for compatibility with older versions were we didn't support video channels yet
return baseUrl + API_ENDPOINT + "accounts/" + id; return baseUrl + "/accounts/" + id;
} }
} }

View File

@ -10,7 +10,8 @@ public class PeertubeStreamLinkHandlerFactory extends LinkHandlerFactory {
private static final PeertubeStreamLinkHandlerFactory instance = new PeertubeStreamLinkHandlerFactory(); private static final PeertubeStreamLinkHandlerFactory instance = new PeertubeStreamLinkHandlerFactory();
private static final String ID_PATTERN = "/videos/(watch/|embed/)?([^/?&#]*)"; private static final String ID_PATTERN = "/videos/(watch/|embed/)?([^/?&#]*)";
private static final String VIDEO_ENDPOINT = "/api/v1/videos/"; public static final String VIDEO_API_ENDPOINT = "/api/v1/videos/";
private static final String VIDEO_PATH = "/videos/watch/";
private PeertubeStreamLinkHandlerFactory() { private PeertubeStreamLinkHandlerFactory() {
} }
@ -21,13 +22,12 @@ public class PeertubeStreamLinkHandlerFactory extends LinkHandlerFactory {
@Override @Override
public String getUrl(String id) { public String getUrl(String id) {
String baseUrl = ServiceList.PeerTube.getBaseUrl(); return getUrl(id, ServiceList.PeerTube.getBaseUrl());
return getUrl(id, baseUrl);
} }
@Override @Override
public String getUrl(String id, String baseUrl) { public String getUrl(String id, String baseUrl) {
return baseUrl + VIDEO_ENDPOINT + id; return baseUrl + VIDEO_PATH + id;
} }
@Override @Override

View File

@ -33,6 +33,7 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static org.schabi.newpipe.extractor.utils.JsonUtils.EMPTY_STRING; import static org.schabi.newpipe.extractor.utils.JsonUtils.EMPTY_STRING;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
@ -68,8 +69,10 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
@Nonnull @Nonnull
@Override @Override
public String getTextualUploadDate() throws ParsingException { public String getTextualUploadDate() {
return track.getString("created_at").replace("T"," ").replace("Z", ""); return track.getString("created_at")
.replace("T"," ")
.replace("Z", "");
} }
@Nonnull @Nonnull
@ -85,10 +88,10 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
if (artworkUrl.isEmpty()) { if (artworkUrl.isEmpty()) {
artworkUrl = track.getObject("user").getString("avatar_url", EMPTY_STRING); artworkUrl = track.getObject("user").getString("avatar_url", EMPTY_STRING);
} }
String artworkUrlBetterResolution = artworkUrl.replace("large.jpg", "crop.jpg"); return artworkUrl.replace("large.jpg", "crop.jpg");
return artworkUrlBetterResolution;
} }
@Nonnull
@Override @Override
public Description getDescription() { public Description getDescription() {
return new Description(track.getString("description"), Description.PLAIN_TEXT); return new Description(track.getString("description"), Description.PLAIN_TEXT);
@ -144,19 +147,19 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
@Nonnull @Nonnull
@Override @Override
public String getSubChannelUrl() throws ParsingException { public String getSubChannelUrl() {
return ""; return "";
} }
@Nonnull @Nonnull
@Override @Override
public String getSubChannelName() throws ParsingException { public String getSubChannelName() {
return ""; return "";
} }
@Nonnull @Nonnull
@Override @Override
public String getSubChannelAvatarUrl() throws ParsingException { public String getSubChannelAvatarUrl() {
return ""; return "";
} }
@ -168,14 +171,14 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
@Nonnull @Nonnull
@Override @Override
public String getHlsUrl() throws ParsingException { public String getHlsUrl() {
return ""; return "";
} }
@Override @Override
public List<AudioStream> getAudioStreams() throws IOException, ExtractionException { public List<AudioStream> getAudioStreams() throws IOException, ExtractionException {
List<AudioStream> audioStreams = new ArrayList<>(); List<AudioStream> audioStreams = new ArrayList<>();
Downloader dl = NewPipe.getDownloader(); final Downloader dl = NewPipe.getDownloader();
// Streams can be streamable and downloadable - or explicitly not. // Streams can be streamable and downloadable - or explicitly not.
// For playing the track, it is only necessary to have a streamable track. // For playing the track, it is only necessary to have a streamable track.
@ -183,12 +186,12 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
if (!track.getBoolean("streamable")) return audioStreams; if (!track.getBoolean("streamable")) return audioStreams;
try { try {
JsonArray transcodings = track.getObject("media").getArray("transcodings"); final JsonArray transcodings = track.getObject("media").getArray("transcodings");
// get information about what stream formats are available // get information about what stream formats are available
for (Object transcoding : transcodings) { for (Object transcoding : transcodings) {
JsonObject t = (JsonObject) transcoding; final JsonObject t = (JsonObject) transcoding;
String url = t.getString("url"); String url = t.getString("url");
if (!isNullOrEmpty(url)) { if (!isNullOrEmpty(url)) {
@ -200,7 +203,7 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
// This url points to the endpoint which generates a unique and short living url to the stream. // This url points to the endpoint which generates a unique and short living url to the stream.
// TODO: move this to a separate method to generate valid urls when needed (e.g. resuming a paused stream) // TODO: move this to a separate method to generate valid urls when needed (e.g. resuming a paused stream)
url += "?client_id=" + SoundcloudParsingHelper.clientId(); url += "?client_id=" + SoundcloudParsingHelper.clientId();
String res = dl.get(url).responseBody(); final String res = dl.get(url).responseBody();
try { try {
JsonObject mp3UrlObject = JsonParser.object().from(res); JsonObject mp3UrlObject = JsonParser.object().from(res);
@ -234,24 +237,24 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
} }
@Override @Override
public List<VideoStream> getVideoStreams() throws IOException, ExtractionException { public List<VideoStream> getVideoStreams() {
return null; return Collections.emptyList();
} }
@Override @Override
public List<VideoStream> getVideoOnlyStreams() throws IOException, ExtractionException { public List<VideoStream> getVideoOnlyStreams() {
return null;
}
@Override
@Nonnull
public List<SubtitlesStream> getSubtitlesDefault() throws IOException, ExtractionException {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
@Nonnull @Nonnull
public List<SubtitlesStream> getSubtitles(MediaFormat format) throws IOException, ExtractionException { public List<SubtitlesStream> getSubtitlesDefault() {
return Collections.emptyList();
}
@Override
@Nonnull
public List<SubtitlesStream> getSubtitles(MediaFormat format) {
return Collections.emptyList(); return Collections.emptyList();
} }
@ -260,12 +263,13 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
return StreamType.AUDIO_STREAM; return StreamType.AUDIO_STREAM;
} }
@Nullable
@Override @Override
public StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException { public StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException {
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
String apiUrl = "https://api-v2.soundcloud.com/tracks/" + urlEncode(getId()) + "/related" final String apiUrl = "https://api-v2.soundcloud.com/tracks/" + urlEncode(getId())
+ "?client_id=" + urlEncode(SoundcloudParsingHelper.clientId()); + "/related?client_id=" + urlEncode(SoundcloudParsingHelper.clientId());
SoundcloudParsingHelper.getStreamsFromApi(collector, apiUrl); SoundcloudParsingHelper.getStreamsFromApi(collector, apiUrl);
return collector; return collector;
@ -276,40 +280,44 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
return null; return null;
} }
@Nonnull
@Override @Override
public String getHost() throws ParsingException { public String getHost() {
return "";
}
@Nonnull
@Override
public String getPrivacy() {
return "";
}
@Nonnull
@Override
public String getCategory() {
return "";
}
@Nonnull
@Override
public String getLicence() {
return ""; return "";
} }
@Override @Override
public String getPrivacy() throws ParsingException { public Locale getLanguageInfo() {
return "";
}
@Override
public String getCategory() throws ParsingException {
return "";
}
@Override
public String getLicence() throws ParsingException {
return "";
}
@Override
public Locale getLanguageInfo() throws ParsingException {
return null; return null;
} }
@Nonnull @Nonnull
@Override @Override
public List<String> getTags() throws ParsingException { public List<String> getTags() {
return new ArrayList<>(); return Collections.emptyList();
} }
@Nonnull @Nonnull
@Override @Override
public String getSupportInfo() throws ParsingException { public String getSupportInfo() {
return ""; return "";
} }
} }

View File

@ -183,9 +183,11 @@ public class YoutubeParsingHelper {
} }
public static Calendar parseDateFrom(String textualUploadDate) throws ParsingException { public static Calendar parseDateFrom(String textualUploadDate) throws ParsingException {
Date date; final Date date;
try { try {
date = new SimpleDateFormat("yyyy-MM-dd").parse(textualUploadDate); final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
date = sdf.parse(textualUploadDate);
} catch (ParseException e) { } catch (ParseException e) {
throw new ParsingException("Could not parse date: \"" + textualUploadDate + "\"", e); throw new ParsingException("Could not parse date: \"" + textualUploadDate + "\"", e);
} }

View File

@ -253,7 +253,15 @@ public class YoutubeStreamExtractor extends StreamExtractor {
*/ */
@Override @Override
public long getTimeStamp() throws ParsingException { public long getTimeStamp() throws ParsingException {
return getTimestampSeconds("((#|&|\\?)(t|start)=\\d{0,3}h?\\d{0,3}m?\\d{1,3}s?)"); final long timestamp =
getTimestampSeconds("((#|&|\\?)t=\\d{0,3}h?\\d{0,3}m?\\d{1,3}s?)");
if (timestamp == -2) {
// regex for timestamp was not found
return 0;
} else {
return timestamp;
}
} }
@Override @Override
@ -568,11 +576,14 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} }
} }
@Nullable
@Override @Override
public StreamInfoItemsCollector getRelatedStreams() throws ExtractionException { public StreamInfoItemsCollector getRelatedStreams() throws ExtractionException {
assertPageFetched(); assertPageFetched();
if (getAgeLimit() != NO_AGE_LIMIT) return null; if (getAgeLimit() != NO_AGE_LIMIT) {
return null;
}
try { try {
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
@ -604,10 +615,11 @@ public class YoutubeStreamExtractor extends StreamExtractor {
@Override @Override
public String getErrorMessage() { public String getErrorMessage() {
try { try {
return getTextFromObject(initialAjaxJson.getObject(2).getObject("playerResponse").getObject("playabilityStatus") return getTextFromObject(initialAjaxJson.getObject(2).getObject("playerResponse")
.getObject("errorScreen").getObject("playerErrorMessageRenderer").getObject("reason")); .getObject("playabilityStatus").getObject("errorScreen")
} catch (ParsingException e) { .getObject("playerErrorMessageRenderer").getObject("reason"));
return null; } catch (ParsingException | NullPointerException e) {
return null; // no error message
} }
} }
@ -999,12 +1011,18 @@ public class YoutubeStreamExtractor extends StreamExtractor {
@Override @Override
public List<Frameset> getFrames() throws ExtractionException { public List<Frameset> getFrames() throws ExtractionException {
try { try {
JsonObject jo = initialAjaxJson.getObject(2).getObject("player"); final JsonObject storyboards = playerResponse.getObject("storyboards");
final String resp = jo.getObject("args").getString("player_response"); final JsonObject storyboardsRenderer;
jo = JsonParser.object().from(resp); if (storyboards.has("playerLiveStoryboardSpecRenderer")) {
final String[] spec = jo.getObject("storyboards").getObject("playerStoryboardSpecRenderer").getString("spec").split("\\|"); storyboardsRenderer = storyboards.getObject("playerLiveStoryboardSpecRenderer");
} else {
storyboardsRenderer = storyboards.getObject("playerStoryboardSpecRenderer");
}
final String[] spec = storyboardsRenderer.getString("spec").split("\\|");
final String url = spec[0]; final String url = spec[0];
final ArrayList<Frameset> result = new ArrayList<>(spec.length - 1); final ArrayList<Frameset> result = new ArrayList<>(spec.length - 1);
for (int i = 1; i < spec.length; ++i) { for (int i = 1; i < spec.length; ++i) {
final String[] parts = spec[i].split("#"); final String[] parts = spec[i].split("#");
if (parts.length != 8) { if (parts.length != 8) {
@ -1074,7 +1092,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
@Nonnull @Nonnull
@Override @Override
public List<String> getTags() { public List<String> getTags() {
return new ArrayList<>(); return Collections.emptyList();
} }
@Nonnull @Nonnull

View File

@ -321,6 +321,7 @@ public abstract class StreamExtractor extends Extractor {
* @throws IOException * @throws IOException
* @throws ExtractionException * @throws ExtractionException
*/ */
@Nullable
public abstract StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException; public abstract StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException;
/** /**

View File

@ -1,12 +1,19 @@
package org.schabi.newpipe.extractor; package org.schabi.newpipe.extractor;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class ExtractorAsserts { public class ExtractorAsserts {
public static void assertEmptyErrors(String message, List<Throwable> errors) { public static void assertEmptyErrors(String message, List<Throwable> errors) {
@ -56,4 +63,22 @@ public class ExtractorAsserts {
assertTrue(message, stringToCheck.isEmpty()); assertTrue(message, stringToCheck.isEmpty());
} }
} }
public static void assertAtLeast(long expected, long actual) {
assertTrue(actual + " is not at least " + expected, actual >= expected);
}
// this assumes that sorting a and b in-place is not an issue, so it's only intended for tests
public static void assertEqualsOrderIndependent(List<String> expected, List<String> actual) {
if (expected == null) {
assertNull(actual);
return;
} else {
assertNotNull(actual);
}
Collections.sort(expected);
Collections.sort(actual);
assertEquals(expected, actual);
}
} }

View File

@ -0,0 +1,35 @@
package org.schabi.newpipe.extractor.services;
public interface BaseStreamExtractorTest extends BaseExtractorTest {
void testStreamType() throws Exception;
void testUploaderName() throws Exception;
void testUploaderUrl() throws Exception;
void testUploaderAvatarUrl() throws Exception;
void testSubChannelName() throws Exception;
void testSubChannelUrl() throws Exception;
void testSubChannelAvatarUrl() throws Exception;
void testThumbnailUrl() throws Exception;
void testDescription() throws Exception;
void testLength() throws Exception;
void testTimestamp() throws Exception;
void testViewCount() throws Exception;
void testUploadDate() throws Exception;
void testTextualUploadDate() throws Exception;
void testLikeCount() throws Exception;
void testDislikeCount() throws Exception;
void testRelatedStreams() throws Exception;
void testAgeLimit() throws Exception;
void testErrorMessage() throws Exception;
void testAudioStreams() throws Exception;
void testVideoStreams() throws Exception;
void testSubtitles() throws Exception;
void testGetDashMpdUrl() throws Exception;
void testFrames() throws Exception;
void testHost() throws Exception;
void testPrivacy() throws Exception;
void testCategory() throws Exception;
void testLicence() throws Exception;
void testLanguageInfo() throws Exception;
void testTags() throws Exception;
void testSupportInfo() throws Exception;
}

View File

@ -0,0 +1,385 @@
package org.schabi.newpipe.extractor.services;
import org.junit.Test;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.extractor.stream.Frameset;
import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
import org.schabi.newpipe.extractor.stream.VideoStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import javax.annotation.Nullable;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertAtLeast;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertEqualsOrderIndependent;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsValidUrl;
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestListOfItems;
/**
* Test for {@link StreamExtractor}
*/
public abstract class DefaultStreamExtractorTest extends DefaultExtractorTest<StreamExtractor>
implements BaseStreamExtractorTest {
public abstract StreamType expectedStreamType();
public abstract String expectedUploaderName();
public abstract String expectedUploaderUrl();
public String expectedSubChannelName() { return ""; } // default: there is no subchannel
public String expectedSubChannelUrl() { return ""; } // default: there is no subchannel
public abstract List<String> expectedDescriptionContains(); // e.g. for full links
public abstract long expectedLength();
public long expectedTimestamp() { return 0; } // default: there is no timestamp
public abstract long expectedViewCountAtLeast();
@Nullable public abstract String expectedUploadDate(); // format: "yyyy-MM-dd HH:mm:ss.SSS"
@Nullable public abstract String expectedTextualUploadDate();
public abstract long expectedLikeCountAtLeast(); // return -1 if ratings are disabled
public abstract long expectedDislikeCountAtLeast(); // return -1 if ratings are disabled
public boolean expectedHasRelatedStreams() { return true; } // default: there are related videos
public int expectedAgeLimit() { return StreamExtractor.NO_AGE_LIMIT; } // default: no limit
@Nullable public String expectedErrorMessage() { return null; } // default: no error message
public boolean expectedHasVideoStreams() { return true; } // default: there are video streams
public boolean expectedHasAudioStreams() { return true; } // default: there are audio streams
public boolean expectedHasSubtitles() { return true; } // default: there are subtitles streams
@Nullable public String expectedDashMpdUrlContains() { return null; } // default: no dash mpd
public boolean expectedHasFrames() { return true; } // default: there are frames
public String expectedHost() { return ""; } // default: no host for centralized platforms
public String expectedPrivacy() { return ""; } // default: no privacy policy available
public String expectedCategory() { return ""; } // default: no category
public String expectedLicence() { return ""; } // default: no licence
public Locale expectedLanguageInfo() { return null; } // default: no language info available
public List<String> expectedTags() { return Collections.emptyList(); } // default: no tags
public String expectedSupportInfo() { return ""; } // default: no support info available
@Test
@Override
public void testStreamType() throws Exception {
assertEquals(expectedStreamType(), extractor().getStreamType());
}
@Test
@Override
public void testUploaderName() throws Exception {
assertEquals(expectedUploaderName(), extractor().getUploaderName());
}
@Test
@Override
public void testUploaderUrl() throws Exception {
final String uploaderUrl = extractor().getUploaderUrl();
assertIsSecureUrl(uploaderUrl);
assertEquals(expectedUploaderUrl(), uploaderUrl);
}
@Test
@Override
public void testUploaderAvatarUrl() throws Exception {
assertIsSecureUrl(extractor().getUploaderAvatarUrl());
}
@Test
@Override
public void testSubChannelName() throws Exception {
assertEquals(expectedSubChannelName(), extractor().getSubChannelName());
}
@Test
@Override
public void testSubChannelUrl() throws Exception {
final String subChannelUrl = extractor().getSubChannelUrl();
assertEquals(expectedSubChannelUrl(), subChannelUrl);
if (!expectedSubChannelUrl().isEmpty()) {
// this stream has a subchannel
assertIsSecureUrl(subChannelUrl);
}
}
@Test
@Override
public void testSubChannelAvatarUrl() throws Exception {
if (expectedSubChannelName().isEmpty() && expectedSubChannelUrl().isEmpty()) {
// this stream has no subchannel
assertEquals("", extractor().getSubChannelAvatarUrl());
} else {
// this stream has a subchannel
assertIsSecureUrl(extractor().getSubChannelAvatarUrl());
}
}
@Test
@Override
public void testThumbnailUrl() throws Exception {
assertIsSecureUrl(extractor().getThumbnailUrl());
}
@Test
@Override
public void testDescription() throws Exception {
final Description description = extractor().getDescription();
assertNotNull(description);
assertFalse("description is empty", description.getContent().isEmpty());
for (final String s : expectedDescriptionContains()) {
assertThat(description.getContent(), containsString(s));
}
}
@Test
@Override
public void testLength() throws Exception {
assertEquals(expectedLength(), extractor().getLength());
}
@Test
@Override
public void testTimestamp() throws Exception {
assertEquals(expectedTimestamp(), extractor().getTimeStamp());
}
@Test
@Override
public void testViewCount() throws Exception {
assertAtLeast(expectedViewCountAtLeast(), extractor().getViewCount());
}
@Test
@Override
public void testUploadDate() throws Exception {
final DateWrapper dateWrapper = extractor().getUploadDate();
if (expectedUploadDate() == null) {
assertNull(dateWrapper);
} else {
assertNotNull(dateWrapper);
final Calendar expectedDate = Calendar.getInstance();
final Calendar actualDate = dateWrapper.date();
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
expectedDate.setTime(sdf.parse(expectedUploadDate()));
assertEquals(expectedDate, actualDate);
}
}
@Test
@Override
public void testTextualUploadDate() throws Exception {
assertEquals(expectedTextualUploadDate(), extractor().getTextualUploadDate());
}
@Test
@Override
public void testLikeCount() throws Exception {
if (expectedLikeCountAtLeast() == -1) {
assertEquals(-1, extractor().getLikeCount());
} else {
assertAtLeast(expectedLikeCountAtLeast(), extractor().getLikeCount());
}
}
@Test
@Override
public void testDislikeCount() throws Exception {
if (expectedDislikeCountAtLeast() == -1) {
assertEquals(-1, extractor().getDislikeCount());
} else {
assertAtLeast(expectedDislikeCountAtLeast(), extractor().getDislikeCount());
}
}
@Test
@Override
public void testRelatedStreams() throws Exception {
final StreamInfoItemsCollector relatedStreams = extractor().getRelatedStreams();
if (expectedHasRelatedStreams()) {
defaultTestListOfItems(extractor().getService(), relatedStreams.getItems(),
relatedStreams.getErrors());
} else {
assertNull(relatedStreams);
}
}
@Test
@Override
public void testAgeLimit() throws Exception {
assertEquals(expectedAgeLimit(), extractor().getAgeLimit());
}
@Test
@Override
public void testErrorMessage() throws Exception {
assertEquals(expectedErrorMessage(), extractor().getErrorMessage());
}
@Test
@Override
public void testVideoStreams() throws Exception {
final List<VideoStream> videoStreams = extractor().getVideoStreams();
final List<VideoStream> videoOnlyStreams = extractor().getVideoOnlyStreams();
assertNotNull(videoStreams);
assertNotNull(videoOnlyStreams);
videoStreams.addAll(videoOnlyStreams);
if (expectedHasVideoStreams()) {
assertFalse(videoStreams.isEmpty());
for (final VideoStream stream : videoStreams) {
assertIsSecureUrl(stream.getUrl());
assertFalse(stream.getResolution().isEmpty());
final int formatId = stream.getFormatId();
// see MediaFormat: video stream formats range from 0 to 0x100
assertTrue("format id does not fit a video stream: " + formatId,
0 <= formatId && formatId < 0x100);
}
} else {
assertTrue(videoStreams.isEmpty());
}
}
@Test
@Override
public void testAudioStreams() throws Exception {
final List<AudioStream> audioStreams = extractor().getAudioStreams();
assertNotNull(audioStreams);
if (expectedHasAudioStreams()) {
assertFalse(audioStreams.isEmpty());
for (final AudioStream stream : audioStreams) {
assertIsSecureUrl(stream.getUrl());
final int formatId = stream.getFormatId();
// see MediaFormat: video stream formats range from 0x100 to 0x1000
assertTrue("format id does not fit an audio stream: " + formatId,
0x100 <= formatId && formatId < 0x1000);
}
} else {
assertTrue(audioStreams.isEmpty());
}
}
@Test
@Override
public void testSubtitles() throws Exception {
final List<SubtitlesStream> subtitles = extractor().getSubtitlesDefault();
assertNotNull(subtitles);
if (expectedHasSubtitles()) {
assertFalse(subtitles.isEmpty());
for (final SubtitlesStream stream : subtitles) {
assertIsSecureUrl(stream.getUrl());
final int formatId = stream.getFormatId();
// see MediaFormat: video stream formats range from 0x1000 to 0x10000
assertTrue("format id does not fit a subtitles stream: " + formatId,
0x1000 <= formatId && formatId < 0x10000);
}
} else {
assertTrue(subtitles.isEmpty());
final MediaFormat[] formats = {MediaFormat.VTT, MediaFormat.TTML, MediaFormat.SRT,
MediaFormat.TRANSCRIPT1, MediaFormat.TRANSCRIPT2, MediaFormat.TRANSCRIPT3};
for (final MediaFormat format : formats) {
final List<SubtitlesStream> formatSubtitles = extractor().getSubtitles(format);
assertNotNull(formatSubtitles);
assertTrue(formatSubtitles.isEmpty());
}
}
}
@Override
public void testGetDashMpdUrl() throws Exception {
final String dashMpdUrl = extractor().getDashMpdUrl();
if (expectedDashMpdUrlContains() == null) {
assertNotNull(dashMpdUrl);
assertTrue(dashMpdUrl.isEmpty());
} else {
assertIsSecureUrl(dashMpdUrl);
assertThat(extractor().getDashMpdUrl(), containsString(expectedDashMpdUrlContains()));
}
}
@Test
@Override
public void testFrames() throws Exception {
final List<Frameset> frames = extractor().getFrames();
assertNotNull(frames);
if (expectedHasFrames()) {
assertFalse(frames.isEmpty());
for (final Frameset f : frames) {
for (final String url : f.getUrls()) {
assertIsValidUrl(url);
assertIsSecureUrl(url);
}
}
} else {
assertTrue(frames.isEmpty());
}
}
@Test
@Override
public void testHost() throws Exception {
assertEquals(expectedHost(), extractor().getHost());
}
@Test
@Override
public void testPrivacy() throws Exception {
assertEquals(expectedPrivacy(), extractor().getPrivacy());
}
@Test
@Override
public void testCategory() throws Exception {
assertEquals(expectedCategory(), extractor().getCategory());
}
@Test
@Override
public void testLicence() throws Exception {
assertEquals(expectedLicence(), extractor().getLicence());
}
@Test
@Override
public void testLanguageInfo() throws Exception {
assertEquals(expectedLanguageInfo(), extractor().getLanguageInfo());
}
@Test
@Override
public void testTags() throws Exception {
assertEqualsOrderIndependent(expectedTags(), extractor().getTags());
}
@Test
@Override
public void testSupportInfo() throws Exception {
assertEquals(expectedSupportInfo(), extractor().getSupportInfo());
}
}

View File

@ -10,7 +10,6 @@ import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem; import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import java.util.Calendar;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -42,7 +41,7 @@ public final class DefaultTests {
StreamInfoItem streamInfoItem = (StreamInfoItem) item; StreamInfoItem streamInfoItem = (StreamInfoItem) item;
assertNotEmpty("Uploader name not set: " + item, streamInfoItem.getUploaderName()); assertNotEmpty("Uploader name not set: " + item, streamInfoItem.getUploaderName());
// assertNotEmpty("Uploader url not set: " + item, streamInfoItem.getUploaderUrl()); // assertNotEmpty("Uploader url not set: " + item, streamInfoItem.getUploaderUrl());
final String uploaderUrl = streamInfoItem.getUploaderUrl(); final String uploaderUrl = streamInfoItem.getUploaderUrl();
if (!isNullOrEmpty(uploaderUrl)) { if (!isNullOrEmpty(uploaderUrl)) {
assertIsSecureUrl(uploaderUrl); assertIsSecureUrl(uploaderUrl);
@ -54,7 +53,6 @@ public final class DefaultTests {
if (!isNullOrEmpty(streamInfoItem.getTextualUploadDate())) { if (!isNullOrEmpty(streamInfoItem.getTextualUploadDate())) {
final DateWrapper uploadDate = streamInfoItem.getUploadDate(); final DateWrapper uploadDate = streamInfoItem.getUploadDate();
assertNotNull("No parsed upload date", uploadDate); assertNotNull("No parsed upload date", uploadDate);
assertTrue("Upload date not in the past", uploadDate.date().before(Calendar.getInstance()));
} }
} else if (item instanceof ChannelInfoItem) { } else if (item instanceof ChannelInfoItem) {

View File

@ -31,7 +31,7 @@ public class MediaCCCConferenceExtractorTest {
@Test @Test
public void testGetUrl() throws Exception { public void testGetUrl() throws Exception {
assertEquals("https://media.ccc.de/public/conferences/froscon2017", extractor.getUrl()); assertEquals("https://media.ccc.de/c/froscon2017", extractor.getUrl());
} }
@Test @Test
@ -67,7 +67,7 @@ public class MediaCCCConferenceExtractorTest {
@Test @Test
public void testGetUrl() throws Exception { public void testGetUrl() throws Exception {
assertEquals("https://media.ccc.de/public/conferences/oscal19", extractor.getUrl()); assertEquals("https://media.ccc.de/c/oscal19", extractor.getUrl());
} }
@Test @Test

View File

@ -0,0 +1,42 @@
package org.schabi.newpipe.extractor.services.media_ccc;
import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCConferenceLinkHandlerFactory;
import static org.junit.Assert.assertEquals;
public class MediaCCCConferenceLinkHandlerFactoryTest {
private static MediaCCCConferenceLinkHandlerFactory linkHandler;
@BeforeClass
public static void setUp() {
linkHandler = new MediaCCCConferenceLinkHandlerFactory();
NewPipe.init(DownloaderTestImpl.getInstance());
}
@Test
public void getId() throws ParsingException {
assertEquals("jh20",
linkHandler.fromUrl("https://media.ccc.de/c/jh20#278").getId());
assertEquals("jh20",
linkHandler.fromUrl("https://media.ccc.de/b/jh20?a=b").getId());
assertEquals("jh20",
linkHandler.fromUrl("https://api.media.ccc.de/public/conferences/jh20&a=b&b=c").getId());
}
@Test
public void getUrl() throws ParsingException {
assertEquals("https://media.ccc.de/c/jh20",
linkHandler.fromUrl("https://media.ccc.de/c/jh20#278").getUrl());
assertEquals("https://media.ccc.de/c/jh20",
linkHandler.fromUrl("https://media.ccc.de/b/jh20?a=b").getUrl());
assertEquals("https://media.ccc.de/c/jh20",
linkHandler.fromUrl("https://api.media.ccc.de/public/conferences/jh20&a=b&b=c").getUrl());
assertEquals("https://media.ccc.de/c/jh20",
linkHandler.fromId("jh20").getUrl());
}
}

View File

@ -1,204 +1,152 @@
package org.schabi.newpipe.extractor.services.media_ccc; package org.schabi.newpipe.extractor.services.media_ccc;
import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl; import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest;
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCStreamExtractor; import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCStreamExtractor;
import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.extractor.stream.StreamType;
import java.text.ParseException; import java.util.Arrays;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List; import java.util.List;
import static java.util.Objects.requireNonNull; import javax.annotation.Nullable;
import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertEquals;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.MediaCCC; import static org.schabi.newpipe.extractor.ServiceList.MediaCCC;
/** /**
* Test {@link MediaCCCStreamExtractor} * Test {@link MediaCCCStreamExtractor}
*/ */
public class MediaCCCStreamExtractorTest { public class MediaCCCStreamExtractorTest {
public static class Gpn18Tmux { private static final String BASE_URL = "https://media.ccc.de/v/";
private static MediaCCCStreamExtractor extractor;
public static class Gpn18Tmux extends DefaultStreamExtractorTest {
private static final String ID = "gpn18-105-tmux-warum-ein-schwarzes-fenster-am-bildschirm-reicht";
private static final String URL = BASE_URL + ID;
private static StreamExtractor extractor;
@BeforeClass @BeforeClass
public static void setUpClass() throws Exception { public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
extractor = MediaCCC.getStreamExtractor(URL);
extractor = (MediaCCCStreamExtractor) MediaCCC.getStreamExtractor("https://media.ccc.de/v/gpn18-105-tmux-warum-ein-schwarzes-fenster-am-bildschirm-reicht");
extractor.fetchPage(); extractor.fetchPage();
} }
@Test @Override public StreamExtractor extractor() { return extractor; }
public void testServiceId() throws Exception { @Override public StreamingService expectedService() { return MediaCCC; }
assertEquals(2, extractor.getServiceId()); @Override public String expectedName() { return "tmux - Warum ein schwarzes Fenster am Bildschirm reicht"; }
} @Override public String expectedId() { return ID; }
@Override public String expectedUrlContains() { return URL; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Test @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
public void testName() throws Exception { @Override public String expectedUploaderName() { return "gpn18"; }
assertEquals("tmux - Warum ein schwarzes Fenster am Bildschirm reicht", extractor.getName()); @Override public String expectedUploaderUrl() { return "https://media.ccc.de/c/gpn18"; }
} @Override public List<String> expectedDescriptionContains() { return Arrays.asList("SSH-Sessions", "\"Terminal Multiplexer\""); }
@Override public long expectedLength() { return 3097; }
@Override public long expectedViewCountAtLeast() { return 2380; }
@Nullable @Override public String expectedUploadDate() { return "2018-05-11 00:00:00.000"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2018-05-11T02:00:00.000+02:00"; }
@Override public long expectedLikeCountAtLeast() { return -1; }
@Override public long expectedDislikeCountAtLeast() { return -1; }
@Override public boolean expectedHasRelatedStreams() { return false; }
@Override public boolean expectedHasSubtitles() { return false; }
@Override public boolean expectedHasFrames() { return false; }
@Override public List<String> expectedTags() { return Arrays.asList("gpn18", "105"); }
@Override
@Test @Test
public void testId() throws Exception { public void testThumbnailUrl() throws Exception {
assertEquals("gpn18-105-tmux-warum-ein-schwarzes-fenster-am-bildschirm-reicht", extractor.getId()); super.testThumbnailUrl();
}
@Test
public void testUrl() throws Exception {
assertIsSecureUrl(extractor.getUrl());
assertEquals("https://media.ccc.de/public/events/gpn18-105-tmux-warum-ein-schwarzes-fenster-am-bildschirm-reicht", extractor.getUrl());
}
@Test
public void testOriginalUrl() throws Exception {
assertIsSecureUrl(extractor.getOriginalUrl());
assertEquals("https://media.ccc.de/v/gpn18-105-tmux-warum-ein-schwarzes-fenster-am-bildschirm-reicht", extractor.getOriginalUrl());
}
@Test
public void testThumbnail() throws Exception {
assertIsSecureUrl(extractor.getThumbnailUrl());
assertEquals("https://static.media.ccc.de/media/events/gpn/gpn18/105-hd.jpg", extractor.getThumbnailUrl()); assertEquals("https://static.media.ccc.de/media/events/gpn/gpn18/105-hd.jpg", extractor.getThumbnailUrl());
} }
@Test @Override
public void testUploaderName() throws Exception {
assertEquals("gpn18", extractor.getUploaderName());
}
@Test
public void testUploaderUrl() throws Exception {
assertIsSecureUrl(extractor.getUploaderUrl());
assertEquals("https://media.ccc.de/public/conferences/gpn18", extractor.getUploaderUrl());
}
@Test @Test
public void testUploaderAvatarUrl() throws Exception { public void testUploaderAvatarUrl() throws Exception {
assertIsSecureUrl(extractor.getUploaderAvatarUrl()); super.testUploaderAvatarUrl();
assertEquals("https://static.media.ccc.de/media/events/gpn/gpn18/logo.png", extractor.getUploaderAvatarUrl()); assertEquals("https://static.media.ccc.de/media/events/gpn/gpn18/logo.png", extractor.getUploaderAvatarUrl());
} }
@Override
@Test @Test
public void testVideoStreams() throws Exception { public void testVideoStreams() throws Exception {
List<VideoStream> videoStreamList = extractor.getVideoStreams(); super.testVideoStreams();
assertEquals(4, videoStreamList.size()); assertEquals(4, extractor.getVideoStreams().size());
for (VideoStream stream : videoStreamList) {
assertIsSecureUrl(stream.getUrl());
}
} }
@Override
@Test @Test
public void testAudioStreams() throws Exception { public void testAudioStreams() throws Exception {
List<AudioStream> audioStreamList = extractor.getAudioStreams(); super.testAudioStreams();
assertEquals(2, audioStreamList.size()); assertEquals(2, extractor.getAudioStreams().size());
for (AudioStream stream : audioStreamList) {
assertIsSecureUrl(stream.getUrl());
}
}
@Test
public void testGetTextualUploadDate() throws ParsingException {
Assert.assertEquals("2018-05-11T02:00:00.000+02:00", extractor.getTextualUploadDate());
}
@Test
public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2018-05-11"));
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
} }
} }
public static class _36c3PrivacyMessaging { public static class _36c3PrivacyMessaging extends DefaultStreamExtractorTest {
private static MediaCCCStreamExtractor extractor; private static final String ID = "36c3-10565-what_s_left_for_private_messaging";
private static final String URL = BASE_URL + ID;
private static StreamExtractor extractor;
@BeforeClass @BeforeClass
public static void setUpClass() throws Exception { public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (MediaCCCStreamExtractor) MediaCCC.getStreamExtractor("https://media.ccc.de/v/36c3-10565-what_s_left_for_private_messaging"); extractor = MediaCCC.getStreamExtractor(URL);
extractor.fetchPage(); extractor.fetchPage();
} }
@Test @Override public StreamExtractor extractor() { return extractor; }
public void testName() throws Exception { @Override public StreamingService expectedService() { return MediaCCC; }
assertEquals("What's left for private messaging?", extractor.getName()); @Override public String expectedName() { return "What's left for private messaging?"; }
} @Override public String expectedId() { return ID; }
@Override public String expectedUrlContains() { return URL; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Test @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
public void testId() throws Exception { @Override public String expectedUploaderName() { return "36c3"; }
assertEquals("36c3-10565-what_s_left_for_private_messaging", extractor.getId()); @Override public String expectedUploaderUrl() { return "https://media.ccc.de/c/36c3"; }
} @Override public List<String> expectedDescriptionContains() { return Arrays.asList("WhatsApp", "Signal"); }
@Override public long expectedLength() { return 3603; }
@Override public long expectedViewCountAtLeast() { return 2380; }
@Nullable @Override public String expectedUploadDate() { return "2020-01-11 00:00:00.000"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2020-01-11T01:00:00.000+01:00"; }
@Override public long expectedLikeCountAtLeast() { return -1; }
@Override public long expectedDislikeCountAtLeast() { return -1; }
@Override public boolean expectedHasRelatedStreams() { return false; }
@Override public boolean expectedHasSubtitles() { return false; }
@Override public boolean expectedHasFrames() { return false; }
@Override public List<String> expectedTags() { return Arrays.asList("36c3", "10565", "2019", "Security", "Main"); }
@Override
@Test @Test
public void testUrl() throws Exception { public void testThumbnailUrl() throws Exception {
assertIsSecureUrl(extractor.getUrl()); super.testThumbnailUrl();
assertEquals("https://media.ccc.de/public/events/36c3-10565-what_s_left_for_private_messaging", extractor.getUrl());
}
@Test
public void testOriginalUrl() throws Exception {
assertIsSecureUrl(extractor.getOriginalUrl());
assertEquals("https://media.ccc.de/v/36c3-10565-what_s_left_for_private_messaging", extractor.getOriginalUrl());
}
@Test
public void testThumbnail() throws Exception {
assertIsSecureUrl(extractor.getThumbnailUrl());
assertEquals("https://static.media.ccc.de/media/congress/2019/10565-hd.jpg", extractor.getThumbnailUrl()); assertEquals("https://static.media.ccc.de/media/congress/2019/10565-hd.jpg", extractor.getThumbnailUrl());
} }
@Test @Override
public void testUploaderName() throws Exception {
assertEquals("36c3", extractor.getUploaderName());
}
@Test
public void testUploaderUrl() throws Exception {
assertIsSecureUrl(extractor.getUploaderUrl());
assertEquals("https://media.ccc.de/public/conferences/36c3", extractor.getUploaderUrl());
}
@Test @Test
public void testUploaderAvatarUrl() throws Exception { public void testUploaderAvatarUrl() throws Exception {
assertIsSecureUrl(extractor.getUploaderAvatarUrl()); super.testUploaderAvatarUrl();
assertEquals("https://static.media.ccc.de/media/congress/2019/logo.png", extractor.getUploaderAvatarUrl()); assertEquals("https://static.media.ccc.de/media/congress/2019/logo.png", extractor.getUploaderAvatarUrl());
} }
@Override
@Test @Test
public void testVideoStreams() throws Exception { public void testVideoStreams() throws Exception {
List<VideoStream> videoStreamList = extractor.getVideoStreams(); super.testVideoStreams();
assertEquals(8, videoStreamList.size()); assertEquals(8, extractor.getVideoStreams().size());
for (VideoStream stream : videoStreamList) {
assertIsSecureUrl(stream.getUrl());
}
} }
@Override
@Test @Test
public void testAudioStreams() throws Exception { public void testAudioStreams() throws Exception {
List<AudioStream> audioStreamList = extractor.getAudioStreams(); super.testAudioStreams();
assertEquals(2, audioStreamList.size()); assertEquals(2, extractor.getAudioStreams().size());
for (AudioStream stream : audioStreamList) {
assertIsSecureUrl(stream.getUrl());
}
}
@Test
public void testGetTextualUploadDate() throws ParsingException {
Assert.assertEquals("2020-01-11T01:00:00.000+01:00", extractor.getTextualUploadDate());
}
@Test
public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2020-01-11"));
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
} }
} }
} }

View File

@ -0,0 +1,42 @@
package org.schabi.newpipe.extractor.services.media_ccc;
import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCStreamLinkHandlerFactory;
import static org.junit.Assert.assertEquals;
public class MediaCCCStreamLinkHandlerFactoryTest {
private static MediaCCCStreamLinkHandlerFactory linkHandler;
@BeforeClass
public static void setUp() {
linkHandler = new MediaCCCStreamLinkHandlerFactory();
NewPipe.init(DownloaderTestImpl.getInstance());
}
@Test
public void getId() throws ParsingException {
assertEquals("jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020",
linkHandler.fromUrl("https://media.ccc.de/v/jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020").getId());
assertEquals("jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020",
linkHandler.fromUrl("https://media.ccc.de/v/jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020?a=b").getId());
assertEquals("jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020",
linkHandler.fromUrl("https://media.ccc.de/v/jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020#3").getId());
assertEquals("jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020",
linkHandler.fromUrl("https://api.media.ccc.de/public/events/jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020&a=b").getId());
}
@Test
public void getUrl() throws ParsingException {
assertEquals("https://media.ccc.de/v/jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020",
linkHandler.fromUrl("https://media.ccc.de/v/jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020").getUrl());
assertEquals("https://media.ccc.de/v/jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020",
linkHandler.fromUrl("https://api.media.ccc.de/public/events/jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020?b=a&a=b").getUrl());
assertEquals("https://media.ccc.de/v/jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020",
linkHandler.fromId("jhremote20-3001-abschlusspraesentation_jugend_hackt_remote_2020").getUrl());
}
}

View File

@ -28,7 +28,7 @@ public class PeertubeAccountExtractorTest {
// setting instance might break test when running in parallel // setting instance might break test when running in parallel
PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host")); PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host"));
extractor = (PeertubeAccountExtractor) PeerTube extractor = (PeertubeAccountExtractor) PeerTube
.getChannelExtractor("https://peertube.mastodon.host/api/v1/accounts/kde"); .getChannelExtractor("https://peertube.mastodon.host/accounts/kde");
extractor.fetchPage(); extractor.fetchPage();
} }
@ -53,7 +53,7 @@ public class PeertubeAccountExtractorTest {
@Test @Test
public void testUrl() throws ParsingException { public void testUrl() throws ParsingException {
assertEquals("https://peertube.mastodon.host/api/v1/accounts/kde", extractor.getUrl()); assertEquals("https://peertube.mastodon.host/accounts/kde", extractor.getUrl());
} }
@Test @Test
@ -115,7 +115,7 @@ public class PeertubeAccountExtractorTest {
// setting instance might break test when running in parallel // setting instance might break test when running in parallel
PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host")); PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host"));
extractor = (PeertubeAccountExtractor) PeerTube extractor = (PeertubeAccountExtractor) PeerTube
.getChannelExtractor("https://peertube.mastodon.host/accounts/booteille"); .getChannelExtractor("https://peertube.mastodon.host/api/v1/accounts/booteille");
extractor.fetchPage(); extractor.fetchPage();
} }
@ -150,12 +150,12 @@ public class PeertubeAccountExtractorTest {
@Test @Test
public void testUrl() throws ParsingException { public void testUrl() throws ParsingException {
assertEquals("https://peertube.mastodon.host/api/v1/accounts/booteille", extractor.getUrl()); assertEquals("https://peertube.mastodon.host/accounts/booteille", extractor.getUrl());
} }
@Test @Test
public void testOriginalUrl() throws ParsingException { public void testOriginalUrl() throws ParsingException {
assertEquals("https://peertube.mastodon.host/accounts/booteille", extractor.getOriginalUrl()); assertEquals("https://peertube.mastodon.host/api/v1/accounts/booteille", extractor.getOriginalUrl());
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////

View File

@ -28,7 +28,7 @@ public class PeertubeChannelExtractorTest {
// setting instance might break test when running in parallel // setting instance might break test when running in parallel
PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host")); PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host"));
extractor = (PeertubeChannelExtractor) PeerTube extractor = (PeertubeChannelExtractor) PeerTube
.getChannelExtractor("https://peertube.mastodon.host/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa"); .getChannelExtractor("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa");
extractor.fetchPage(); extractor.fetchPage();
} }
@ -53,7 +53,7 @@ public class PeertubeChannelExtractorTest {
@Test @Test
public void testUrl() throws ParsingException { public void testUrl() throws ParsingException {
assertEquals("https://peertube.mastodon.host/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa", extractor.getUrl()); assertEquals("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa", extractor.getUrl());
} }
@Test @Test
@ -130,7 +130,7 @@ public class PeertubeChannelExtractorTest {
// setting instance might break test when running in parallel // setting instance might break test when running in parallel
PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host")); PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host"));
extractor = (PeertubeChannelExtractor) PeerTube extractor = (PeertubeChannelExtractor) PeerTube
.getChannelExtractor("https://peertube.mastodon.host/video-channels/35080089-79b6-45fc-96ac-37e4d46a4457"); .getChannelExtractor("https://peertube.mastodon.host/api/v1/video-channels/35080089-79b6-45fc-96ac-37e4d46a4457");
extractor.fetchPage(); extractor.fetchPage();
} }
@ -165,12 +165,12 @@ public class PeertubeChannelExtractorTest {
@Test @Test
public void testUrl() throws ParsingException { public void testUrl() throws ParsingException {
assertEquals("https://peertube.mastodon.host/api/v1/video-channels/35080089-79b6-45fc-96ac-37e4d46a4457", extractor.getUrl()); assertEquals("https://peertube.mastodon.host/video-channels/35080089-79b6-45fc-96ac-37e4d46a4457", extractor.getUrl());
} }
@Test @Test
public void testOriginalUrl() throws ParsingException { public void testOriginalUrl() throws ParsingException {
assertEquals("https://peertube.mastodon.host/video-channels/35080089-79b6-45fc-96ac-37e4d46a4457", extractor.getOriginalUrl()); assertEquals("https://peertube.mastodon.host/api/v1/video-channels/35080089-79b6-45fc-96ac-37e4d46a4457", extractor.getOriginalUrl());
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////

View File

@ -28,20 +28,36 @@ public class PeertubeChannelLinkHandlerFactoryTest {
@Test @Test
public void acceptUrlTest() throws ParsingException { public void acceptUrlTest() throws ParsingException {
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net")); assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net"));
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa")); assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/api/v1/accounts/kranti@videos.squat.net/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa"));
} }
@Test @Test
public void getIdFromUrl() throws ParsingException { public void getId() throws ParsingException {
assertEquals("accounts/kranti@videos.squat.net", linkHandler.fromUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net").getId()); assertEquals("accounts/kranti@videos.squat.net",
assertEquals("accounts/kranti@videos.squat.net", linkHandler.fromUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net/videos").getId()); linkHandler.fromUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net").getId());
assertEquals("video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa", linkHandler.fromUrl("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa/videos").getId()); assertEquals("accounts/kranti@videos.squat.net",
linkHandler.fromUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net/videos").getId());
assertEquals("video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa",
linkHandler.fromUrl("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa/videos").getId());
assertEquals("accounts/kranti@videos.squat.net",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/accounts/kranti@videos.squat.net").getId());
assertEquals("accounts/kranti@videos.squat.net",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/accounts/kranti@videos.squat.net/videos").getId());
assertEquals("video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa").getId());
} }
@Test @Test
public void getUrlFromId() throws ParsingException { public void getUrl() throws ParsingException {
assertEquals("https://peertube.mastodon.host/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa", linkHandler.fromId("video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa").getUrl()); assertEquals("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa",
assertEquals("https://peertube.mastodon.host/api/v1/accounts/kranti@videos.squat.net", linkHandler.fromId("accounts/kranti@videos.squat.net").getUrl()); linkHandler.fromId("video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa").getUrl());
assertEquals("https://peertube.mastodon.host/api/v1/accounts/kranti@videos.squat.net", linkHandler.fromId("kranti@videos.squat.net").getUrl()); assertEquals("https://peertube.mastodon.host/accounts/kranti@videos.squat.net",
linkHandler.fromId("accounts/kranti@videos.squat.net").getUrl());
assertEquals("https://peertube.mastodon.host/accounts/kranti@videos.squat.net",
linkHandler.fromId("kranti@videos.squat.net").getUrl());
assertEquals("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa").getUrl());
} }
} }

View File

@ -1,180 +0,0 @@
package org.schabi.newpipe.extractor.services.peertube;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeStreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.stream.StreamType;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import static java.util.Objects.requireNonNull;
import static org.junit.Assert.*;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
/**
* Test for {@link StreamExtractor}
*/
public class PeertubeStreamExtractorDefaultTest {
private static PeertubeStreamExtractor extractor;
private static final String expectedLargeDescription = "**[Want to help to translate this video?](https://weblate.framasoft.org/projects/what-is-peertube-video/)**\r\n\r\n**Take back the control of your videos! [#JoinPeertube](https://joinpeertube.org)**\r\n*A decentralized video hosting network, based on free/libre software!*\r\n\r\n**Animation Produced by:** [LILA](https://libreart.info) - [ZeMarmot Team](https://film.zemarmot.net)\r\n*Directed by* Aryeom\r\n*Assistant* Jehan\r\n**Licence**: [CC-By-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)\r\n\r\n**Sponsored by** [Framasoft](https://framasoft.org)\r\n\r\n**Music**: [Red Step Forward](http://play.dogmazic.net/song.php?song_id=52491) - CC-By Ken Bushima\r\n\r\n**Movie Clip**: [Caminades 3: Llamigos](http://www.caminandes.com/) CC-By Blender Institute\r\n\r\n**Video sources**: https://gitlab.gnome.org/Jehan/what-is-peertube/";
private static final String expectedSmallDescription = "https://www.kickstarter.com/projects/1587081065/nothing-to-hide-the-documentary";
@BeforeClass
public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());
// setting instance might break test when running in parallel
PeerTube.setInstance(new PeertubeInstance("https://framatube.org", "FramaTube"));
extractor = (PeertubeStreamExtractor) PeerTube.getStreamExtractor("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d");
extractor.fetchPage();
}
@Test
public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
instance.setTime(sdf.parse("2018-10-01T10:52:46.396Z"));
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
}
@Test
public void testGetInvalidTimeStamp() throws ParsingException {
assertTrue(extractor.getTimeStamp() + "",
extractor.getTimeStamp() <= 0);
}
@Test
public void testGetTitle() throws ParsingException {
assertEquals("What is PeerTube?", extractor.getName());
}
@Test
public void testGetLargeDescription() throws ParsingException {
assertEquals(expectedLargeDescription, extractor.getDescription().getContent());
}
@Test
public void testGetEmptyDescription() throws Exception {
PeertubeStreamExtractor extractorEmpty = (PeertubeStreamExtractor) PeerTube.getStreamExtractor("https://framatube.org/api/v1/videos/d5907aad-2252-4207-89ec-a4b687b9337d");
extractorEmpty.fetchPage();
assertEquals("", extractorEmpty.getDescription().getContent());
}
@Test
public void testGetSmallDescription() throws Exception {
PeerTube.setInstance(new PeertubeInstance("https://peertube.cpy.re", "PeerTube test server"));
PeertubeStreamExtractor extractorSmall = (PeertubeStreamExtractor) PeerTube.getStreamExtractor("https://peertube.cpy.re/videos/watch/d2a5ec78-5f85-4090-8ec5-dc1102e022ea");
extractorSmall.fetchPage();
assertEquals(expectedSmallDescription, extractorSmall.getDescription().getContent());
}
@Test
public void testGetUploaderName() throws ParsingException {
assertEquals("Framasoft", extractor.getUploaderName());
}
@Test
public void testGetUploaderUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderUrl());
assertEquals("https://framatube.org/api/v1/accounts/framasoft@framatube.org", extractor.getUploaderUrl());
}
@Test
public void testGetUploaderAvatarUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
}
@Test
public void testGetSubChannelName() throws ParsingException {
assertEquals("Les vidéos de Framasoft", extractor.getSubChannelName());
}
@Test
public void testGetSubChannelUrl() throws ParsingException {
assertIsSecureUrl(extractor.getSubChannelUrl());
assertEquals("https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8", extractor.getSubChannelUrl());
}
@Test
public void testGetSubChannelAvatarUrl() throws ParsingException {
assertIsSecureUrl(extractor.getSubChannelAvatarUrl());
}
@Test
public void testGetLength() throws ParsingException {
assertEquals(113, extractor.getLength());
}
@Test
public void testGetViewCount() throws ParsingException {
assertTrue(Long.toString(extractor.getViewCount()),
extractor.getViewCount() > 10);
}
@Test
public void testGetThumbnailUrl() throws ParsingException {
assertIsSecureUrl(extractor.getThumbnailUrl());
}
@Test
public void testGetVideoStreams() throws IOException, ExtractionException {
assertFalse(extractor.getVideoStreams().isEmpty());
}
@Test
public void testStreamType() throws ParsingException {
assertTrue(extractor.getStreamType() == StreamType.VIDEO_STREAM);
}
@Ignore
@Test
public void testGetRelatedVideos() throws ExtractionException, IOException {
StreamInfoItemsCollector relatedVideos = extractor.getRelatedStreams();
assertFalse(relatedVideos.getItems().isEmpty());
assertTrue(relatedVideos.getErrors().isEmpty());
}
@Test
public void testGetSubtitlesListDefault() throws IOException, ExtractionException {
assertFalse(extractor.getSubtitlesDefault().isEmpty());
}
@Test
public void testGetSubtitlesList() throws IOException, ExtractionException {
assertFalse(extractor.getSubtitlesDefault().isEmpty());
}
@Test
public void testGetAgeLimit() throws ExtractionException, IOException {
assertEquals(0, extractor.getAgeLimit());
PeertubeStreamExtractor ageLimit = (PeertubeStreamExtractor) PeerTube.getStreamExtractor("https://nocensoring.net/videos/embed/dbd8e5e1-c527-49b6-b70c-89101dbb9c08");
ageLimit.fetchPage();
assertEquals(18, ageLimit.getAgeLimit());
}
@Test
public void testGetSupportInformation() throws ExtractionException, IOException {
PeertubeStreamExtractor supportInfoExtractor = (PeertubeStreamExtractor) PeerTube.getStreamExtractor("https://framatube.org/videos/watch/ee408ec8-07cd-4e35-b884-fb681a4b9d37");
supportInfoExtractor.fetchPage();
assertEquals("https://utip.io/chatsceptique", supportInfoExtractor.getSupportInfo());
}
@Test
public void testGetLanguageInformation() throws ParsingException {
assertEquals(new Locale("en"), extractor.getLanguageInfo());
}
}

View File

@ -0,0 +1,172 @@
package org.schabi.newpipe.extractor.services.peertube;
import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest;
import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamType;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import javax.annotation.Nullable;
import static org.junit.Assert.assertEquals;
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
public class PeertubeStreamExtractorTest {
private static final String BASE_URL = "/videos/watch/";
public static class WhatIsPeertube extends DefaultStreamExtractorTest {
private static final String ID = "9c9de5e8-0a1e-484a-b099-e80766180a6d";
private static final String INSTANCE = "https://framatube.org";
private static final int TIMESTAMP_MINUTE = 1;
private static final int TIMESTAMP_SECOND = 21;
private static final String URL = INSTANCE + BASE_URL + ID + "?start=" + TIMESTAMP_MINUTE + "m" + TIMESTAMP_SECOND + "s";
private static StreamExtractor extractor;
@BeforeClass
public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());
// setting instance might break test when running in parallel (!)
PeerTube.setInstance(new PeertubeInstance(INSTANCE, "FramaTube"));
extractor = PeerTube.getStreamExtractor(URL);
extractor.fetchPage();
}
@Test
public void testGetLanguageInformation() throws ParsingException {
assertEquals(new Locale("en"), extractor.getLanguageInfo());
}
@Override public StreamExtractor extractor() { return extractor; }
@Override public StreamingService expectedService() { return PeerTube; }
@Override public String expectedName() { return "What is PeerTube?"; }
@Override public String expectedId() { return ID; }
@Override public String expectedUrlContains() { return INSTANCE + BASE_URL + ID; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
@Override public String expectedUploaderName() { return "Framasoft"; }
@Override public String expectedUploaderUrl() { return "https://framatube.org/accounts/framasoft@framatube.org"; }
@Override public String expectedSubChannelName() { return "Les vidéos de Framasoft"; }
@Override public String expectedSubChannelUrl() { return "https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8"; }
@Override public List<String> expectedDescriptionContains() { // CRLF line ending
return Arrays.asList("**[Want to help to translate this video?](https://weblate.framasoft.org/projects/what-is-peertube-video/)**\r\n"
+ "\r\n"
+ "**Take back the control of your videos! [#JoinPeertube](https://joinpeertube.org)**\r\n"
+ "*A decentralized video hosting network, based on free/libre software!*\r\n"
+ "\r\n"
+ "**Animation Produced by:** [LILA](https://libreart.info) - [ZeMarmot Team](https://film.zemarmot.net)\r\n"
+ "*Directed by* Aryeom\r\n"
+ "*Assistant* Jehan\r\n"
+ "**Licence**: [CC-By-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)\r\n"
+ "\r\n"
+ "**Sponsored by** [Framasoft](https://framasoft.org)\r\n"
+ "\r\n"
+ "**Music**: [Red Step Forward](http://play.dogmazic.net/song.php?song_id=52491) - CC-By Ken Bushima\r\n"
+ "\r\n"
+ "**Movie Clip**: [Caminades 3: Llamigos](http://www.caminandes.com/) CC-By Blender Institute\r\n"
+ "\r\n"
+ "**Video sources**: https://gitlab.gnome.org/Jehan/what-is-peertube/");
}
@Override public long expectedLength() { return 113; }
@Override public long expectedTimestamp() { return TIMESTAMP_MINUTE*60 + TIMESTAMP_SECOND; }
@Override public long expectedViewCountAtLeast() { return 38600; }
@Nullable @Override public String expectedUploadDate() { return "2018-10-01 10:52:46.396"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2018-10-01T10:52:46.396Z"; }
@Override public long expectedLikeCountAtLeast() { return 120; }
@Override public long expectedDislikeCountAtLeast() { return 0; }
@Override public boolean expectedHasAudioStreams() { return false; }
@Override public boolean expectedHasFrames() { return false; }
@Override public String expectedHost() { return "framatube.org"; }
@Override public String expectedPrivacy() { return "Public"; }
@Override public String expectedCategory() { return "Science & Technology"; }
@Override public String expectedLicence() { return "Attribution - Share Alike"; }
@Override public Locale expectedLanguageInfo() { return Locale.forLanguageTag("en"); }
@Override public List<String> expectedTags() { return Arrays.asList("framasoft", "peertube"); }
}
public static class AgeRestricted extends DefaultStreamExtractorTest {
private static final String ID = "dbd8e5e1-c527-49b6-b70c-89101dbb9c08";
private static final String INSTANCE = "https://nocensoring.net";
private static final String URL = INSTANCE + "/videos/embed/" + ID;
private static StreamExtractor extractor;
@BeforeClass
public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());;
// setting instance might break test when running in parallel (!)
PeerTube.setInstance(new PeertubeInstance(INSTANCE));
extractor = PeerTube.getStreamExtractor(URL);
extractor.fetchPage();
}
@Override public StreamExtractor extractor() { return extractor; }
@Override public StreamingService expectedService() { return PeerTube; }
@Override public String expectedName() { return "Covid-19 ? [Court-métrage]"; }
@Override public String expectedId() { return ID; }
@Override public String expectedUrlContains() { return INSTANCE + BASE_URL + ID; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
@Override public String expectedUploaderName() { return "Résilience humaine"; }
@Override public String expectedUploaderUrl() { return "https://nocensoring.net/accounts/gmt@nocensoring.net"; }
@Override public String expectedSubChannelName() { return "SYSTEM FAILURE Quel à-venir ?"; }
@Override public String expectedSubChannelUrl() { return "https://nocensoring.net/video-channels/systemfailure_quel"; }
@Override public List<String> expectedDescriptionContains() { // LF line ending
return Arrays.asList("2020, le monde est frappé par une pandémie, beaucoup d'humains sont confinés.",
"System Failure Quel à-venir ? - Covid-19 / 2020");
}
@Override public long expectedLength() { return 667; }
@Override public long expectedViewCountAtLeast() { return 138; }
@Nullable @Override public String expectedUploadDate() { return "2020-05-14 17:24:35.580"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2020-05-14T17:24:35.580Z"; }
@Override public long expectedLikeCountAtLeast() { return 1; }
@Override public long expectedDislikeCountAtLeast() { return 0; }
@Override public int expectedAgeLimit() { return 18; }
@Override public boolean expectedHasAudioStreams() { return false; }
@Override public boolean expectedHasSubtitles() { return false; }
@Override public boolean expectedHasFrames() { return false; }
@Override public String expectedHost() { return "nocensoring.net"; }
@Override public String expectedPrivacy() { return "Public"; }
@Override public String expectedCategory() { return "Art"; }
@Override public String expectedLicence() { return "Attribution"; }
@Override public List<String> expectedTags() { return Arrays.asList("Covid-19", "Gérôme-Mary trebor", "Horreur et beauté", "court-métrage", "nue artistique"); }
}
@BeforeClass
public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());
PeerTube.setInstance(new PeertubeInstance("https://peertube.cpy.re", "PeerTube test server"));
}
@Test
public void testGetEmptyDescription() throws Exception {
StreamExtractor extractorEmpty = PeerTube.getStreamExtractor("https://framatube.org/api/v1/videos/d5907aad-2252-4207-89ec-a4b687b9337d");
extractorEmpty.fetchPage();
assertEquals("", extractorEmpty.getDescription().getContent());
}
@Test
public void testGetSmallDescription() throws Exception {
StreamExtractor extractorSmall = PeerTube.getStreamExtractor("https://peertube.cpy.re/videos/watch/d2a5ec78-5f85-4090-8ec5-dc1102e022ea");
extractorSmall.fetchPage();
assertEquals("https://www.kickstarter.com/projects/1587081065/nothing-to-hide-the-documentary", extractorSmall.getDescription().getContent());
}
@Test
public void testGetSupportInformation() throws ExtractionException, IOException {
StreamExtractor supportInfoExtractor = PeerTube.getStreamExtractor("https://framatube.org/videos/watch/ee408ec8-07cd-4e35-b884-fb681a4b9d37");
supportInfoExtractor.fetchPage();
assertEquals("https://utip.io/chatsceptique", supportInfoExtractor.getSupportInfo());
}
}

View File

@ -9,6 +9,7 @@ import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeStream
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
/** /**
* Test for {@link PeertubeStreamLinkHandlerFactory} * Test for {@link PeertubeStreamLinkHandlerFactory}
@ -17,16 +18,34 @@ public class PeertubeStreamLinkHandlerFactoryTest {
private static PeertubeStreamLinkHandlerFactory linkHandler; private static PeertubeStreamLinkHandlerFactory linkHandler;
@BeforeClass @BeforeClass
public static void setUp() throws Exception { public static void setUp() {
PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host"));
linkHandler = PeertubeStreamLinkHandlerFactory.getInstance(); linkHandler = PeertubeStreamLinkHandlerFactory.getInstance();
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
} }
@Test @Test
public void getId() throws Exception { public void getId() throws Exception {
assertEquals("986aac60-1263-4f73-9ce5-36b18225cb60", linkHandler.fromUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60").getId()); assertEquals("986aac60-1263-4f73-9ce5-36b18225cb60",
assertEquals("986aac60-1263-4f73-9ce5-36b18225cb60", linkHandler.fromUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60?fsdafs=fsafa").getId()); linkHandler.fromUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60").getId());
assertEquals("9c9de5e8-0a1e-484a-b099-e80766180a6d", linkHandler.fromUrl("https://framatube.org/videos/embed/9c9de5e8-0a1e-484a-b099-e80766180a6d").getId()); assertEquals("986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60?fsdafs=fsafa").getId());
assertEquals("9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/videos/embed/9c9de5e8-0a1e-484a-b099-e80766180a6d").getId());
assertEquals("986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60").getId());
assertEquals("986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60?fsdafs=fsafa").getId());
}
@Test
public void getUrl() throws Exception {
assertEquals("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromId("986aac60-1263-4f73-9ce5-36b18225cb60").getUrl());
assertEquals("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60").getUrl());
assertEquals("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromUrl("https://peertube.mastodon.host/videos/embed/986aac60-1263-4f73-9ce5-36b18225cb60").getUrl());
} }
@ -35,5 +54,6 @@ public class PeertubeStreamLinkHandlerFactoryTest {
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60")); assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60"));
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60?fsdafs=fsafa")); assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60?fsdafs=fsafa"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/videos/embed/9c9de5e8-0a1e-484a-b099-e80766180a6d")); assertTrue(linkHandler.acceptUrl("https://framatube.org/videos/embed/9c9de5e8-0a1e-484a-b099-e80766180a6d"));
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/api/v1/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60?fsdafs=fsafa"));
} }
} }

View File

@ -8,8 +8,8 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.BaseListExtractorTest; import org.schabi.newpipe.extractor.services.BaseListExtractorTest;
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeTrendingExtractor; import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeTrendingExtractor;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.schabi.newpipe.extractor.ServiceList.*; import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
import static org.schabi.newpipe.extractor.services.DefaultTests.*; import static org.schabi.newpipe.extractor.services.DefaultTests.*;
public class PeertubeTrendingExtractorTest { public class PeertubeTrendingExtractorTest {

View File

@ -8,7 +8,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.BaseListExtractorTest; import org.schabi.newpipe.extractor.services.BaseListExtractorTest;
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChartsExtractor; import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChartsExtractor;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud; import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
import static org.schabi.newpipe.extractor.services.DefaultTests.*; import static org.schabi.newpipe.extractor.services.DefaultTests.*;

View File

@ -1,163 +0,0 @@
package org.schabi.newpipe.extractor.services.soundcloud;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudStreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.stream.StreamType;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
import static java.util.Objects.requireNonNull;
import static org.junit.Assert.*;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
/**
* Test for {@link StreamExtractor}
*/
public class SoundcloudStreamExtractorDefaultTest {
public static class LilUziVertDoWhatIWant {
private static SoundcloudStreamExtractor extractor;
@BeforeClass
public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (SoundcloudStreamExtractor) SoundCloud.getStreamExtractor("https://soundcloud.com/liluzivert/do-what-i-want-produced-by-maaly-raw-don-cannon");
extractor.fetchPage();
}
@Test
public void testGetInvalidTimeStamp() throws ParsingException {
assertTrue(extractor.getTimeStamp() + "",
extractor.getTimeStamp() <= 0);
}
@Test
public void testGetValidTimeStamp() throws IOException, ExtractionException {
StreamExtractor extractor = SoundCloud.getStreamExtractor("https://soundcloud.com/liluzivert/do-what-i-want-produced-by-maaly-raw-don-cannon#t=69");
assertEquals("69", extractor.getTimeStamp() + "");
}
@Test
public void testGetTitle() throws ParsingException {
assertEquals("Do What I Want [Produced By Maaly Raw + Don Cannon]", extractor.getName());
}
@Test
public void testGetDescription() throws ParsingException {
assertEquals("The Perfect LUV Tape®", extractor.getDescription().getContent());
}
@Test
public void testGetUploaderName() throws ParsingException {
assertEquals("Lil Uzi Vert", extractor.getUploaderName());
}
@Test
public void testGetLength() throws ParsingException {
assertEquals(175, extractor.getLength());
}
@Test
public void testGetViewCount() throws ParsingException {
assertTrue(Long.toString(extractor.getViewCount()),
extractor.getViewCount() > 44227978);
}
@Test
public void testGetTextualUploadDate() throws ParsingException {
Assert.assertEquals("2016-07-31 18:18:07", extractor.getTextualUploadDate());
}
@Test
public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss +0000");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
instance.setTime(sdf.parse("2016/07/31 18:18:07 +0000"));
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
}
@Test
public void testGetUploaderUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderUrl());
assertEquals("https://soundcloud.com/liluzivert", extractor.getUploaderUrl());
}
@Test
public void testGetThumbnailUrl() throws ParsingException {
assertIsSecureUrl(extractor.getThumbnailUrl());
}
@Test
public void testGetUploaderAvatarUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
}
@Test
public void testGetAudioStreams() throws IOException, ExtractionException {
assertFalse(extractor.getAudioStreams().isEmpty());
}
@Test
public void testStreamType() throws ParsingException {
assertTrue(extractor.getStreamType() == StreamType.AUDIO_STREAM);
}
@Test
public void testGetRelatedVideos() throws ExtractionException, IOException {
StreamInfoItemsCollector relatedVideos = extractor.getRelatedStreams();
assertFalse(relatedVideos.getItems().isEmpty());
assertTrue(relatedVideos.getErrors().isEmpty());
}
@Test
public void testGetSubtitlesListDefault() throws IOException, ExtractionException {
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
assertTrue(extractor.getSubtitlesDefault().isEmpty());
}
@Test
public void testGetSubtitlesList() throws IOException, ExtractionException {
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
assertTrue(extractor.getSubtitlesDefault().isEmpty());
}
}
public static class ContentNotSupported {
@BeforeClass
public static void setUp() {
NewPipe.init(DownloaderTestImpl.getInstance());
}
@Test(expected = ContentNotSupportedException.class)
public void hlsAudioStream() throws Exception {
final StreamExtractor extractor =
SoundCloud.getStreamExtractor("https://soundcloud.com/dualipa/cool");
extractor.fetchPage();
extractor.getAudioStreams();
}
@Test(expected = ContentNotSupportedException.class)
public void bothHlsAndOpusAudioStreams() throws Exception {
final StreamExtractor extractor =
SoundCloud.getStreamExtractor("https://soundcloud.com/lil-baby-4pf/no-sucker");
extractor.fetchPage();
extractor.getAudioStreams();
}
}
}

View File

@ -0,0 +1,81 @@
package org.schabi.newpipe.extractor.services.soundcloud;
import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest;
import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamType;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
public class SoundcloudStreamExtractorTest {
public static class LilUziVertDoWhatIWant extends DefaultStreamExtractorTest {
private static final String ID = "do-what-i-want-produced-by-maaly-raw-don-cannon";
private static final String UPLOADER = "https://soundcloud.com/liluzivert";
private static final int TIMESTAMP = 69;
private static final String URL = UPLOADER + "/" + ID + "#t=" + TIMESTAMP;
private static StreamExtractor extractor;
@BeforeClass
public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());
extractor = SoundCloud.getStreamExtractor(URL);
extractor.fetchPage();
}
@Override public StreamExtractor extractor() { return extractor; }
@Override public StreamingService expectedService() { return SoundCloud; }
@Override public String expectedName() { return "Do What I Want [Produced By Maaly Raw + Don Cannon]"; }
@Override public String expectedId() { return "276206960"; }
@Override public String expectedUrlContains() { return UPLOADER + "/" + ID; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Override public StreamType expectedStreamType() { return StreamType.AUDIO_STREAM; }
@Override public String expectedUploaderName() { return "Lil Uzi Vert"; }
@Override public String expectedUploaderUrl() { return UPLOADER; }
@Override public List<String> expectedDescriptionContains() { return Arrays.asList("The Perfect LUV Tape®"); }
@Override public long expectedLength() { return 175; }
@Override public long expectedTimestamp() { return TIMESTAMP; }
@Override public long expectedViewCountAtLeast() { return 75413600; }
@Nullable @Override public String expectedUploadDate() { return "2016-07-31 18:18:07.000"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2016-07-31 18:18:07"; }
@Override public long expectedLikeCountAtLeast() { return -1; }
@Override public long expectedDislikeCountAtLeast() { return -1; }
@Override public boolean expectedHasVideoStreams() { return false; }
@Override public boolean expectedHasSubtitles() { return false; }
@Override public boolean expectedHasFrames() { return false; }
}
public static class ContentNotSupported {
@BeforeClass
public static void setUp() {
NewPipe.init(DownloaderTestImpl.getInstance());
}
@Test(expected = ContentNotSupportedException.class)
public void hlsAudioStream() throws Exception {
final StreamExtractor extractor =
SoundCloud.getStreamExtractor("https://soundcloud.com/dualipa/cool");
extractor.fetchPage();
extractor.getAudioStreams();
}
@Test(expected = ContentNotSupportedException.class)
public void bothHlsAndOpusAudioStreams() throws Exception {
final StreamExtractor extractor =
SoundCloud.getStreamExtractor("https://soundcloud.com/lil-baby-4pf/no-sucker");
extractor.fetchPage();
extractor.getAudioStreams();
}
}
}

View File

@ -1,144 +1,53 @@
package org.schabi.newpipe.extractor.services.youtube.stream; package org.schabi.newpipe.extractor.services.youtube.stream;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl; import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest;
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.StreamExtractor; import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.extractor.stream.StreamType;
import java.io.IOException; import java.util.Arrays;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List; import java.util.List;
import static java.util.Objects.requireNonNull; import javax.annotation.Nullable;
import static org.junit.Assert.*;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.YouTube; import static org.schabi.newpipe.extractor.ServiceList.YouTube;
/** public class YoutubeStreamExtractorAgeRestrictedTest extends DefaultStreamExtractorTest {
* Test for {@link YoutubeStreamLinkHandlerFactory} private static final String ID = "MmBeUZqv1QA";
*/ private static final int TIMESTAMP = 196;
public class YoutubeStreamExtractorAgeRestrictedTest { private static final String URL = YoutubeStreamExtractorDefaultTest.BASE_URL + ID + "&t=" + TIMESTAMP;
public static final String HTTPS = "https://"; private static StreamExtractor extractor;
private static YoutubeStreamExtractor extractor;
@BeforeClass @BeforeClass
public static void setUp() throws Exception { public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (YoutubeStreamExtractor) YouTube extractor = YouTube.getStreamExtractor(URL);
.getStreamExtractor("https://www.youtube.com/watch?v=MmBeUZqv1QA");
extractor.fetchPage(); extractor.fetchPage();
} }
@Test @Override public StreamExtractor extractor() { return extractor; }
public void testGetInvalidTimeStamp() throws ParsingException { @Override public StreamingService expectedService() { return YouTube; }
assertTrue(extractor.getTimeStamp() + "", extractor.getTimeStamp() <= 0); @Override public String expectedName() { return "FINGERING PORNSTARS @ AVN Expo 2017 In Las Vegas!"; }
} @Override public String expectedId() { return ID; }
@Override public String expectedUrlContains() { return YoutubeStreamExtractorDefaultTest.BASE_URL + ID; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Test @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
public void testGetValidTimeStamp() throws IOException, ExtractionException { @Override public String expectedUploaderName() { return "EpicFiveTV"; }
StreamExtractor extractor = YouTube.getStreamExtractor("https://youtu.be/FmG385_uUys?t=174"); @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCuPUHlLP5POZphOIrjrNxiw"; }
assertEquals(extractor.getTimeStamp() + "", "174"); @Override public List<String> expectedDescriptionContains() { return Arrays.asList("http://instagram.com/Ruben_Sole", "AVN"); }
extractor = YouTube.getStreamExtractor("https://youtube.com/embed/FmG385_uUys?start=174"); @Override public long expectedLength() { return 1790; }
assertEquals(extractor.getTimeStamp() + "", "174"); @Override public long expectedTimestamp() { return TIMESTAMP; }
} @Override public long expectedViewCountAtLeast() { return 28500000; }
@Nullable @Override public String expectedUploadDate() { return "2017-01-25 00:00:00.000"; }
@Test @Nullable @Override public String expectedTextualUploadDate() { return "2017-01-25"; }
public void testGetAgeLimit() throws ParsingException { @Override public long expectedLikeCountAtLeast() { return 149000; }
assertEquals(18, extractor.getAgeLimit()); @Override public long expectedDislikeCountAtLeast() { return 38000; }
} @Override public boolean expectedHasRelatedStreams() { return false; } // no related videos (!)
@Override public int expectedAgeLimit() { return 18; }
@Test @Nullable @Override public String expectedErrorMessage() { return "Sign in to confirm your age"; }
public void testGetName() throws ParsingException { @Override public boolean expectedHasSubtitles() { return false; }
assertNotNull("name is null", extractor.getName());
assertFalse("name is empty", extractor.getName().isEmpty());
}
@Test
public void testGetDescription() throws ParsingException {
assertNotNull(extractor.getDescription());
assertFalse(extractor.getDescription().getContent().isEmpty());
}
@Test
public void testGetUploaderName() throws ParsingException {
assertNotNull(extractor.getUploaderName());
assertFalse(extractor.getUploaderName().isEmpty());
}
@Test
public void testGetLength() throws ParsingException {
assertEquals(1790, extractor.getLength());
}
@Test
public void testGetViews() throws ParsingException {
assertTrue(extractor.getViewCount() > 0);
}
@Test
public void testGetTextualUploadDate() throws ParsingException {
assertEquals("2017-01-25", extractor.getTextualUploadDate());
}
@Test
public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2017-01-25"));
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
}
@Test
public void testGetThumbnailUrl() throws ParsingException {
assertIsSecureUrl(extractor.getThumbnailUrl());
}
@Test
public void testGetUploaderAvatarUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
}
@Test
public void testGetAudioStreams() throws IOException, ExtractionException {
// audio streams are not always necessary
assertFalse(extractor.getAudioStreams().isEmpty());
}
@Test
public void testGetVideoStreams() throws IOException, ExtractionException {
List<VideoStream> streams = new ArrayList<>();
streams.addAll(extractor.getVideoStreams());
streams.addAll(extractor.getVideoOnlyStreams());
assertTrue(Integer.toString(streams.size()), streams.size() > 0);
for (VideoStream s : streams) {
assertTrue(s.getUrl(),
s.getUrl().contains(HTTPS));
assertTrue(s.resolution.length() > 0);
assertTrue(Integer.toString(s.getFormatId()),
0 <= s.getFormatId() && s.getFormatId() <= 0x100);
}
}
@Test
public void testGetSubtitlesListDefault() throws IOException, ExtractionException {
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
assertTrue(extractor.getSubtitlesDefault().isEmpty());
}
@Test
public void testGetSubtitlesList() throws IOException, ExtractionException {
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
assertTrue(extractor.getSubtitles(MediaFormat.TTML).isEmpty());
}
} }

View File

@ -1,134 +1,54 @@
package org.schabi.newpipe.extractor.services.youtube.stream; package org.schabi.newpipe.extractor.services.youtube.stream;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl; import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest;
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory; import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.StreamExtractor; import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.extractor.stream.StreamType;
import java.io.IOException; import java.util.Arrays;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List; import java.util.List;
import static java.util.Objects.requireNonNull; import javax.annotation.Nullable;
import static org.junit.Assert.*;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.YouTube; import static org.schabi.newpipe.extractor.ServiceList.YouTube;
/** /**
* Test for {@link YoutubeStreamLinkHandlerFactory} * Test for {@link YoutubeStreamLinkHandlerFactory}
*/ */
public class YoutubeStreamExtractorControversialTest { public class YoutubeStreamExtractorControversialTest extends DefaultStreamExtractorTest {
private static YoutubeStreamExtractor extractor; private static final String ID = "T4XJQO3qol8";
private static final String URL = YoutubeStreamExtractorDefaultTest.BASE_URL + ID;
private static StreamExtractor extractor;
@BeforeClass @BeforeClass
public static void setUp() throws Exception { public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (YoutubeStreamExtractor) YouTube extractor = YouTube.getStreamExtractor(URL);
.getStreamExtractor("https://www.youtube.com/watch?v=T4XJQO3qol8");
extractor.fetchPage(); extractor.fetchPage();
} }
@Test @Override public StreamExtractor extractor() { return extractor; }
public void testGetInvalidTimeStamp() throws ParsingException { @Override public StreamingService expectedService() { return YouTube; }
assertTrue(extractor.getTimeStamp() + "", extractor.getTimeStamp() <= 0); @Override public String expectedName() { return "Burning Everyone's Koran"; }
} @Override public String expectedId() { return ID; }
@Override public String expectedUrlContains() { return URL; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Test @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
public void testGetValidTimeStamp() throws IOException, ExtractionException { @Override public String expectedUploaderName() { return "Amazing Atheist"; }
StreamExtractor extractor = YouTube.getStreamExtractor("https://youtu.be/FmG385_uUys?t=174"); @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCjNxszyFPasDdRoD9J6X-sw"; }
assertEquals(extractor.getTimeStamp() + "", "174"); @Override public List<String> expectedDescriptionContains() {
} return Arrays.asList("http://www.huffingtonpost.com/2010/09/09/obama-gma-interview-quran_n_710282.html",
"freedom");
@Test
@Ignore
public void testGetAgeLimit() throws ParsingException {
assertEquals(18, extractor.getAgeLimit());
}
@Test
public void testGetName() throws ParsingException {
assertNotNull("name is null", extractor.getName());
assertFalse("name is empty", extractor.getName().isEmpty());
}
@Test
public void testGetDescription() throws ParsingException {
assertNotNull(extractor.getDescription());
assertFalse(extractor.getDescription().getContent().isEmpty());
}
@Test
public void testGetUploaderName() throws ParsingException {
assertNotNull(extractor.getUploaderName());
assertFalse(extractor.getUploaderName().isEmpty());
}
@Test
public void testGetLength() throws ParsingException {
assertEquals(219, extractor.getLength());
}
@Test
public void testGetViews() throws ParsingException {
assertTrue(extractor.getViewCount() > 0);
}
@Test
public void testGetTextualUploadDate() throws ParsingException {
assertEquals("2010-09-09", extractor.getTextualUploadDate());
}
@Test
public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2010-09-09"));
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
}
@Test
public void testGetThumbnailUrl() throws ParsingException {
assertIsSecureUrl(extractor.getThumbnailUrl());
}
@Test
public void testGetUploaderAvatarUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
}
@Test
public void testGetAudioStreams() throws IOException, ExtractionException {
// audio streams are not always necessary
assertFalse(extractor.getAudioStreams().isEmpty());
}
@Test
public void testGetVideoStreams() throws IOException, ExtractionException {
List<VideoStream> streams = new ArrayList<>();
streams.addAll(extractor.getVideoStreams());
streams.addAll(extractor.getVideoOnlyStreams());
assertTrue(streams.size() > 0);
}
@Test
public void testGetSubtitlesListDefault() throws IOException, ExtractionException {
// Video (/view?v=T4XJQO3qol8) set in the setUp() method has at least auto-generated (English) captions
assertFalse(extractor.getSubtitlesDefault().isEmpty());
}
@Test
public void testGetSubtitlesList() throws IOException, ExtractionException {
// Video (/view?v=T4XJQO3qol8) set in the setUp() method has at least auto-generated (English) captions
assertFalse(extractor.getSubtitles(MediaFormat.TTML).isEmpty());
} }
@Override public long expectedLength() { return 219; }
@Override public long expectedViewCountAtLeast() { return 285000; }
@Nullable @Override public String expectedUploadDate() { return "2010-09-09 00:00:00.000"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2010-09-09"; }
@Override public long expectedLikeCountAtLeast() { return 13300; }
@Override public long expectedDislikeCountAtLeast() { return 2600; }
} }

View File

@ -1,35 +1,22 @@
package org.schabi.newpipe.extractor.services.youtube.stream; package org.schabi.newpipe.extractor.services.youtube.stream;
import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl; import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.ExtractorAsserts;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException; import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor; import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest;
import org.schabi.newpipe.extractor.stream.Frameset;
import org.schabi.newpipe.extractor.stream.StreamExtractor; import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.extractor.utils.Utils;
import java.text.ParseException; import java.util.Arrays;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List; import java.util.List;
import static java.util.Objects.requireNonNull; import javax.annotation.Nullable;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.YouTube; import static org.schabi.newpipe.extractor.ServiceList.YouTube;
/* /*
@ -51,11 +38,8 @@ import static org.schabi.newpipe.extractor.ServiceList.YouTube;
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>. * along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* Test for {@link StreamExtractor}
*/
public class YoutubeStreamExtractorDefaultTest { public class YoutubeStreamExtractorDefaultTest {
static final String BASE_URL = "https://www.youtube.com/watch?v=";
public static class NotAvailable { public static class NotAvailable {
@BeforeClass @BeforeClass
@ -66,266 +50,162 @@ public class YoutubeStreamExtractorDefaultTest {
@Test(expected = ContentNotAvailableException.class) @Test(expected = ContentNotAvailableException.class)
public void nonExistentFetch() throws Exception { public void nonExistentFetch() throws Exception {
final StreamExtractor extractor = final StreamExtractor extractor =
YouTube.getStreamExtractor("https://www.youtube.com/watch?v=don-t-exist"); YouTube.getStreamExtractor(BASE_URL + "don-t-exist");
extractor.fetchPage(); extractor.fetchPage();
} }
@Test(expected = ParsingException.class) @Test(expected = ParsingException.class)
public void invalidId() throws Exception { public void invalidId() throws Exception {
final StreamExtractor extractor = final StreamExtractor extractor =
YouTube.getStreamExtractor("https://www.youtube.com/watch?v=INVALID_ID_INVALID_ID"); YouTube.getStreamExtractor(BASE_URL + "INVALID_ID_INVALID_ID");
extractor.fetchPage(); extractor.fetchPage();
} }
} }
/** public static class AdeleHello extends DefaultStreamExtractorTest {
* Test for {@link StreamExtractor} private static final String ID = "YQHsXMglC9A";
*/ private static final String URL = BASE_URL + ID;
public static class AdeleHello { private static StreamExtractor extractor;
private static YoutubeStreamExtractor extractor;
@BeforeClass @BeforeClass
public static void setUp() throws Exception { public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (YoutubeStreamExtractor) YouTube extractor = YouTube.getStreamExtractor(URL);
.getStreamExtractor("https://www.youtube.com/watch?v=YQHsXMglC9A");
extractor.fetchPage(); extractor.fetchPage();
} }
@Test @Test
public void testGetInvalidTimeStamp() throws ParsingException { @Override
assertTrue(extractor.getTimeStamp() + "", public void testUploaderUrl() throws ParsingException {
extractor.getTimeStamp() <= 0); String url = extractor().getUploaderUrl();
}
@Test
public void testGetValidTimeStamp() throws ExtractionException {
StreamExtractor extractor = YouTube.getStreamExtractor("https://youtu.be/FmG385_uUys?t=174");
assertEquals(extractor.getTimeStamp() + "", "174");
}
@Test
public void testGetTitle() throws ParsingException {
assertFalse(extractor.getName().isEmpty());
}
@Test
public void testGetDescription() throws ParsingException {
assertNotNull(extractor.getDescription());
assertFalse(extractor.getDescription().getContent().isEmpty());
}
@Test
public void testGetFullLinksInDescription() throws ParsingException {
assertTrue(extractor.getDescription().getContent().contains("http://adele.com"));
}
@Test
public void testGetUploaderName() throws ParsingException {
assertNotNull(extractor.getUploaderName());
assertFalse(extractor.getUploaderName().isEmpty());
}
@Test
public void testGetLength() throws ParsingException {
assertEquals(367, extractor.getLength());
}
@Test
public void testGetViewCount() throws ParsingException {
Long count = extractor.getViewCount();
assertTrue(Long.toString(count), count >= /* specific to that video */ 1220025784);
}
@Test
public void testGetTextualUploadDate() throws ParsingException {
Assert.assertEquals("2015-10-22", extractor.getTextualUploadDate());
}
@Test
public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2015-10-22"));
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
}
@Test
public void testGetUploaderUrl() throws ParsingException {
String url = extractor.getUploaderUrl();
if (!url.equals("https://www.youtube.com/channel/UCsRM0YB_dabtEPGPTKo-gcw") && if (!url.equals("https://www.youtube.com/channel/UCsRM0YB_dabtEPGPTKo-gcw") &&
!url.equals("https://www.youtube.com/channel/UComP_epzeKzvBX156r6pm1Q")) { !url.equals("https://www.youtube.com/channel/UComP_epzeKzvBX156r6pm1Q")) {
fail("Uploader url is neither the music channel one nor the Vevo one"); fail("Uploader url is neither the music channel one nor the Vevo one");
} }
} }
@Test @Override public StreamExtractor extractor() { return extractor; }
public void testGetThumbnailUrl() throws ParsingException { @Override public StreamingService expectedService() { return YouTube; }
assertIsSecureUrl(extractor.getThumbnailUrl()); @Override public String expectedName() { return "Adele - Hello"; }
} @Override public String expectedId() { return ID; }
@Override public String expectedUrlContains() { return URL; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Test @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
public void testGetUploaderAvatarUrl() throws ParsingException { @Override public String expectedUploaderName() { return "Adele"; }
assertIsSecureUrl(extractor.getUploaderAvatarUrl()); @Override public String expectedUploaderUrl() { return null; } // overridden above
} @Override public List<String> expectedDescriptionContains() { return Arrays.asList("http://adele.com", "https://www.facebook.com/Adele"); }
@Override public long expectedLength() { return 367; }
@Test @Override public long expectedViewCountAtLeast() { return 1220025784; }
public void testGetAudioStreams() throws ExtractionException { @Nullable @Override public String expectedUploadDate() { return "2015-10-22 00:00:00.000"; }
assertFalse(extractor.getAudioStreams().isEmpty()); @Nullable @Override public String expectedTextualUploadDate() { return "2015-10-22"; }
} @Override public long expectedLikeCountAtLeast() { return 15289000; }
@Override public long expectedDislikeCountAtLeast() { return 826000; }
@Test @Override public boolean expectedHasSubtitles() { return false; }
public void testGetVideoStreams() throws ExtractionException {
for (VideoStream s : extractor.getVideoStreams()) {
assertIsSecureUrl(s.url);
assertTrue(s.resolution.length() > 0);
assertTrue(Integer.toString(s.getFormatId()),
0 <= s.getFormatId() && s.getFormatId() <= 0x100);
}
}
@Test
public void testStreamType() throws ParsingException {
assertTrue(extractor.getStreamType() == StreamType.VIDEO_STREAM);
}
@Test
public void testGetDashMpd() throws ParsingException {
// we dont expect this particular video to have a DASH file. For this purpouse we use a different test class.
assertTrue(extractor.getDashMpdUrl(),
extractor.getDashMpdUrl() != null && extractor.getDashMpdUrl().isEmpty());
}
@Test
public void testGetRelatedVideos() throws ExtractionException {
StreamInfoItemsCollector relatedVideos = extractor.getRelatedStreams();
Utils.printErrors(relatedVideos.getErrors());
assertFalse(relatedVideos.getItems().isEmpty());
assertTrue(relatedVideos.getErrors().isEmpty());
}
@Test
public void testGetSubtitlesListDefault() {
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
assertTrue(extractor.getSubtitlesDefault().isEmpty());
}
@Test
public void testGetSubtitlesList() {
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
assertTrue(extractor.getSubtitles(MediaFormat.TTML).isEmpty());
}
@Test
public void testGetLikeCount() throws ParsingException {
long likeCount = extractor.getLikeCount();
assertTrue("" + likeCount, likeCount >= 15000000);
}
@Test
public void testGetDislikeCount() throws ParsingException {
long dislikeCount = extractor.getDislikeCount();
assertTrue("" + dislikeCount, dislikeCount >= 818000);
}
} }
public static class DescriptionTestPewdiepie { public static class DescriptionTestPewdiepie extends DefaultStreamExtractorTest {
private static YoutubeStreamExtractor extractor; private static final String ID = "7PIMiDcwNvc";
private static final int TIMESTAMP = 17;
private static final String URL = BASE_URL + ID + "&t=" + TIMESTAMP;
private static StreamExtractor extractor;
@BeforeClass @BeforeClass
public static void setUp() throws Exception { public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (YoutubeStreamExtractor) YouTube extractor = YouTube.getStreamExtractor(URL);
.getStreamExtractor("https://www.youtube.com/watch?v=fBc4Q_htqPg");
extractor.fetchPage(); extractor.fetchPage();
} }
@Test @Override public StreamExtractor extractor() { return extractor; }
public void testGetDescription() throws ParsingException { @Override public StreamingService expectedService() { return YouTube; }
assertNotNull(extractor.getDescription()); @Override public String expectedName() { return "Marzia & Felix - Wedding 19.08.2019"; }
assertFalse(extractor.getDescription().getContent().isEmpty()); @Override public String expectedId() { return ID; }
} @Override public String expectedUrlContains() { return BASE_URL + ID; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Test @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
public void testGetFullLinksInDescription() throws ParsingException { @Override public String expectedUploaderName() { return "PewDiePie"; }
assertTrue(extractor.getDescription().getContent().contains("https://www.reddit.com/r/PewdiepieSubmissions/")); @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UC-lHJZR3Gqxm24_Vd_AJ5Yw"; }
assertTrue(extractor.getDescription().getContent().contains("https://www.youtube.com/channel/UC3e8EMTOn4g6ZSKggHTnNng")); @Override public List<String> expectedDescriptionContains() {
assertTrue(extractor.getDescription().getContent().contains("https://usa.clutchchairz.com/product/pewdiepie-edition-throttle-series/")); return Arrays.asList("https://www.youtube.com/channel/UC7l23W7gFi4Uho6WSzckZRA",
"https://www.handcraftpictures.com/");
} }
@Override public long expectedLength() { return 381; }
@Override public long expectedTimestamp() { return TIMESTAMP; }
@Override public long expectedViewCountAtLeast() { return 26682500; }
@Nullable @Override public String expectedUploadDate() { return "2019-08-24 00:00:00.000"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2019-08-24"; }
@Override public long expectedLikeCountAtLeast() { return 5212900; }
@Override public long expectedDislikeCountAtLeast() { return 30600; }
} }
public static class DescriptionTestUnboxing { public static class DescriptionTestUnboxing extends DefaultStreamExtractorTest {
private static YoutubeStreamExtractor extractor; private static final String ID = "cV5TjZCJkuA";
private static final String URL = BASE_URL + ID;
private static StreamExtractor extractor;
@BeforeClass @BeforeClass
public static void setUp() throws Exception { public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (YoutubeStreamExtractor) YouTube extractor = YouTube.getStreamExtractor(URL);
.getStreamExtractor("https://www.youtube.com/watch?v=cV5TjZCJkuA");
extractor.fetchPage(); extractor.fetchPage();
} }
@Test @Override public StreamExtractor extractor() { return extractor; }
public void testGetDescription() throws ParsingException { @Override public StreamingService expectedService() { return YouTube; }
assertNotNull(extractor.getDescription()); @Override public String expectedName() { return "This Smartphone Changes Everything..."; }
assertFalse(extractor.getDescription().getContent().isEmpty()); @Override public String expectedId() { return ID; }
} @Override public String expectedUrlContains() { return URL; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Test @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
public void testGetFullLinksInDescription() throws ParsingException { @Override public String expectedUploaderName() { return "Unbox Therapy"; }
final String description = extractor.getDescription().getContent(); @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCsTcErHg8oDvUnTzoqsYeNw"; }
assertTrue(description.contains("https://www.youtube.com/watch?v=X7FLCHVXpsA&amp;list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34")); @Override public List<String> expectedDescriptionContains() {
assertTrue(description.contains("https://www.youtube.com/watch?v=Lqv6G0pDNnw&amp;list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34")); return Arrays.asList("https://www.youtube.com/watch?v=X7FLCHVXpsA&amp;list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34",
assertTrue(description.contains("https://www.youtube.com/watch?v=XxaRBPyrnBU&amp;list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34")); "https://www.youtube.com/watch?v=Lqv6G0pDNnw&amp;list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34",
assertTrue(description.contains("https://www.youtube.com/watch?v=U-9tUEOFKNU&amp;list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34")); "https://www.youtube.com/watch?v=XxaRBPyrnBU&amp;list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34",
"https://www.youtube.com/watch?v=U-9tUEOFKNU&amp;list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34");
} }
@Override public long expectedLength() { return 434; }
@Override public long expectedViewCountAtLeast() { return 21229200; }
@Nullable @Override public String expectedUploadDate() { return "2018-06-19 00:00:00.000"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2018-06-19"; }
@Override public long expectedLikeCountAtLeast() { return 340100; }
@Override public long expectedDislikeCountAtLeast() { return 18700; }
} }
public static class RatingsDisabledTest { public static class RatingsDisabledTest extends DefaultStreamExtractorTest {
private static YoutubeStreamExtractor extractor; private static final String ID = "HRKu0cvrr_o";
private static final int TIMESTAMP = 17;
private static final String URL = BASE_URL + ID + "&t=" + TIMESTAMP;
private static StreamExtractor extractor;
@BeforeClass @BeforeClass
public static void setUp() throws Exception { public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (YoutubeStreamExtractor) YouTube extractor = YouTube.getStreamExtractor(URL);
.getStreamExtractor("https://www.youtube.com/watch?v=HRKu0cvrr_o");
extractor.fetchPage(); extractor.fetchPage();
} }
@Test @Override public StreamExtractor extractor() { return extractor; }
public void testGetLikeCount() throws ParsingException { @Override public StreamingService expectedService() { return YouTube; }
assertEquals(-1, extractor.getLikeCount()); @Override public String expectedName() { return "AlphaOmegaSin Fanboy Logic: Likes/Dislikes Disabled = Point Invalid Lol wtf?"; }
} @Override public String expectedId() { return ID; }
@Override public String expectedUrlContains() { return BASE_URL + ID; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Test @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
public void testGetDislikeCount() throws ParsingException { @Override public String expectedUploaderName() { return "YouTuber PrinceOfFALLEN"; }
assertEquals(-1, extractor.getDislikeCount()); @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCQT2yul0lr6Ie9qNQNmw-sg"; }
} @Override public List<String> expectedDescriptionContains() { return Arrays.asList("dislikes", "Alpha", "wrong"); }
@Override public long expectedLength() { return 84; }
} @Override public long expectedTimestamp() { return TIMESTAMP; }
@Override public long expectedViewCountAtLeast() { return 190; }
public static class FramesTest { @Nullable @Override public String expectedUploadDate() { return "2019-01-02 00:00:00.000"; }
private static YoutubeStreamExtractor extractor; @Nullable @Override public String expectedTextualUploadDate() { return "2019-01-02"; }
@Override public long expectedLikeCountAtLeast() { return -1; }
@BeforeClass @Override public long expectedDislikeCountAtLeast() { return -1; }
public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (YoutubeStreamExtractor) YouTube
.getStreamExtractor("https://www.youtube.com/watch?v=HoK9shIJ2xQ");
extractor.fetchPage();
}
@Test
public void testGetFrames() throws ExtractionException {
final List<Frameset> frames = extractor.getFrames();
assertNotNull(frames);
assertFalse(frames.isEmpty());
for (final Frameset f : frames) {
for (final String url : f.getUrls()) {
ExtractorAsserts.assertIsValidUrl(url);
ExtractorAsserts.assertIsSecureUrl(url);
}
}
}
} }
} }

View File

@ -1,139 +1,55 @@
package org.schabi.newpipe.extractor.services.youtube.stream; package org.schabi.newpipe.extractor.services.youtube.stream;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl; import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest;
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor; import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.extractor.utils.Utils;
import static org.junit.Assert.assertEquals; import java.util.Arrays;
import static org.junit.Assert.assertFalse; import java.util.List;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import javax.annotation.Nullable;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.YouTube; import static org.schabi.newpipe.extractor.ServiceList.YouTube;
public class YoutubeStreamExtractorLivestreamTest { public class YoutubeStreamExtractorLivestreamTest extends DefaultStreamExtractorTest {
private static YoutubeStreamExtractor extractor; private static final String ID = "5qap5aO4i9A";
private static final int TIMESTAMP = 1737;
private static final String URL = YoutubeStreamExtractorDefaultTest.BASE_URL + ID + "&t=" + TIMESTAMP;
private static StreamExtractor extractor;
@BeforeClass @BeforeClass
public static void setUp() throws Exception { public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (YoutubeStreamExtractor) YouTube extractor = YouTube.getStreamExtractor(URL);
.getStreamExtractor("https://www.youtube.com/watch?v=5qap5aO4i9A");
extractor.fetchPage(); extractor.fetchPage();
} }
@Test @Override public StreamExtractor extractor() { return extractor; }
public void testGetInvalidTimeStamp() throws ParsingException { @Override public StreamingService expectedService() { return YouTube; }
assertTrue(extractor.getTimeStamp() + "", @Override public String expectedName() { return "lofi hip hop radio - beats to relax/study to"; }
extractor.getTimeStamp() <= 0); @Override public String expectedId() { return ID; }
} @Override public String expectedUrlContains() { return YoutubeStreamExtractorDefaultTest.BASE_URL + ID; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Test @Override public StreamType expectedStreamType() { return StreamType.LIVE_STREAM; }
public void testGetTitle() throws ParsingException { @Override public String expectedUploaderName() { return "ChilledCow"; }
assertFalse(extractor.getName().isEmpty()); @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow"; }
} @Override public List<String> expectedDescriptionContains() {
return Arrays.asList("https://bit.ly/chilledcow-playlists",
@Test "https://bit.ly/chilledcow-submissions");
public void testGetDescription() throws ParsingException {
assertNotNull(extractor.getDescription());
assertFalse(extractor.getDescription().getContent().isEmpty());
}
@Test
public void testGetFullLinksInDescription() throws ParsingException {
assertTrue(extractor.getDescription().getContent().contains("https://bit.ly/chilledcow-playlists"));
}
@Test
public void testGetUploaderName() throws ParsingException {
assertNotNull(extractor.getUploaderName());
assertFalse(extractor.getUploaderName().isEmpty());
}
@Test
public void testGetLength() throws ParsingException {
assertEquals(0, extractor.getLength());
}
@Test
public void testGetViewCount() throws ParsingException {
long count = extractor.getViewCount();
assertTrue(Long.toString(count), count > -1);
}
@Test
public void testGetUploadDate() throws ParsingException {
assertNull(extractor.getUploadDate());
assertNull(extractor.getTextualUploadDate());
}
@Test
public void testGetUploaderUrl() throws ParsingException {
assertEquals("https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow", extractor.getUploaderUrl());
}
@Test
public void testGetThumbnailUrl() throws ParsingException {
assertIsSecureUrl(extractor.getThumbnailUrl());
}
@Test
public void testGetUploaderAvatarUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
}
@Test
public void testGetAudioStreams() throws ExtractionException {
assertFalse(extractor.getAudioStreams().isEmpty());
}
@Test
public void testGetVideoStreams() throws ExtractionException {
for (VideoStream s : extractor.getVideoStreams()) {
assertIsSecureUrl(s.url);
assertTrue(s.resolution.length() > 0);
assertTrue(Integer.toString(s.getFormatId()),
0 <= s.getFormatId() && s.getFormatId() <= 0x100);
}
}
@Test
public void testStreamType() throws ParsingException {
assertSame(extractor.getStreamType(), StreamType.LIVE_STREAM);
}
@Test
public void testGetDashMpd() throws ParsingException {
assertTrue(extractor.getDashMpdUrl().startsWith("https://manifest.googlevideo.com/api/manifest/dash/"));
}
@Test
public void testGetRelatedVideos() throws ExtractionException {
StreamInfoItemsCollector relatedVideos = extractor.getRelatedStreams();
Utils.printErrors(relatedVideos.getErrors());
assertFalse(relatedVideos.getItems().isEmpty());
assertTrue(relatedVideos.getErrors().isEmpty());
}
@Test
public void testGetSubtitlesListDefault() {
assertTrue(extractor.getSubtitlesDefault().isEmpty());
}
@Test
public void testGetSubtitlesList() {
assertTrue(extractor.getSubtitles(MediaFormat.TTML).isEmpty());
} }
@Override public long expectedLength() { return 0; }
@Override public long expectedTimestamp() { return TIMESTAMP; }
@Override public long expectedViewCountAtLeast() { return 0; }
@Nullable @Override public String expectedUploadDate() { return null; }
@Nullable @Override public String expectedTextualUploadDate() { return null; }
@Override public long expectedLikeCountAtLeast() { return 825000; }
@Override public long expectedDislikeCountAtLeast() { return 15600; }
@Override public boolean expectedHasSubtitles() { return false; }
@Nullable @Override public String expectedDashMpdUrlContains() { return "https://manifest.googlevideo.com/api/manifest/dash/"; }
@Override public boolean expectedHasFrames() { return false; }
} }

View File

@ -1,161 +1,50 @@
package org.schabi.newpipe.extractor.services.youtube.stream; package org.schabi.newpipe.extractor.services.youtube.stream;
import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl; import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest;
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor; import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.extractor.utils.Utils;
import java.text.ParseException; import java.util.Arrays;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List; import java.util.List;
import static org.junit.Assert.*; import javax.annotation.Nullable;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.YouTube; import static org.schabi.newpipe.extractor.ServiceList.YouTube;
public class YoutubeStreamExtractorUnlistedTest { public class YoutubeStreamExtractorUnlistedTest extends DefaultStreamExtractorTest {
private static YoutubeStreamExtractor extractor; static final String ID = "udsB8KnIJTg";
static final String URL = YoutubeStreamExtractorDefaultTest.BASE_URL + ID;
private static StreamExtractor extractor;
@BeforeClass @BeforeClass
public static void setUp() throws Exception { public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance()); NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (YoutubeStreamExtractor) YouTube extractor = YouTube.getStreamExtractor(URL);
.getStreamExtractor("https://www.youtube.com/watch?v=udsB8KnIJTg");
extractor.fetchPage(); extractor.fetchPage();
} }
@Test @Override public StreamExtractor extractor() { return extractor; }
public void testGetInvalidTimeStamp() throws ParsingException { @Override public StreamingService expectedService() { return YouTube; }
assertTrue(extractor.getTimeStamp() + "", @Override public String expectedName() { return "Praise the Casual: Ein Neuling trifft Dark Souls - Folge 5"; }
extractor.getTimeStamp() <= 0); @Override public String expectedId() { return ID; }
} @Override public String expectedUrlContains() { return URL; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Test @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
public void testGetTitle() throws ParsingException { @Override public String expectedUploaderName() { return "Hooked"; }
assertFalse(extractor.getName().isEmpty()); @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCPysfiuOv4VKBeXFFPhKXyw"; }
} @Override public List<String> expectedDescriptionContains() {
return Arrays.asList("https://www.youtube.com/user/Roccowschiptune",
@Test "https://www.facebook.com/HookedMagazinDE");
public void testGetDescription() throws ParsingException {
assertNotNull(extractor.getDescription());
assertFalse(extractor.getDescription().getContent().isEmpty());
}
@Test
public void testGetFullLinksInDescription() throws ParsingException {
assertTrue(extractor.getDescription().getContent().contains("https://www.youtube.com/user/Roccowschiptune"));
}
@Test
public void testGetUploaderName() throws ParsingException {
assertNotNull(extractor.getUploaderName());
assertFalse(extractor.getUploaderName().isEmpty());
}
@Test
public void testGetLength() throws ParsingException {
assertEquals(2488, extractor.getLength());
}
@Test
public void testGetViewCount() throws ParsingException {
long count = extractor.getViewCount();
assertTrue(Long.toString(count), count >= /* specific to that video */ 1225);
}
@Test
public void testGetTextualUploadDate() throws ParsingException {
Assert.assertEquals("2017-09-22", extractor.getTextualUploadDate());
}
@Test
public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2017-09-22"));
assertNotNull(extractor.getUploadDate());
assertEquals(instance, extractor.getUploadDate().date());
}
@Test
public void testGetUploaderUrl() throws ParsingException {
assertEquals("https://www.youtube.com/channel/UCPysfiuOv4VKBeXFFPhKXyw", extractor.getUploaderUrl());
}
@Test
public void testGetThumbnailUrl() throws ParsingException {
assertIsSecureUrl(extractor.getThumbnailUrl());
}
@Test
public void testGetUploaderAvatarUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
}
@Test
public void testGetAudioStreams() throws ExtractionException {
List<AudioStream> audioStreams = extractor.getAudioStreams();
assertFalse(audioStreams.isEmpty());
for (AudioStream s : audioStreams) {
assertIsSecureUrl(s.url);
assertTrue(Integer.toString(s.getFormatId()),
0x100 <= s.getFormatId() && s.getFormatId() < 0x1000);
}
}
@Test
public void testGetVideoStreams() throws ExtractionException {
for (VideoStream s : extractor.getVideoStreams()) {
assertIsSecureUrl(s.url);
assertTrue(s.resolution.length() > 0);
assertTrue(Integer.toString(s.getFormatId()),
0 <= s.getFormatId() && s.getFormatId() < 0x100);
}
}
@Test
public void testStreamType() throws ParsingException {
assertSame(StreamType.VIDEO_STREAM, extractor.getStreamType());
}
@Test
public void testGetRelatedVideos() throws ExtractionException {
StreamInfoItemsCollector relatedVideos = extractor.getRelatedStreams();
Utils.printErrors(relatedVideos.getErrors());
assertFalse(relatedVideos.getItems().isEmpty());
assertTrue(relatedVideos.getErrors().isEmpty());
}
@Test
public void testGetSubtitlesListDefault() {
assertFalse(extractor.getSubtitlesDefault().isEmpty());
}
@Test
public void testGetSubtitlesList() {
assertFalse(extractor.getSubtitles(MediaFormat.TTML).isEmpty());
}
@Test
public void testGetLikeCount() throws ParsingException {
long likeCount = extractor.getLikeCount();
assertTrue("" + likeCount, likeCount >= 96);
}
@Test
public void testGetDislikeCount() throws ParsingException {
long dislikeCount = extractor.getDislikeCount();
assertTrue("" + dislikeCount, dislikeCount >= 0);
} }
@Override public long expectedLength() { return 2488; }
@Override public long expectedViewCountAtLeast() { return 1500; }
@Nullable @Override public String expectedUploadDate() { return "2017-09-22 00:00:00.000"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2017-09-22"; }
@Override public long expectedLikeCountAtLeast() { return 110; }
@Override public long expectedDislikeCountAtLeast() { return 0; }
} }