package org.schabi.newpipe.extractor.services.youtube.search; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.schabi.newpipe.extractor.ExtractorAsserts.assertEmptyErrors; import static org.schabi.newpipe.extractor.ServiceList.YouTube; import static org.schabi.newpipe.extractor.services.DefaultTests.assertNoDuplicatedItems; import static org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory.CHANNELS; import static org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory.PLAYLISTS; import static org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory.VIDEOS; import static java.util.Collections.singletonList; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.schabi.newpipe.downloader.DownloaderFactory; import org.schabi.newpipe.downloader.MockOnly; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.MetaInfo; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.search.SearchExtractor; import org.schabi.newpipe.extractor.services.DefaultSearchExtractorTest; import org.schabi.newpipe.extractor.services.youtube.YoutubeTestsUtils; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.util.Collections; import java.util.List; import javax.annotation.Nullable; public class YoutubeSearchExtractorTest { private static final String RESOURCE_PATH = DownloaderFactory.RESOURCE_PATH + "services/youtube/extractor/search/"; public static class All extends DefaultSearchExtractorTest { private static SearchExtractor extractor; private static final String QUERY = "test"; @BeforeAll public static void setUp() throws Exception { YoutubeTestsUtils.ensureStateless(); NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "all")); extractor = YouTube.getSearchExtractor(QUERY); extractor.fetchPage(); } @Override public SearchExtractor extractor() { return extractor; } @Override public StreamingService expectedService() { return YouTube; } @Override public String expectedName() { return QUERY; } @Override public String expectedId() { return QUERY; } @Override public String expectedUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedOriginalUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedSearchString() { return QUERY; } @Nullable @Override public String expectedSearchSuggestion() { return null; } } public static class Channel extends DefaultSearchExtractorTest { private static SearchExtractor extractor; private static final String QUERY = "test"; @BeforeAll public static void setUp() throws Exception { YoutubeTestsUtils.ensureStateless(); NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "channel")); extractor = YouTube.getSearchExtractor(QUERY, singletonList(CHANNELS), ""); extractor.fetchPage(); } @Override public SearchExtractor extractor() { return extractor; } @Override public StreamingService expectedService() { return YouTube; } @Override public String expectedName() { return QUERY; } @Override public String expectedId() { return QUERY; } @Override public String expectedUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedOriginalUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedSearchString() { return QUERY; } @Nullable @Override public String expectedSearchSuggestion() { return null; } @Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.CHANNEL; } } public static class Playlists extends DefaultSearchExtractorTest { private static SearchExtractor extractor; private static final String QUERY = "test"; @BeforeAll public static void setUp() throws Exception { YoutubeTestsUtils.ensureStateless(); NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "playlist")); extractor = YouTube.getSearchExtractor(QUERY, singletonList(PLAYLISTS), ""); extractor.fetchPage(); } @Override public SearchExtractor extractor() { return extractor; } @Override public StreamingService expectedService() { return YouTube; } @Override public String expectedName() { return QUERY; } @Override public String expectedId() { return QUERY; } @Override public String expectedUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedOriginalUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedSearchString() { return QUERY; } @Nullable @Override public String expectedSearchSuggestion() { return null; } @Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.PLAYLIST; } } public static class Videos extends DefaultSearchExtractorTest { private static SearchExtractor extractor; private static final String QUERY = "test"; @BeforeAll public static void setUp() throws Exception { YoutubeTestsUtils.ensureStateless(); NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "videos")); extractor = YouTube.getSearchExtractor(QUERY, singletonList(VIDEOS), ""); extractor.fetchPage(); } @Override public SearchExtractor extractor() { return extractor; } @Override public StreamingService expectedService() { return YouTube; } @Override public String expectedName() { return QUERY; } @Override public String expectedId() { return QUERY; } @Override public String expectedUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedOriginalUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedSearchString() { return QUERY; } @Nullable @Override public String expectedSearchSuggestion() { return null; } @Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; } } /** * Test for YT's "Did you mean...". *
* Hint: YT mostly shows "did you mean..." when you are searching in another language. *
*/ @MockOnly("Currently constantly switching between \"Did you mean\" and \"Showing results for ...\" occurs") public static class Suggestion extends DefaultSearchExtractorTest { private static SearchExtractor extractor; private static final String QUERY = "algorythm"; private static final String EXPECTED_SUGGESTION = "algorithm"; @BeforeAll public static void setUp() throws Exception { YoutubeTestsUtils.ensureStateless(); NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "suggestions")); extractor = YouTube.getSearchExtractor(QUERY, singletonList(VIDEOS), ""); extractor.fetchPage(); } @Override public SearchExtractor extractor() { return extractor; } @Override public StreamingService expectedService() { return YouTube; } @Override public String expectedName() { return QUERY; } @Override public String expectedId() { return QUERY; } @Override public String expectedUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedOriginalUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedSearchString() { return QUERY; } @Nullable @Override public String expectedSearchSuggestion() { return EXPECTED_SUGGESTION; } @Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; } } /** * Test for YT's "Showing results for...". */ public static class CorrectedSearch extends DefaultSearchExtractorTest { private static SearchExtractor extractor; private static final String QUERY = "pewdeipie"; private static final String EXPECTED_SUGGESTION = "pewdiepie"; @BeforeAll public static void setUp() throws Exception { YoutubeTestsUtils.ensureStateless(); NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "corrected")); extractor = YouTube.getSearchExtractor(QUERY, singletonList(VIDEOS), ""); extractor.fetchPage(); } @Override public SearchExtractor extractor() { return extractor; } @Override public StreamingService expectedService() { return YouTube; } @Override public String expectedName() { return QUERY; } @Override public String expectedId() { return QUERY; } @Override public String expectedUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedOriginalUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedSearchString() { return QUERY; } @Nullable @Override public String expectedSearchSuggestion() { return EXPECTED_SUGGESTION; } @Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; } @Override public boolean isCorrectedSearch() { return true; } } public static class RandomQueryNoMorePages extends DefaultSearchExtractorTest { private static SearchExtractor extractor; private static final String QUERY = "UCO6AK"; @BeforeAll public static void setUp() throws Exception { YoutubeTestsUtils.ensureStateless(); NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "random")); extractor = YouTube.getSearchExtractor(QUERY); extractor.fetchPage(); } @Override public SearchExtractor extractor() { return extractor; } @Override public StreamingService expectedService() { return YouTube; } @Override public String expectedName() { return QUERY; } @Override public String expectedId() { return QUERY; } @Override public String expectedUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedOriginalUrlContains() { return "youtube.com/results?search_query=" + QUERY; } @Override public String expectedSearchString() { return QUERY; } @Nullable @Override public String expectedSearchSuggestion() { return null; } /*////////////////////////////////////////////////////////////////////////// // Test Overrides //////////////////////////////////////////////////////////////////////////*/ @Test public void testMoreRelatedItems() throws Exception { final ListExtractor.InfoItemsPage