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.
This commit is contained in:
XiangRongLin 2020-12-15 15:14:07 +01:00
parent 1bcb9c76a7
commit 7c40fb8bf7
4 changed files with 138 additions and 0 deletions

View File

@ -9,4 +9,6 @@ dependencies {
testImplementation 'junit:junit:4.13.1' testImplementation 'junit:junit:4.13.1'
testImplementation "com.squareup.okhttp3:okhttp:3.12.11" 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'
} }

View File

@ -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<Request, Response> 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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}