diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCConferenceExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCConferenceExtractor.java index 7d39eacb9..77ea3ad1c 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCConferenceExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCConferenceExtractor.java @@ -13,6 +13,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.services.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.StreamInfoItemsCollector; @@ -71,8 +72,8 @@ public class MediaCCCConferenceExtractor extends ChannelExtractor { @Nonnull @Override public InfoItemsPage getInitialPage() { - StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); - JsonArray events = conferenceData.getArray("events"); + final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); + final JsonArray events = conferenceData.getArray("events"); for (int i = 0; i < events.size(); i++) { collector.commit(new MediaCCCStreamInfoItemExtractor(events.getObject(i))); } @@ -87,10 +88,11 @@ public class MediaCCCConferenceExtractor extends ChannelExtractor { @Override public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { + final String conferenceUrl = MediaCCCConferenceLinkHandlerFactory.CONFERENCE_API_ENDPOINT + getId(); try { - conferenceData = JsonParser.object().from(downloader.get(getUrl()).responseBody()); + conferenceData = JsonParser.object().from(downloader.get(conferenceUrl).responseBody()); } 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 { return conferenceData.getString("title"); } - - @Nonnull - @Override - public String getOriginalUrl() { - return "https://media.ccc.de/c/" + conferenceData.getString("acronym"); - } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCParsingHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCParsingHelper.java index 9e5baaf9c..14ca5c52c 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCParsingHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCParsingHelper.java @@ -6,14 +6,17 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; +import java.util.TimeZone; public final class MediaCCCParsingHelper { private MediaCCCParsingHelper() { } public static Calendar parseDateFrom(final String textualUploadDate) throws ParsingException { - Date date; + final Date date; 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) { throw new ParsingException("Could not parse date: \"" + textualUploadDate + "\"", e); } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java index 042c5cd18..96b1a5cc7 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java @@ -19,14 +19,18 @@ 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 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.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public class MediaCCCStreamExtractor extends StreamExtractor { private JsonObject data; @@ -93,7 +97,7 @@ public class MediaCCCStreamExtractor extends StreamExtractor { @Nonnull @Override public String getUploaderUrl() { - return data.getString("conference_url"); + return MediaCCCConferenceLinkHandlerFactory.CONFERENCE_PATH + getUploaderName(); } @Nonnull @@ -111,25 +115,25 @@ public class MediaCCCStreamExtractor extends StreamExtractor { @Nonnull @Override - public String getSubChannelUrl() throws ParsingException { + public String getSubChannelUrl() { return ""; } @Nonnull @Override - public String getSubChannelName() throws ParsingException { + public String getSubChannelName() { return ""; } @Nonnull @Override - public String getSubChannelAvatarUrl() throws ParsingException { + public String getSubChannelAvatarUrl() { return ""; } @Nonnull @Override - public String getDashMpdUrl() throws ParsingException { + public String getDashMpdUrl() { return ""; } @@ -194,7 +198,7 @@ public class MediaCCCStreamExtractor extends StreamExtractor { @Override public List getVideoOnlyStreams() { - return null; + return Collections.emptyList(); } @Nonnull @@ -214,9 +218,10 @@ public class MediaCCCStreamExtractor extends StreamExtractor { return StreamType.VIDEO_STREAM; } + @Nullable @Override public StreamInfoItemsCollector getRelatedStreams() { - return new StreamInfoItemsCollector(getServiceId()); + return null; } @Override @@ -227,14 +232,13 @@ public class MediaCCCStreamExtractor extends StreamExtractor { @Override public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { + final String videoUrl = MediaCCCStreamLinkHandlerFactory.VIDEO_API_ENDPOINT + getId(); try { - data = JsonParser.object().from( - downloader.get(getLinkHandler().getUrl()).responseBody()); + data = JsonParser.object().from(downloader.get(videoUrl).responseBody()); conferenceData = JsonParser.object() - .from(downloader.get(getUploaderUrl()).responseBody()); + .from(downloader.get(data.getString("conference_url")).responseBody()); } catch (JsonParserException jpe) { - throw new ExtractionException("Could not parse json returned by url: " - + getLinkHandler().getUrl(), jpe); + throw new ExtractionException("Could not parse json returned by url: " + videoUrl, jpe); } } @@ -250,21 +254,25 @@ public class MediaCCCStreamExtractor extends StreamExtractor { return data.getString("frontend_link"); } + @Nonnull @Override public String getHost() { return ""; } + @Nonnull @Override public String getPrivacy() { return ""; } + @Nonnull @Override public String getCategory() { return ""; } + @Nonnull @Override public String getLicence() { return ""; @@ -278,7 +286,7 @@ public class MediaCCCStreamExtractor extends StreamExtractor { @Nonnull @Override public List getTags() { - return new ArrayList<>(); + return Arrays.asList(data.getArray("tags").toArray(new String[0])); } @Nonnull diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCConferenceLinkHandlerFactory.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCConferenceLinkHandlerFactory.java index 5dc903d88..e5e9b158f 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCConferenceLinkHandlerFactory.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCConferenceLinkHandlerFactory.java @@ -7,30 +7,26 @@ import org.schabi.newpipe.extractor.utils.Parser; import java.util.List; 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 - public String getUrl(final String id, final List contentFilter, final String sortFilter) - throws ParsingException { - return "https://media.ccc.de/public/conferences/" + id; + public String getUrl(final String id, + final List contentFilter, + final String sortFilter) throws ParsingException { + return CONFERENCE_PATH + id; } @Override public String getId(final String url) throws ParsingException { - if (url.startsWith("https://media.ccc.de/public/conferences/") - || 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); + return Parser.matchGroup1(ID_PATTERN, url); } @Override public boolean onAcceptUrl(final String url) { try { - getId(url); - return true; + return getId(url) != null; } catch (ParsingException e) { return false; } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCStreamLinkHandlerFactory.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCStreamLinkHandlerFactory.java index a335abf86..fa9ac4829 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCStreamLinkHandlerFactory.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/linkHandler/MediaCCCStreamLinkHandlerFactory.java @@ -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.linkhandler.LinkHandlerFactory; -import org.schabi.newpipe.extractor.utils.Utils; - -import java.net.MalformedURLException; -import java.net.URL; +import org.schabi.newpipe.extractor.utils.Parser; 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 - public String getId(final String urlString) throws ParsingException { - if (urlString.startsWith("https://media.ccc.de/public/events/") - && !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); + public String getId(final String url) throws ParsingException { + return Parser.matchGroup1(ID_PATTERN, url); } @Override public String getUrl(final String id) throws ParsingException { - return "https://media.ccc.de/public/events/" + id; + return VIDEO_PATH + id; } @Override public boolean onAcceptUrl(final String url) { try { - getId(url); - return true; + return getId(url) != null; } catch (ParsingException e) { return false; } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeAccountExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeAccountExtractor.java index 49978e889..b41bf2057 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeAccountExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeAccountExtractor.java @@ -13,6 +13,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper; +import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import org.schabi.newpipe.extractor.utils.JsonUtils; @@ -20,6 +21,8 @@ import org.schabi.newpipe.extractor.utils.Utils; 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.ITEMS_PER_PAGE; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY; @@ -85,14 +88,16 @@ public class PeertubeAccountExtractor extends ChannelExtractor { return ""; } + @Nonnull @Override public InfoItemsPage getInitialPage() throws IOException, ExtractionException { - final String pageUrl = getUrl() + "/videos?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE; - return getPage(new Page(pageUrl)); + return getPage(new Page( + getUrl() + "/videos?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE)); } @Override - public InfoItemsPage getPage(final Page page) throws IOException, ExtractionException { + public InfoItemsPage getPage(final Page page) + throws IOException, ExtractionException { if (page == null || isNullOrEmpty(page.getUrl())) { throw new IllegalArgumentException("Page doesn't contain an URL"); } @@ -122,8 +127,16 @@ public class PeertubeAccountExtractor extends ChannelExtractor { } @Override - public void onFetchPage(final Downloader downloader) throws IOException, ExtractionException { - final Response response = downloader.get(getUrl()); + public void onFetchPage(@Nonnull final Downloader downloader) + 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) { setInitialData(response.responseBody()); } else { @@ -140,13 +153,9 @@ public class PeertubeAccountExtractor extends ChannelExtractor { if (json == null) throw new ExtractionException("Unable to extract PeerTube account data"); } + @Nonnull @Override public String getName() throws ParsingException { return JsonUtils.getString(json, "displayName"); } - - @Override - public String getOriginalUrl() throws ParsingException { - return baseUrl + "/" + getId(); - } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeChannelExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeChannelExtractor.java index e6cc66b6a..432433cdc 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeChannelExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeChannelExtractor.java @@ -13,6 +13,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper; +import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import org.schabi.newpipe.extractor.utils.JsonUtils; @@ -20,6 +21,8 @@ import org.schabi.newpipe.extractor.utils.Utils; 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.ITEMS_PER_PAGE; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY; @@ -92,10 +95,11 @@ public class PeertubeChannelExtractor extends ChannelExtractor { return baseUrl + value; } + @Nonnull @Override public InfoItemsPage getInitialPage() throws IOException, ExtractionException { - final String pageUrl = getUrl() + "/videos?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE; - return getPage(new Page(pageUrl)); + return getPage(new Page( + getUrl() + "/videos?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE)); } @Override @@ -130,7 +134,8 @@ public class PeertubeChannelExtractor extends ChannelExtractor { @Override 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) { setInitialData(response.responseBody()); } else { @@ -147,13 +152,9 @@ public class PeertubeChannelExtractor extends ChannelExtractor { if (json == null) throw new ExtractionException("Unable to extract PeerTube channel data"); } + @Nonnull @Override public String getName() throws ParsingException { return JsonUtils.getString(json, "displayName"); } - - @Override - public String getOriginalUrl() throws ParsingException { - return baseUrl + "/" + getId(); - } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java index 4fda78275..fa02d473a 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamExtractor.java @@ -17,6 +17,7 @@ import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.localization.DateWrapper; 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.PeertubeStreamLinkHandlerFactory; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.Stream; @@ -37,11 +38,12 @@ import java.util.List; import java.util.Locale; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public class PeertubeStreamExtractor extends StreamExtractor { private final String baseUrl; private JsonObject json; - private List subtitles = new ArrayList<>(); + private final List subtitles = new ArrayList<>(); public PeertubeStreamExtractor(final StreamingService service, final LinkHandler linkHandler) throws ParsingException { super(service, linkHandler); @@ -64,11 +66,13 @@ public class PeertubeStreamExtractor extends StreamExtractor { return new DateWrapper(PeertubeParsingHelper.parseDateFrom(textualUploadDate)); } + @Nonnull @Override public String getThumbnailUrl() throws ParsingException { return baseUrl + JsonUtils.getString(json, "previewPath"); } + @Nonnull @Override public Description getDescription() throws ParsingException { String text; @@ -81,7 +85,9 @@ public class PeertubeStreamExtractor extends StreamExtractor { //if description is shortened, get full description final Downloader dl = NewPipe.getDownloader(); 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()); text = JsonUtils.getString(jsonObject, "description"); } catch (ReCaptchaException | IOException | JsonParserException e) { @@ -107,9 +113,16 @@ public class PeertubeStreamExtractor extends StreamExtractor { } @Override - public long getTimeStamp() { - //TODO fetch timestamp from url if present; - return 0; + public long getTimeStamp() throws ParsingException { + final long timestamp = + 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 @@ -127,6 +140,7 @@ public class PeertubeStreamExtractor extends StreamExtractor { return json.getLong("dislikes"); } + @Nonnull @Override public String getUploaderUrl() throws ParsingException { 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(); } + @Nonnull @Override public String getUploaderName() throws ParsingException { return JsonUtils.getString(json, "account.displayName"); } + @Nonnull @Override public String getUploaderAvatarUrl() { String value; @@ -150,6 +166,7 @@ public class PeertubeStreamExtractor extends StreamExtractor { return baseUrl + value; } + @Nonnull @Override public String getSubChannelUrl() throws ParsingException { return JsonUtils.getString(json, "channel.url"); @@ -173,11 +190,13 @@ public class PeertubeStreamExtractor extends StreamExtractor { return baseUrl + value; } + @Nonnull @Override public String getDashMpdUrl() { return ""; } + @Nonnull @Override public String getHlsUrl() { return ""; @@ -185,7 +204,7 @@ public class PeertubeStreamExtractor extends StreamExtractor { @Override public List getAudioStreams() { - return null; + return Collections.emptyList(); } @Override @@ -220,11 +239,13 @@ public class PeertubeStreamExtractor extends StreamExtractor { return Collections.emptyList(); } + @Nonnull @Override public List getSubtitlesDefault() { return subtitles; } + @Nonnull @Override public List getSubtitles(final MediaFormat format) { final List filteredSubs = new ArrayList<>(); @@ -241,21 +262,27 @@ public class PeertubeStreamExtractor extends StreamExtractor { return StreamType.VIDEO_STREAM; } + @Nullable @Override public StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException { - final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); final List tags = getTags(); final String apiUrl; - if (!tags.isEmpty()) { - apiUrl = getRelatedStreamsUrl(tags); - - } else { + if (tags.isEmpty()) { 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 public List getTags() { try { @@ -327,7 +354,7 @@ public class PeertubeStreamExtractor extends StreamExtractor { @Override 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) { setInitialData(response.responseBody()); } else { @@ -343,14 +370,18 @@ public class PeertubeStreamExtractor extends StreamExtractor { } catch (JsonParserException 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); } private void loadSubtitles() { if (subtitles.isEmpty()) { 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 JsonArray captions = JsonUtils.getArray(captionsJson, "data"); for (final Object c : captions) { @@ -370,31 +401,31 @@ public class PeertubeStreamExtractor extends StreamExtractor { } } + @Nonnull @Override public String getName() throws ParsingException { return JsonUtils.getString(json, "name"); } - @Override - public String getOriginalUrl() throws ParsingException { - return baseUrl + "/videos/watch/" + getId(); - } - + @Nonnull @Override public String getHost() throws ParsingException { return JsonUtils.getString(json, "account.host"); } + @Nonnull @Override public String getPrivacy() throws ParsingException { return JsonUtils.getString(json, "privacy.label"); } + @Nonnull @Override public String getCategory() throws ParsingException { return JsonUtils.getString(json, "category.label"); } + @Nonnull @Override public String getLicence() throws ParsingException { return JsonUtils.getString(json, "licence.label"); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamInfoItemExtractor.java index edb72c164..489f5fe0c 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeStreamInfoItemExtractor.java @@ -27,8 +27,7 @@ public class PeertubeStreamInfoItemExtractor implements StreamInfoItemExtractor @Override public String getThumbnailUrl() throws ParsingException { - final String value = JsonUtils.getString(item, "thumbnailPath"); - return baseUrl + value; + return baseUrl + JsonUtils.getString(item, "thumbnailPath"); } @Override @@ -51,7 +50,8 @@ public class PeertubeStreamInfoItemExtractor implements StreamInfoItemExtractor final String name = JsonUtils.getString(item, "account.name"); 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 diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/linkHandler/PeertubeChannelLinkHandlerFactory.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/linkHandler/PeertubeChannelLinkHandlerFactory.java index ef81ca4b0..9134c14e5 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/linkHandler/PeertubeChannelLinkHandlerFactory.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/linkHandler/PeertubeChannelLinkHandlerFactory.java @@ -11,7 +11,7 @@ public class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFactory { private static final PeertubeChannelLinkHandlerFactory instance = new PeertubeChannelLinkHandlerFactory(); 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() { return instance; @@ -24,19 +24,17 @@ public class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFactory { @Override public String getUrl(String id, List contentFilters, String searchFilter) throws ParsingException { - String baseUrl = ServiceList.PeerTube.getBaseUrl(); - return getUrl(id, contentFilters, searchFilter, baseUrl); + return getUrl(id, contentFilters, searchFilter, ServiceList.PeerTube.getBaseUrl()); } @Override public String getUrl(String id, List contentFilter, String sortFilter, String baseUrl) throws ParsingException { - if (id.matches(ID_PATTERN)) { - return baseUrl + API_ENDPOINT + id; + return baseUrl + "/" + id; } else { // 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; } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/linkHandler/PeertubeStreamLinkHandlerFactory.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/linkHandler/PeertubeStreamLinkHandlerFactory.java index d3f369fcc..16b3fed3f 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/linkHandler/PeertubeStreamLinkHandlerFactory.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/linkHandler/PeertubeStreamLinkHandlerFactory.java @@ -10,7 +10,8 @@ public class PeertubeStreamLinkHandlerFactory extends LinkHandlerFactory { private static final PeertubeStreamLinkHandlerFactory instance = new PeertubeStreamLinkHandlerFactory(); 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() { } @@ -21,13 +22,12 @@ public class PeertubeStreamLinkHandlerFactory extends LinkHandlerFactory { @Override public String getUrl(String id) { - String baseUrl = ServiceList.PeerTube.getBaseUrl(); - return getUrl(id, baseUrl); + return getUrl(id, ServiceList.PeerTube.getBaseUrl()); } @Override public String getUrl(String id, String baseUrl) { - return baseUrl + VIDEO_ENDPOINT + id; + return baseUrl + VIDEO_PATH + id; } @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudStreamExtractor.java index d909acfc6..bc1d59026 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudStreamExtractor.java @@ -33,6 +33,7 @@ import java.util.List; import java.util.Locale; 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.Utils.isNullOrEmpty; @@ -68,8 +69,10 @@ public class SoundcloudStreamExtractor extends StreamExtractor { @Nonnull @Override - public String getTextualUploadDate() throws ParsingException { - return track.getString("created_at").replace("T"," ").replace("Z", ""); + public String getTextualUploadDate() { + return track.getString("created_at") + .replace("T"," ") + .replace("Z", ""); } @Nonnull @@ -85,10 +88,10 @@ public class SoundcloudStreamExtractor extends StreamExtractor { if (artworkUrl.isEmpty()) { artworkUrl = track.getObject("user").getString("avatar_url", EMPTY_STRING); } - String artworkUrlBetterResolution = artworkUrl.replace("large.jpg", "crop.jpg"); - return artworkUrlBetterResolution; + return artworkUrl.replace("large.jpg", "crop.jpg"); } + @Nonnull @Override public Description getDescription() { return new Description(track.getString("description"), Description.PLAIN_TEXT); @@ -144,19 +147,19 @@ public class SoundcloudStreamExtractor extends StreamExtractor { @Nonnull @Override - public String getSubChannelUrl() throws ParsingException { + public String getSubChannelUrl() { return ""; } @Nonnull @Override - public String getSubChannelName() throws ParsingException { + public String getSubChannelName() { return ""; } @Nonnull @Override - public String getSubChannelAvatarUrl() throws ParsingException { + public String getSubChannelAvatarUrl() { return ""; } @@ -168,14 +171,14 @@ public class SoundcloudStreamExtractor extends StreamExtractor { @Nonnull @Override - public String getHlsUrl() throws ParsingException { + public String getHlsUrl() { return ""; } @Override public List getAudioStreams() throws IOException, ExtractionException { List audioStreams = new ArrayList<>(); - Downloader dl = NewPipe.getDownloader(); + final Downloader dl = NewPipe.getDownloader(); // Streams can be streamable and downloadable - or explicitly not. // 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; try { - JsonArray transcodings = track.getObject("media").getArray("transcodings"); + final JsonArray transcodings = track.getObject("media").getArray("transcodings"); // get information about what stream formats are available for (Object transcoding : transcodings) { - JsonObject t = (JsonObject) transcoding; + final JsonObject t = (JsonObject) transcoding; String url = t.getString("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. // TODO: move this to a separate method to generate valid urls when needed (e.g. resuming a paused stream) url += "?client_id=" + SoundcloudParsingHelper.clientId(); - String res = dl.get(url).responseBody(); + final String res = dl.get(url).responseBody(); try { JsonObject mp3UrlObject = JsonParser.object().from(res); @@ -234,24 +237,24 @@ public class SoundcloudStreamExtractor extends StreamExtractor { } @Override - public List getVideoStreams() throws IOException, ExtractionException { - return null; + public List getVideoStreams() { + return Collections.emptyList(); } @Override - public List getVideoOnlyStreams() throws IOException, ExtractionException { - return null; - } - - @Override - @Nonnull - public List getSubtitlesDefault() throws IOException, ExtractionException { + public List getVideoOnlyStreams() { return Collections.emptyList(); } @Override @Nonnull - public List getSubtitles(MediaFormat format) throws IOException, ExtractionException { + public List getSubtitlesDefault() { + return Collections.emptyList(); + } + + @Override + @Nonnull + public List getSubtitles(MediaFormat format) { return Collections.emptyList(); } @@ -260,12 +263,13 @@ public class SoundcloudStreamExtractor extends StreamExtractor { return StreamType.AUDIO_STREAM; } + @Nullable @Override 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" - + "?client_id=" + urlEncode(SoundcloudParsingHelper.clientId()); + final String apiUrl = "https://api-v2.soundcloud.com/tracks/" + urlEncode(getId()) + + "/related?client_id=" + urlEncode(SoundcloudParsingHelper.clientId()); SoundcloudParsingHelper.getStreamsFromApi(collector, apiUrl); return collector; @@ -276,40 +280,44 @@ public class SoundcloudStreamExtractor extends StreamExtractor { return null; } + @Nonnull @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 ""; } @Override - public String getPrivacy() throws ParsingException { - return ""; - } - - @Override - public String getCategory() throws ParsingException { - return ""; - } - - @Override - public String getLicence() throws ParsingException { - return ""; - } - - @Override - public Locale getLanguageInfo() throws ParsingException { + public Locale getLanguageInfo() { return null; } @Nonnull @Override - public List getTags() throws ParsingException { - return new ArrayList<>(); + public List getTags() { + return Collections.emptyList(); } @Nonnull @Override - public String getSupportInfo() throws ParsingException { + public String getSupportInfo() { return ""; } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java index af10efa22..ac7db9855 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java @@ -183,9 +183,11 @@ public class YoutubeParsingHelper { } public static Calendar parseDateFrom(String textualUploadDate) throws ParsingException { - Date date; + final Date date; 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) { throw new ParsingException("Could not parse date: \"" + textualUploadDate + "\"", e); } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java index 8364246c2..0077a163e 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java @@ -253,7 +253,15 @@ public class YoutubeStreamExtractor extends StreamExtractor { */ @Override 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 @@ -568,11 +576,14 @@ public class YoutubeStreamExtractor extends StreamExtractor { } } + @Nullable @Override public StreamInfoItemsCollector getRelatedStreams() throws ExtractionException { assertPageFetched(); - if (getAgeLimit() != NO_AGE_LIMIT) return null; + if (getAgeLimit() != NO_AGE_LIMIT) { + return null; + } try { final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); @@ -604,10 +615,11 @@ public class YoutubeStreamExtractor extends StreamExtractor { @Override public String getErrorMessage() { try { - return getTextFromObject(initialAjaxJson.getObject(2).getObject("playerResponse").getObject("playabilityStatus") - .getObject("errorScreen").getObject("playerErrorMessageRenderer").getObject("reason")); - } catch (ParsingException e) { - return null; + return getTextFromObject(initialAjaxJson.getObject(2).getObject("playerResponse") + .getObject("playabilityStatus").getObject("errorScreen") + .getObject("playerErrorMessageRenderer").getObject("reason")); + } catch (ParsingException | NullPointerException e) { + return null; // no error message } } @@ -999,12 +1011,18 @@ public class YoutubeStreamExtractor extends StreamExtractor { @Override public List getFrames() throws ExtractionException { try { - JsonObject jo = initialAjaxJson.getObject(2).getObject("player"); - final String resp = jo.getObject("args").getString("player_response"); - jo = JsonParser.object().from(resp); - final String[] spec = jo.getObject("storyboards").getObject("playerStoryboardSpecRenderer").getString("spec").split("\\|"); + final JsonObject storyboards = playerResponse.getObject("storyboards"); + final JsonObject storyboardsRenderer; + if (storyboards.has("playerLiveStoryboardSpecRenderer")) { + storyboardsRenderer = storyboards.getObject("playerLiveStoryboardSpecRenderer"); + } else { + storyboardsRenderer = storyboards.getObject("playerStoryboardSpecRenderer"); + } + + final String[] spec = storyboardsRenderer.getString("spec").split("\\|"); final String url = spec[0]; final ArrayList result = new ArrayList<>(spec.length - 1); + for (int i = 1; i < spec.length; ++i) { final String[] parts = spec[i].split("#"); if (parts.length != 8) { @@ -1074,7 +1092,7 @@ public class YoutubeStreamExtractor extends StreamExtractor { @Nonnull @Override public List getTags() { - return new ArrayList<>(); + return Collections.emptyList(); } @Nonnull diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java index f48bb913f..4e109bbab 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java @@ -321,6 +321,7 @@ public abstract class StreamExtractor extends Extractor { * @throws IOException * @throws ExtractionException */ + @Nullable public abstract StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException; /** diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/ExtractorAsserts.java b/extractor/src/test/java/org/schabi/newpipe/extractor/ExtractorAsserts.java index 1006f7b34..69e10b0ed 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/ExtractorAsserts.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/ExtractorAsserts.java @@ -1,12 +1,19 @@ 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.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 static void assertEmptyErrors(String message, List errors) { @@ -56,4 +63,22 @@ public class ExtractorAsserts { 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 expected, List actual) { + if (expected == null) { + assertNull(actual); + return; + } else { + assertNotNull(actual); + } + + Collections.sort(expected); + Collections.sort(actual); + assertEquals(expected, actual); + } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/BaseStreamExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/BaseStreamExtractorTest.java new file mode 100644 index 000000000..40356cebf --- /dev/null +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/BaseStreamExtractorTest.java @@ -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; +} diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/DefaultStreamExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/DefaultStreamExtractorTest.java new file mode 100644 index 000000000..a70b38a8a --- /dev/null +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/DefaultStreamExtractorTest.java @@ -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 + 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 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 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 videoStreams = extractor().getVideoStreams(); + final List 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 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 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 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 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()); + } +} diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/DefaultTests.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/DefaultTests.java index a335b0eca..d2b9ca4ae 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/DefaultTests.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/DefaultTests.java @@ -10,7 +10,6 @@ import org.schabi.newpipe.extractor.localization.DateWrapper; import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem; -import java.util.Calendar; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -42,7 +41,7 @@ public final class DefaultTests { StreamInfoItem streamInfoItem = (StreamInfoItem) item; 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(); if (!isNullOrEmpty(uploaderUrl)) { assertIsSecureUrl(uploaderUrl); @@ -54,7 +53,6 @@ public final class DefaultTests { if (!isNullOrEmpty(streamInfoItem.getTextualUploadDate())) { final DateWrapper uploadDate = streamInfoItem.getUploadDate(); assertNotNull("No parsed upload date", uploadDate); - assertTrue("Upload date not in the past", uploadDate.date().before(Calendar.getInstance())); } } else if (item instanceof ChannelInfoItem) { diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCConferenceExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCConferenceExtractorTest.java index 98b6203c9..f189497df 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCConferenceExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCConferenceExtractorTest.java @@ -31,7 +31,7 @@ public class MediaCCCConferenceExtractorTest { @Test 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 @@ -67,7 +67,7 @@ public class MediaCCCConferenceExtractorTest { @Test 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 diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCConferenceLinkHandlerFactoryTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCConferenceLinkHandlerFactoryTest.java new file mode 100644 index 000000000..945bbc35e --- /dev/null +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCConferenceLinkHandlerFactoryTest.java @@ -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()); + } +} diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamExtractorTest.java index 95c882290..ec962cb2c 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamExtractorTest.java @@ -1,204 +1,152 @@ package org.schabi.newpipe.extractor.services.media_ccc; -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.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.stream.AudioStream; -import org.schabi.newpipe.extractor.stream.VideoStream; +import org.schabi.newpipe.extractor.stream.StreamExtractor; +import org.schabi.newpipe.extractor.stream.StreamType; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; +import java.util.Arrays; import java.util.List; -import static java.util.Objects.requireNonNull; +import javax.annotation.Nullable; + import static junit.framework.TestCase.assertEquals; -import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl; import static org.schabi.newpipe.extractor.ServiceList.MediaCCC; /** * Test {@link MediaCCCStreamExtractor} */ public class MediaCCCStreamExtractorTest { - public static class Gpn18Tmux { - private static MediaCCCStreamExtractor extractor; + private static final String BASE_URL = "https://media.ccc.de/v/"; + + 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 - public static void setUpClass() throws Exception { + public static void setUp() throws Exception { NewPipe.init(DownloaderTestImpl.getInstance()); - - extractor = (MediaCCCStreamExtractor) MediaCCC.getStreamExtractor("https://media.ccc.de/v/gpn18-105-tmux-warum-ein-schwarzes-fenster-am-bildschirm-reicht"); + extractor = MediaCCC.getStreamExtractor(URL); extractor.fetchPage(); } - @Test - public void testServiceId() throws Exception { - assertEquals(2, extractor.getServiceId()); - } + @Override public StreamExtractor extractor() { return extractor; } + @Override public StreamingService expectedService() { return MediaCCC; } + @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 - public void testName() throws Exception { - assertEquals("tmux - Warum ein schwarzes Fenster am Bildschirm reicht", extractor.getName()); - } + @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; } + @Override public String expectedUploaderName() { return "gpn18"; } + @Override public String expectedUploaderUrl() { return "https://media.ccc.de/c/gpn18"; } + @Override public List 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 expectedTags() { return Arrays.asList("gpn18", "105"); } + @Override @Test - public void testId() throws Exception { - assertEquals("gpn18-105-tmux-warum-ein-schwarzes-fenster-am-bildschirm-reicht", extractor.getId()); - } - - @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()); + public void testThumbnailUrl() throws Exception { + super.testThumbnailUrl(); assertEquals("https://static.media.ccc.de/media/events/gpn/gpn18/105-hd.jpg", extractor.getThumbnailUrl()); } - @Test - 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()); - } - + @Override @Test public void testUploaderAvatarUrl() throws Exception { - assertIsSecureUrl(extractor.getUploaderAvatarUrl()); + super.testUploaderAvatarUrl(); assertEquals("https://static.media.ccc.de/media/events/gpn/gpn18/logo.png", extractor.getUploaderAvatarUrl()); } + @Override @Test public void testVideoStreams() throws Exception { - List videoStreamList = extractor.getVideoStreams(); - assertEquals(4, videoStreamList.size()); - for (VideoStream stream : videoStreamList) { - assertIsSecureUrl(stream.getUrl()); - } + super.testVideoStreams(); + assertEquals(4, extractor.getVideoStreams().size()); } + @Override @Test public void testAudioStreams() throws Exception { - List audioStreamList = extractor.getAudioStreams(); - assertEquals(2, audioStreamList.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()); + super.testAudioStreams(); + assertEquals(2, extractor.getAudioStreams().size()); } } - public static class _36c3PrivacyMessaging { - private static MediaCCCStreamExtractor extractor; + public static class _36c3PrivacyMessaging extends DefaultStreamExtractorTest { + 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 - public static void setUpClass() throws Exception { + public static void setUp() throws Exception { 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(); } - @Test - public void testName() throws Exception { - assertEquals("What's left for private messaging?", extractor.getName()); - } + @Override public StreamExtractor extractor() { return extractor; } + @Override public StreamingService expectedService() { return MediaCCC; } + @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 - public void testId() throws Exception { - assertEquals("36c3-10565-what_s_left_for_private_messaging", extractor.getId()); - } + @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; } + @Override public String expectedUploaderName() { return "36c3"; } + @Override public String expectedUploaderUrl() { return "https://media.ccc.de/c/36c3"; } + @Override public List 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 expectedTags() { return Arrays.asList("36c3", "10565", "2019", "Security", "Main"); } + @Override @Test - public void testUrl() throws Exception { - assertIsSecureUrl(extractor.getUrl()); - 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()); + public void testThumbnailUrl() throws Exception { + super.testThumbnailUrl(); assertEquals("https://static.media.ccc.de/media/congress/2019/10565-hd.jpg", extractor.getThumbnailUrl()); } - @Test - 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()); - } - + @Override @Test public void testUploaderAvatarUrl() throws Exception { - assertIsSecureUrl(extractor.getUploaderAvatarUrl()); + super.testUploaderAvatarUrl(); assertEquals("https://static.media.ccc.de/media/congress/2019/logo.png", extractor.getUploaderAvatarUrl()); } + @Override @Test public void testVideoStreams() throws Exception { - List videoStreamList = extractor.getVideoStreams(); - assertEquals(8, videoStreamList.size()); - for (VideoStream stream : videoStreamList) { - assertIsSecureUrl(stream.getUrl()); - } + super.testVideoStreams(); + assertEquals(8, extractor.getVideoStreams().size()); } + @Override @Test public void testAudioStreams() throws Exception { - List audioStreamList = extractor.getAudioStreams(); - assertEquals(2, audioStreamList.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()); + super.testAudioStreams(); + assertEquals(2, extractor.getAudioStreams().size()); } } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamLinkHandlerFactoryTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamLinkHandlerFactoryTest.java new file mode 100644 index 000000000..79228ae60 --- /dev/null +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCStreamLinkHandlerFactoryTest.java @@ -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()); + } +} diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeAccountExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeAccountExtractorTest.java index fd944f49d..1c315ff12 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeAccountExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeAccountExtractorTest.java @@ -28,7 +28,7 @@ public class PeertubeAccountExtractorTest { // setting instance might break test when running in parallel PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host")); extractor = (PeertubeAccountExtractor) PeerTube - .getChannelExtractor("https://peertube.mastodon.host/api/v1/accounts/kde"); + .getChannelExtractor("https://peertube.mastodon.host/accounts/kde"); extractor.fetchPage(); } @@ -53,7 +53,7 @@ public class PeertubeAccountExtractorTest { @Test 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 @@ -115,7 +115,7 @@ public class PeertubeAccountExtractorTest { // setting instance might break test when running in parallel PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host")); extractor = (PeertubeAccountExtractor) PeerTube - .getChannelExtractor("https://peertube.mastodon.host/accounts/booteille"); + .getChannelExtractor("https://peertube.mastodon.host/api/v1/accounts/booteille"); extractor.fetchPage(); } @@ -150,12 +150,12 @@ public class PeertubeAccountExtractorTest { @Test 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 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()); } /*////////////////////////////////////////////////////////////////////////// diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeChannelExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeChannelExtractorTest.java index 010dbd7b4..f9e686c82 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeChannelExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeChannelExtractorTest.java @@ -28,7 +28,7 @@ public class PeertubeChannelExtractorTest { // setting instance might break test when running in parallel PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host")); 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(); } @@ -53,7 +53,7 @@ public class PeertubeChannelExtractorTest { @Test 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 @@ -130,7 +130,7 @@ public class PeertubeChannelExtractorTest { // setting instance might break test when running in parallel PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host")); 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(); } @@ -165,12 +165,12 @@ public class PeertubeChannelExtractorTest { @Test 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 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()); } /*////////////////////////////////////////////////////////////////////////// diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeChannelLinkHandlerFactoryTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeChannelLinkHandlerFactoryTest.java index d47dc6f64..6696ad631 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeChannelLinkHandlerFactoryTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeChannelLinkHandlerFactoryTest.java @@ -28,20 +28,36 @@ public class PeertubeChannelLinkHandlerFactoryTest { @Test public void acceptUrlTest() throws ParsingException { 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 - public void getIdFromUrl() 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", 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()); + 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", + 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 - public void getUrlFromId() 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/api/v1/accounts/kranti@videos.squat.net", linkHandler.fromId("accounts/kranti@videos.squat.net").getUrl()); - assertEquals("https://peertube.mastodon.host/api/v1/accounts/kranti@videos.squat.net", linkHandler.fromId("kranti@videos.squat.net").getUrl()); + public void getUrl() throws ParsingException { + assertEquals("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa", + linkHandler.fromId("video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa").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()); } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamExtractorDefaultTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamExtractorDefaultTest.java deleted file mode 100644 index c3d8c7169..000000000 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamExtractorDefaultTest.java +++ /dev/null @@ -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()); - } -} diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamExtractorTest.java new file mode 100644 index 000000000..f8c729571 --- /dev/null +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamExtractorTest.java @@ -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 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 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 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 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()); + } +} diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamLinkHandlerFactoryTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamLinkHandlerFactoryTest.java index f217b8e3a..e60db3ba9 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamLinkHandlerFactoryTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeStreamLinkHandlerFactoryTest.java @@ -9,6 +9,7 @@ import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeStream import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.schabi.newpipe.extractor.ServiceList.PeerTube; /** * Test for {@link PeertubeStreamLinkHandlerFactory} @@ -17,16 +18,34 @@ public class PeertubeStreamLinkHandlerFactoryTest { private static PeertubeStreamLinkHandlerFactory linkHandler; @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(); NewPipe.init(DownloaderTestImpl.getInstance()); } @Test 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", 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/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60").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?fsdafs=fsafa")); 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")); } } \ No newline at end of file diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeTrendingExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeTrendingExtractorTest.java index 60f72f9d1..924dbbc1f 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeTrendingExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/peertube/PeertubeTrendingExtractorTest.java @@ -8,8 +8,8 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.services.BaseListExtractorTest; import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeTrendingExtractor; -import static org.junit.Assert.*; -import static org.schabi.newpipe.extractor.ServiceList.*; +import static org.junit.Assert.assertEquals; +import static org.schabi.newpipe.extractor.ServiceList.PeerTube; import static org.schabi.newpipe.extractor.services.DefaultTests.*; public class PeertubeTrendingExtractorTest { diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudChartsExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudChartsExtractorTest.java index 8abfb4d3f..54c48431b 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudChartsExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudChartsExtractorTest.java @@ -8,7 +8,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.services.BaseListExtractorTest; 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.services.DefaultTests.*; diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractorDefaultTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractorDefaultTest.java deleted file mode 100644 index 794a1a6b6..000000000 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractorDefaultTest.java +++ /dev/null @@ -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(); - } - } -} - diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractorTest.java new file mode 100644 index 000000000..28c8d0b23 --- /dev/null +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractorTest.java @@ -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 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(); + } + } +} diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorAgeRestrictedTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorAgeRestrictedTest.java index 95c8aeb43..6844ca2e9 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorAgeRestrictedTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorAgeRestrictedTest.java @@ -1,144 +1,53 @@ package org.schabi.newpipe.extractor.services.youtube.stream; import org.junit.BeforeClass; -import org.junit.Test; import org.schabi.newpipe.DownloaderTestImpl; -import org.schabi.newpipe.extractor.MediaFormat; 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.youtube.extractors.YoutubeStreamExtractor; -import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory; +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest; 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.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; +import java.util.Arrays; import java.util.List; -import static java.util.Objects.requireNonNull; -import static org.junit.Assert.*; -import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl; +import javax.annotation.Nullable; + import static org.schabi.newpipe.extractor.ServiceList.YouTube; -/** - * Test for {@link YoutubeStreamLinkHandlerFactory} - */ -public class YoutubeStreamExtractorAgeRestrictedTest { - public static final String HTTPS = "https://"; - private static YoutubeStreamExtractor extractor; +public class YoutubeStreamExtractorAgeRestrictedTest extends DefaultStreamExtractorTest { + private static final String ID = "MmBeUZqv1QA"; + private static final int TIMESTAMP = 196; + private static final String URL = YoutubeStreamExtractorDefaultTest.BASE_URL + ID + "&t=" + TIMESTAMP; + private static StreamExtractor extractor; @BeforeClass public static void setUp() throws Exception { NewPipe.init(DownloaderTestImpl.getInstance()); - extractor = (YoutubeStreamExtractor) YouTube - .getStreamExtractor("https://www.youtube.com/watch?v=MmBeUZqv1QA"); + extractor = YouTube.getStreamExtractor(URL); extractor.fetchPage(); } - @Test - public void testGetInvalidTimeStamp() throws ParsingException { - assertTrue(extractor.getTimeStamp() + "", extractor.getTimeStamp() <= 0); - } + @Override public StreamExtractor extractor() { return extractor; } + @Override public StreamingService expectedService() { return YouTube; } + @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 - public void testGetValidTimeStamp() throws IOException, ExtractionException { - StreamExtractor extractor = YouTube.getStreamExtractor("https://youtu.be/FmG385_uUys?t=174"); - assertEquals(extractor.getTimeStamp() + "", "174"); - extractor = YouTube.getStreamExtractor("https://youtube.com/embed/FmG385_uUys?start=174"); - assertEquals(extractor.getTimeStamp() + "", "174"); - } - - @Test - 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(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 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()); - } + @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; } + @Override public String expectedUploaderName() { return "EpicFiveTV"; } + @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCuPUHlLP5POZphOIrjrNxiw"; } + @Override public List expectedDescriptionContains() { return Arrays.asList("http://instagram.com/Ruben_Sole", "AVN"); } + @Override public long expectedLength() { return 1790; } + @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"; } + @Nullable @Override public String expectedTextualUploadDate() { return "2017-01-25"; } + @Override public long expectedLikeCountAtLeast() { return 149000; } + @Override public long expectedDislikeCountAtLeast() { return 38000; } + @Override public boolean expectedHasRelatedStreams() { return false; } // no related videos (!) + @Override public int expectedAgeLimit() { return 18; } + @Nullable @Override public String expectedErrorMessage() { return "Sign in to confirm your age"; } + @Override public boolean expectedHasSubtitles() { return false; } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorControversialTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorControversialTest.java index 915f42ae1..a090460a5 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorControversialTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorControversialTest.java @@ -1,134 +1,54 @@ package org.schabi.newpipe.extractor.services.youtube.stream; import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; import org.schabi.newpipe.DownloaderTestImpl; -import org.schabi.newpipe.extractor.MediaFormat; 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.youtube.extractors.YoutubeStreamExtractor; +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest; import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory; 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.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; +import java.util.Arrays; import java.util.List; -import static java.util.Objects.requireNonNull; -import static org.junit.Assert.*; -import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl; +import javax.annotation.Nullable; + import static org.schabi.newpipe.extractor.ServiceList.YouTube; /** * Test for {@link YoutubeStreamLinkHandlerFactory} */ -public class YoutubeStreamExtractorControversialTest { - private static YoutubeStreamExtractor extractor; +public class YoutubeStreamExtractorControversialTest extends DefaultStreamExtractorTest { + private static final String ID = "T4XJQO3qol8"; + private static final String URL = YoutubeStreamExtractorDefaultTest.BASE_URL + ID; + private static StreamExtractor extractor; @BeforeClass public static void setUp() throws Exception { NewPipe.init(DownloaderTestImpl.getInstance()); - extractor = (YoutubeStreamExtractor) YouTube - .getStreamExtractor("https://www.youtube.com/watch?v=T4XJQO3qol8"); + extractor = YouTube.getStreamExtractor(URL); extractor.fetchPage(); } - @Test - public void testGetInvalidTimeStamp() throws ParsingException { - assertTrue(extractor.getTimeStamp() + "", extractor.getTimeStamp() <= 0); - } + @Override public StreamExtractor extractor() { return extractor; } + @Override public StreamingService expectedService() { return YouTube; } + @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 - public void testGetValidTimeStamp() throws IOException, ExtractionException { - StreamExtractor extractor = YouTube.getStreamExtractor("https://youtu.be/FmG385_uUys?t=174"); - assertEquals(extractor.getTimeStamp() + "", "174"); - } - - @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 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 StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; } + @Override public String expectedUploaderName() { return "Amazing Atheist"; } + @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCjNxszyFPasDdRoD9J6X-sw"; } + @Override public List expectedDescriptionContains() { + return Arrays.asList("http://www.huffingtonpost.com/2010/09/09/obama-gma-interview-quran_n_710282.html", + "freedom"); } + @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; } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorDefaultTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorDefaultTest.java index 0d36fd9a8..6a3aa4f28 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorDefaultTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorDefaultTest.java @@ -1,35 +1,22 @@ package org.schabi.newpipe.extractor.services.youtube.stream; -import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; 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.StreamingService; 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.services.youtube.extractors.YoutubeStreamExtractor; -import org.schabi.newpipe.extractor.stream.Frameset; +import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest; 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.VideoStream; -import org.schabi.newpipe.extractor.utils.Utils; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; +import java.util.Arrays; import java.util.List; -import static java.util.Objects.requireNonNull; -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 javax.annotation.Nullable; + import static org.junit.Assert.fail; -import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl; 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 * along with NewPipe. If not, see . */ - -/** - * Test for {@link StreamExtractor} - */ public class YoutubeStreamExtractorDefaultTest { + static final String BASE_URL = "https://www.youtube.com/watch?v="; public static class NotAvailable { @BeforeClass @@ -66,266 +50,162 @@ public class YoutubeStreamExtractorDefaultTest { @Test(expected = ContentNotAvailableException.class) public void nonExistentFetch() throws Exception { final StreamExtractor extractor = - YouTube.getStreamExtractor("https://www.youtube.com/watch?v=don-t-exist"); + YouTube.getStreamExtractor(BASE_URL + "don-t-exist"); extractor.fetchPage(); } @Test(expected = ParsingException.class) public void invalidId() throws Exception { 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(); } } - /** - * Test for {@link StreamExtractor} - */ - public static class AdeleHello { - private static YoutubeStreamExtractor extractor; + public static class AdeleHello extends DefaultStreamExtractorTest { + private static final String ID = "YQHsXMglC9A"; + private static final String URL = BASE_URL + ID; + private static StreamExtractor extractor; @BeforeClass public static void setUp() throws Exception { NewPipe.init(DownloaderTestImpl.getInstance()); - extractor = (YoutubeStreamExtractor) YouTube - .getStreamExtractor("https://www.youtube.com/watch?v=YQHsXMglC9A"); + extractor = YouTube.getStreamExtractor(URL); extractor.fetchPage(); } @Test - public void testGetInvalidTimeStamp() throws ParsingException { - assertTrue(extractor.getTimeStamp() + "", - extractor.getTimeStamp() <= 0); - } - - @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(); + @Override + public void testUploaderUrl() throws ParsingException { + String url = extractor().getUploaderUrl(); if (!url.equals("https://www.youtube.com/channel/UCsRM0YB_dabtEPGPTKo-gcw") && !url.equals("https://www.youtube.com/channel/UComP_epzeKzvBX156r6pm1Q")) { fail("Uploader url is neither the music channel one nor the Vevo one"); } } - @Test - public void testGetThumbnailUrl() throws ParsingException { - assertIsSecureUrl(extractor.getThumbnailUrl()); - } + @Override public StreamExtractor extractor() { return extractor; } + @Override public StreamingService expectedService() { return YouTube; } + @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 - 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 { - 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); - } + @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; } + @Override public String expectedUploaderName() { return "Adele"; } + @Override public String expectedUploaderUrl() { return null; } // overridden above + @Override public List expectedDescriptionContains() { return Arrays.asList("http://adele.com", "https://www.facebook.com/Adele"); } + @Override public long expectedLength() { return 367; } + @Override public long expectedViewCountAtLeast() { return 1220025784; } + @Nullable @Override public String expectedUploadDate() { return "2015-10-22 00:00:00.000"; } + @Nullable @Override public String expectedTextualUploadDate() { return "2015-10-22"; } + @Override public long expectedLikeCountAtLeast() { return 15289000; } + @Override public long expectedDislikeCountAtLeast() { return 826000; } + @Override public boolean expectedHasSubtitles() { return false; } } - public static class DescriptionTestPewdiepie { - private static YoutubeStreamExtractor extractor; + public static class DescriptionTestPewdiepie extends DefaultStreamExtractorTest { + 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 public static void setUp() throws Exception { NewPipe.init(DownloaderTestImpl.getInstance()); - extractor = (YoutubeStreamExtractor) YouTube - .getStreamExtractor("https://www.youtube.com/watch?v=fBc4Q_htqPg"); + extractor = YouTube.getStreamExtractor(URL); extractor.fetchPage(); } - @Test - public void testGetDescription() throws ParsingException { - assertNotNull(extractor.getDescription()); - assertFalse(extractor.getDescription().getContent().isEmpty()); - } + @Override public StreamExtractor extractor() { return extractor; } + @Override public StreamingService expectedService() { return YouTube; } + @Override public String expectedName() { return "Marzia & Felix - Wedding 19.08.2019"; } + @Override public String expectedId() { return ID; } + @Override public String expectedUrlContains() { return BASE_URL + ID; } + @Override public String expectedOriginalUrlContains() { return URL; } - @Test - public void testGetFullLinksInDescription() throws ParsingException { - assertTrue(extractor.getDescription().getContent().contains("https://www.reddit.com/r/PewdiepieSubmissions/")); - assertTrue(extractor.getDescription().getContent().contains("https://www.youtube.com/channel/UC3e8EMTOn4g6ZSKggHTnNng")); - assertTrue(extractor.getDescription().getContent().contains("https://usa.clutchchairz.com/product/pewdiepie-edition-throttle-series/")); + @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; } + @Override public String expectedUploaderName() { return "PewDiePie"; } + @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UC-lHJZR3Gqxm24_Vd_AJ5Yw"; } + @Override public List expectedDescriptionContains() { + 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 { - private static YoutubeStreamExtractor extractor; + public static class DescriptionTestUnboxing extends DefaultStreamExtractorTest { + private static final String ID = "cV5TjZCJkuA"; + private static final String URL = BASE_URL + ID; + private static StreamExtractor extractor; @BeforeClass public static void setUp() throws Exception { NewPipe.init(DownloaderTestImpl.getInstance()); - extractor = (YoutubeStreamExtractor) YouTube - .getStreamExtractor("https://www.youtube.com/watch?v=cV5TjZCJkuA"); + extractor = YouTube.getStreamExtractor(URL); extractor.fetchPage(); } - @Test - public void testGetDescription() throws ParsingException { - assertNotNull(extractor.getDescription()); - assertFalse(extractor.getDescription().getContent().isEmpty()); - } + @Override public StreamExtractor extractor() { return extractor; } + @Override public StreamingService expectedService() { return YouTube; } + @Override public String expectedName() { return "This Smartphone Changes Everything..."; } + @Override public String expectedId() { return ID; } + @Override public String expectedUrlContains() { return URL; } + @Override public String expectedOriginalUrlContains() { return URL; } - @Test - public void testGetFullLinksInDescription() throws ParsingException { - final String description = extractor.getDescription().getContent(); - assertTrue(description.contains("https://www.youtube.com/watch?v=X7FLCHVXpsA&list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34")); - assertTrue(description.contains("https://www.youtube.com/watch?v=Lqv6G0pDNnw&list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34")); - assertTrue(description.contains("https://www.youtube.com/watch?v=XxaRBPyrnBU&list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34")); - assertTrue(description.contains("https://www.youtube.com/watch?v=U-9tUEOFKNU&list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34")); + @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; } + @Override public String expectedUploaderName() { return "Unbox Therapy"; } + @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCsTcErHg8oDvUnTzoqsYeNw"; } + @Override public List expectedDescriptionContains() { + return Arrays.asList("https://www.youtube.com/watch?v=X7FLCHVXpsA&list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34", + "https://www.youtube.com/watch?v=Lqv6G0pDNnw&list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34", + "https://www.youtube.com/watch?v=XxaRBPyrnBU&list=PL7u4lWXQ3wfI_7PgX0C-VTiwLeu0S4v34", + "https://www.youtube.com/watch?v=U-9tUEOFKNU&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 { - private static YoutubeStreamExtractor extractor; + public static class RatingsDisabledTest extends DefaultStreamExtractorTest { + 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 public static void setUp() throws Exception { NewPipe.init(DownloaderTestImpl.getInstance()); - extractor = (YoutubeStreamExtractor) YouTube - .getStreamExtractor("https://www.youtube.com/watch?v=HRKu0cvrr_o"); + extractor = YouTube.getStreamExtractor(URL); extractor.fetchPage(); } - @Test - public void testGetLikeCount() throws ParsingException { - assertEquals(-1, extractor.getLikeCount()); - } + @Override public StreamExtractor extractor() { return extractor; } + @Override public StreamingService expectedService() { return YouTube; } + @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 - public void testGetDislikeCount() throws ParsingException { - assertEquals(-1, extractor.getDislikeCount()); - } - - } - - public static class FramesTest { - private static YoutubeStreamExtractor extractor; - - @BeforeClass - 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 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); - } - } - } + @Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; } + @Override public String expectedUploaderName() { return "YouTuber PrinceOfFALLEN"; } + @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCQT2yul0lr6Ie9qNQNmw-sg"; } + @Override public List 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; } + @Nullable @Override public String expectedUploadDate() { return "2019-01-02 00:00:00.000"; } + @Nullable @Override public String expectedTextualUploadDate() { return "2019-01-02"; } + @Override public long expectedLikeCountAtLeast() { return -1; } + @Override public long expectedDislikeCountAtLeast() { return -1; } } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorLivestreamTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorLivestreamTest.java index 0e17fe8d8..c1c84ed4b 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorLivestreamTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorLivestreamTest.java @@ -1,139 +1,55 @@ package org.schabi.newpipe.extractor.services.youtube.stream; import org.junit.BeforeClass; -import org.junit.Test; import org.schabi.newpipe.DownloaderTestImpl; -import org.schabi.newpipe.extractor.MediaFormat; 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.youtube.extractors.YoutubeStreamExtractor; -import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest; +import org.schabi.newpipe.extractor.stream.StreamExtractor; 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 static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl; +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Nullable; + import static org.schabi.newpipe.extractor.ServiceList.YouTube; -public class YoutubeStreamExtractorLivestreamTest { - private static YoutubeStreamExtractor extractor; +public class YoutubeStreamExtractorLivestreamTest extends DefaultStreamExtractorTest { + 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 public static void setUp() throws Exception { NewPipe.init(DownloaderTestImpl.getInstance()); - extractor = (YoutubeStreamExtractor) YouTube - .getStreamExtractor("https://www.youtube.com/watch?v=5qap5aO4i9A"); + extractor = YouTube.getStreamExtractor(URL); extractor.fetchPage(); } - @Test - public void testGetInvalidTimeStamp() throws ParsingException { - assertTrue(extractor.getTimeStamp() + "", - extractor.getTimeStamp() <= 0); - } + @Override public StreamExtractor extractor() { return extractor; } + @Override public StreamingService expectedService() { return YouTube; } + @Override public String expectedName() { return "lofi hip hop radio - beats to relax/study to"; } + @Override public String expectedId() { return ID; } + @Override public String expectedUrlContains() { return YoutubeStreamExtractorDefaultTest.BASE_URL + ID; } + @Override public String expectedOriginalUrlContains() { return URL; } - @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("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 StreamType expectedStreamType() { return StreamType.LIVE_STREAM; } + @Override public String expectedUploaderName() { return "ChilledCow"; } + @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow"; } + @Override public List expectedDescriptionContains() { + return Arrays.asList("https://bit.ly/chilledcow-playlists", + "https://bit.ly/chilledcow-submissions"); } + @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; } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorUnlistedTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorUnlistedTest.java index 49a851f4f..22b537ddd 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorUnlistedTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorUnlistedTest.java @@ -1,161 +1,50 @@ package org.schabi.newpipe.extractor.services.youtube.stream; -import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Test; import org.schabi.newpipe.DownloaderTestImpl; -import org.schabi.newpipe.extractor.MediaFormat; 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.youtube.extractors.YoutubeStreamExtractor; -import org.schabi.newpipe.extractor.stream.AudioStream; -import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest; +import org.schabi.newpipe.extractor.stream.StreamExtractor; 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.text.SimpleDateFormat; -import java.util.Calendar; +import java.util.Arrays; import java.util.List; -import static org.junit.Assert.*; -import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl; +import javax.annotation.Nullable; + import static org.schabi.newpipe.extractor.ServiceList.YouTube; -public class YoutubeStreamExtractorUnlistedTest { - private static YoutubeStreamExtractor extractor; +public class YoutubeStreamExtractorUnlistedTest extends DefaultStreamExtractorTest { + static final String ID = "udsB8KnIJTg"; + static final String URL = YoutubeStreamExtractorDefaultTest.BASE_URL + ID; + private static StreamExtractor extractor; @BeforeClass public static void setUp() throws Exception { NewPipe.init(DownloaderTestImpl.getInstance()); - extractor = (YoutubeStreamExtractor) YouTube - .getStreamExtractor("https://www.youtube.com/watch?v=udsB8KnIJTg"); + extractor = YouTube.getStreamExtractor(URL); extractor.fetchPage(); } - @Test - public void testGetInvalidTimeStamp() throws ParsingException { - assertTrue(extractor.getTimeStamp() + "", - extractor.getTimeStamp() <= 0); - } + @Override public StreamExtractor extractor() { return extractor; } + @Override public StreamingService expectedService() { return YouTube; } + @Override public String expectedName() { return "Praise the Casual: Ein Neuling trifft Dark Souls - Folge 5"; } + @Override public String expectedId() { return ID; } + @Override public String expectedUrlContains() { return URL; } + @Override public String expectedOriginalUrlContains() { return URL; } - @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("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 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 StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; } + @Override public String expectedUploaderName() { return "Hooked"; } + @Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCPysfiuOv4VKBeXFFPhKXyw"; } + @Override public List expectedDescriptionContains() { + return Arrays.asList("https://www.youtube.com/user/Roccowschiptune", + "https://www.facebook.com/HookedMagazinDE"); } + @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; } }