From 7c40fb8bf70d225e553c7b0095d3929ade57fe65 Mon Sep 17 00:00:00 2001 From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com> Date: Tue, 15 Dec 2020 15:14:07 +0100 Subject: [PATCH] Add additional downloader implementations RecordingDownloader relies on the real downloader and saves the request/response pair into a json file. MockDownloader uses json files from above and mocks responses for specific requests. --- extractor/build.gradle | 2 + .../newpipe/downloader/MockDownloader.java | 55 +++++++++++++++++++ .../downloader/RecordingDownloader.java | 53 ++++++++++++++++++ .../downloader/TestRequestResponse.java | 28 ++++++++++ 4 files changed, 138 insertions(+) create mode 100644 extractor/src/test/java/org/schabi/newpipe/downloader/MockDownloader.java create mode 100644 extractor/src/test/java/org/schabi/newpipe/downloader/RecordingDownloader.java create mode 100644 extractor/src/test/java/org/schabi/newpipe/downloader/TestRequestResponse.java diff --git a/extractor/build.gradle b/extractor/build.gradle index c10d39ea0..1b5b82ffc 100644 --- a/extractor/build.gradle +++ b/extractor/build.gradle @@ -9,4 +9,6 @@ dependencies { testImplementation 'junit:junit:4.13.1' testImplementation "com.squareup.okhttp3:okhttp:3.12.11" + testImplementation 'com.google.code.gson:gson:2.8.6' + testImplementation 'commons-io:commons-io:2.8.0' } diff --git a/extractor/src/test/java/org/schabi/newpipe/downloader/MockDownloader.java b/extractor/src/test/java/org/schabi/newpipe/downloader/MockDownloader.java new file mode 100644 index 000000000..b15c949c0 --- /dev/null +++ b/extractor/src/test/java/org/schabi/newpipe/downloader/MockDownloader.java @@ -0,0 +1,55 @@ +package org.schabi.newpipe.downloader; + +import com.google.gson.GsonBuilder; + +import org.schabi.newpipe.extractor.downloader.Downloader; +import org.schabi.newpipe.extractor.downloader.Request; +import org.schabi.newpipe.extractor.downloader.Response; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Nonnull; + +class MockDownloader extends Downloader { + + private final String path; + private final Map mocks; + + public MockDownloader(@Nonnull String path) throws IOException { + this.path = path; + this.mocks = new HashMap<>(); + File folder = new File(path); + for (File file : folder.listFiles()) { + final FileReader reader = new FileReader(file); + final TestRequestResponse response = new GsonBuilder() + .create() + .fromJson(reader, TestRequestResponse.class); + reader.close(); + mocks.put(response.getRequest(), response.getResponse()); + } + + //shared find proper solution + File clientVersion = new File("src/test/resources/org/schabi/newpipe/extractor/services/youtube/client_version.json"); + final FileReader reader = new FileReader(clientVersion); + final TestRequestResponse response = new GsonBuilder() + .create() + .fromJson(reader, TestRequestResponse.class); + reader.close(); + mocks.put(response.getRequest(), response.getResponse()); + } + + @Override + public Response execute(@Nonnull Request request) { + Response result = mocks.get(request); + if (result == null) { + throw new NullPointerException("No mock response for request with url '" + request.url() + + "' exists in path '" + path + "'.\nPlease make sure to run the tests with " + + "the RecordingDownloader first after changes."); + } + return result; + } +} diff --git a/extractor/src/test/java/org/schabi/newpipe/downloader/RecordingDownloader.java b/extractor/src/test/java/org/schabi/newpipe/downloader/RecordingDownloader.java new file mode 100644 index 000000000..b836b8452 --- /dev/null +++ b/extractor/src/test/java/org/schabi/newpipe/downloader/RecordingDownloader.java @@ -0,0 +1,53 @@ +package org.schabi.newpipe.downloader; + +import com.google.gson.GsonBuilder; + +import org.apache.commons.io.FileUtils; +import org.schabi.newpipe.extractor.downloader.Downloader; +import org.schabi.newpipe.extractor.downloader.Request; +import org.schabi.newpipe.extractor.downloader.Response; +import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import javax.annotation.Nonnull; + +class RecordingDownloader extends Downloader { + + private int index = 0; + private final String path; + + public RecordingDownloader(String stringPath) throws IOException { + this.path = stringPath; + Path path = Paths.get(stringPath); + File directory = path.toFile(); + if (directory.exists()) { + FileUtils.cleanDirectory(directory); + } + Files.createDirectories(path); + } + + @Override + public Response execute(@Nonnull Request request) throws IOException, ReCaptchaException { + Downloader downloader = DownloaderTestImpl.getInstance(); + Response response = downloader.execute(request); + + File outputFile = new File(path + File.separator + index + ".json"); + index++; + outputFile.createNewFile(); + FileWriter writer = new FileWriter(outputFile); + new GsonBuilder() + .setPrettyPrinting() + .create() + .toJson(new TestRequestResponse(request, response), writer); + writer.flush(); + writer.close(); + + return response; + } +} diff --git a/extractor/src/test/java/org/schabi/newpipe/downloader/TestRequestResponse.java b/extractor/src/test/java/org/schabi/newpipe/downloader/TestRequestResponse.java new file mode 100644 index 000000000..81f8843d8 --- /dev/null +++ b/extractor/src/test/java/org/schabi/newpipe/downloader/TestRequestResponse.java @@ -0,0 +1,28 @@ +package org.schabi.newpipe.downloader; + +import org.schabi.newpipe.extractor.downloader.Request; +import org.schabi.newpipe.extractor.downloader.Response; + +final class TestRequestResponse { + private final String comment; + private final Request request; + private final Response response; + + public TestRequestResponse(Request request, Response response) { + this.comment = "Auto-generated for tests. See RecordingDownloader"; + this.request = request; + this.response = response; + } + + public String getComment() { + return comment; + } + + public Request getRequest() { + return request; + } + + public Response getResponse() { + return response; + } +}