Skip to content

Commit c2c4d97

Browse files
authored
Merge pull request #482 from XiangRongLin/mock_mix_pl_test
Mock mix pl tests
2 parents 951159f + 4f81d9d commit c2c4d97

89 files changed

Lines changed: 2192 additions & 69 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

extractor/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ dependencies {
99

1010
testImplementation 'junit:junit:4.13.1'
1111
testImplementation "com.squareup.okhttp3:okhttp:3.12.11"
12+
testImplementation 'com.google.code.gson:gson:2.8.6'
1213
}

extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Request.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,4 +241,27 @@ public static Map<String, List<String>> headersFromLocalization(@Nullable Locali
241241

242242
return headers;
243243
}
244+
245+
/*//////////////////////////////////////////////////////////////////////////
246+
// Generated
247+
//////////////////////////////////////////////////////////////////////////*/
248+
249+
@Override
250+
public boolean equals(Object o) {
251+
if (this == o) return true;
252+
if (o == null || getClass() != o.getClass()) return false;
253+
Request request = (Request) o;
254+
return httpMethod.equals(request.httpMethod) &&
255+
url.equals(request.url) &&
256+
headers.equals(request.headers) &&
257+
Arrays.equals(dataToSend, request.dataToSend) &&
258+
Objects.equals(localization, request.localization);
259+
}
260+
261+
@Override
262+
public int hashCode() {
263+
int result = Objects.hash(httpMethod, url, headers, localization);
264+
result = 31 * result + Arrays.hashCode(dataToSend);
265+
return result;
266+
}
244267
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,16 @@ public static String getKey() throws IOException, ExtractionException {
353353
return key;
354354
}
355355

356+
/**
357+
* Only use in tests.
358+
*
359+
* Quick-and-dirty solution to reset global state in between test classes.
360+
*/
361+
static void resetClientVersionAndKey() {
362+
clientVersion = null;
363+
key = null;
364+
}
365+
356366
public static boolean areHardcodedYoutubeMusicKeysValid() throws IOException, ReCaptchaException {
357367
final String url = "https://music.youtube.com/youtubei/v1/search?alt=json&key=" + HARDCODED_YOUTUBE_MUSIC_KEYS[0];
358368

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.schabi.newpipe.downloader;
2+
3+
import org.schabi.newpipe.extractor.downloader.Downloader;
4+
5+
import java.io.IOException;
6+
7+
public class DownloaderFactory {
8+
9+
public final static String RESOURCE_PATH = "src/test/resources/org/schabi/newpipe/extractor/";
10+
11+
private final static DownloaderType DEFAULT_DOWNLOADER = DownloaderType.REAL;
12+
13+
/**
14+
* <p>
15+
* Returns a implementation of a {@link Downloader}.
16+
* </p>
17+
* <p>
18+
* If the system property "downloader" is set and is one of {@link DownloaderType},
19+
* then a downloader of that type is returned.
20+
* It can be passed in with gradle by adding the argument -Ddownloader=abcd,
21+
* where abcd is one of {@link DownloaderType}
22+
* </p>
23+
* <p>
24+
* Otherwise it falls back to {@link DownloaderFactory#DEFAULT_DOWNLOADER}.
25+
* Change this during development on the local machine to use a different downloader.
26+
* </p>
27+
*
28+
* @param path The path to the folder where mocks are saved/retrieved.
29+
* Preferably starting with {@link DownloaderFactory#RESOURCE_PATH}
30+
*/
31+
public Downloader getDownloader(String path) throws IOException {
32+
DownloaderType type;
33+
try {
34+
type = DownloaderType.valueOf(System.getProperty("downloader"));
35+
} catch (Exception e) {
36+
type = DEFAULT_DOWNLOADER;
37+
}
38+
39+
switch (type) {
40+
case REAL:
41+
return DownloaderTestImpl.getInstance();
42+
case MOCK:
43+
return new MockDownloader(path);
44+
case RECORDING:
45+
return new RecordingDownloader(path);
46+
default:
47+
throw new UnsupportedOperationException("Unknown downloader type: " + type.toString());
48+
}
49+
}
50+
}

extractor/src/test/java/org/schabi/newpipe/DownloaderTestImpl.java renamed to extractor/src/test/java/org/schabi/newpipe/downloader/DownloaderTestImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.schabi.newpipe;
1+
package org.schabi.newpipe.downloader;
22

33
import org.schabi.newpipe.extractor.downloader.Downloader;
44
import org.schabi.newpipe.extractor.downloader.Request;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.schabi.newpipe.downloader;
2+
3+
public enum DownloaderType {
4+
REAL, MOCK, RECORDING
5+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.schabi.newpipe.downloader;
2+
3+
import com.google.gson.GsonBuilder;
4+
5+
import org.schabi.newpipe.extractor.downloader.Downloader;
6+
import org.schabi.newpipe.extractor.downloader.Request;
7+
import org.schabi.newpipe.extractor.downloader.Response;
8+
9+
import java.io.File;
10+
import java.io.FileReader;
11+
import java.io.IOException;
12+
import java.util.HashMap;
13+
import java.util.Map;
14+
15+
import javax.annotation.Nonnull;
16+
17+
/**
18+
* <p>
19+
* Mocks requests by using json files created by {@link RecordingDownloader}
20+
* </p>
21+
*/
22+
class MockDownloader extends Downloader {
23+
24+
private final String path;
25+
private final Map<Request, Response> mocks;
26+
27+
public MockDownloader(@Nonnull String path) throws IOException {
28+
this.path = path;
29+
this.mocks = new HashMap<>();
30+
File folder = new File(path);
31+
for (File file : folder.listFiles()) {
32+
if (file.getName().startsWith(RecordingDownloader.FILE_NAME_PREFIX)) {
33+
final FileReader reader = new FileReader(file);
34+
final TestRequestResponse response = new GsonBuilder()
35+
.create()
36+
.fromJson(reader, TestRequestResponse.class);
37+
reader.close();
38+
mocks.put(response.getRequest(), response.getResponse());
39+
}
40+
}
41+
}
42+
43+
@Override
44+
public Response execute(@Nonnull Request request) {
45+
Response result = mocks.get(request);
46+
if (result == null) {
47+
throw new NullPointerException("No mock response for request with url '" + request.url()
48+
+ "' exists in path '" + path + "'.\nPlease make sure to run the tests with " +
49+
"the RecordingDownloader first after changes.");
50+
}
51+
return result;
52+
}
53+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package org.schabi.newpipe.downloader;
2+
3+
import com.google.gson.GsonBuilder;
4+
5+
import org.schabi.newpipe.extractor.downloader.Downloader;
6+
import org.schabi.newpipe.extractor.downloader.Request;
7+
import org.schabi.newpipe.extractor.downloader.Response;
8+
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
9+
10+
import java.io.File;
11+
import java.io.FileWriter;
12+
import java.io.IOException;
13+
import java.nio.file.Files;
14+
import java.nio.file.Path;
15+
import java.nio.file.Paths;
16+
17+
import javax.annotation.Nonnull;
18+
19+
/**
20+
* <p>
21+
* Relays requests to {@link DownloaderTestImpl} and saves the request/response pair into a json file.
22+
* </p>
23+
* <p>
24+
* Those files are used by {@link MockDownloader}.
25+
* </p>
26+
* <p>
27+
* The files <b>must</b> be created on the local dev environment
28+
* and recreated when the requests made by a test class change.
29+
* </p>
30+
*/
31+
class RecordingDownloader extends Downloader {
32+
33+
public final static String FILE_NAME_PREFIX = "generated_mock_";
34+
35+
private int index = 0;
36+
private final String path;
37+
38+
/**
39+
* Creates the folder described by {@code stringPath} if it does not exists.
40+
* Deletes existing files starting with {@link RecordingDownloader#FILE_NAME_PREFIX}.
41+
* @param stringPath Path to the folder where the json files will be saved to.
42+
*/
43+
public RecordingDownloader(String stringPath) throws IOException {
44+
this.path = stringPath;
45+
Path path = Paths.get(stringPath);
46+
File folder = path.toFile();
47+
if (folder.exists()) {
48+
for (File file : folder.listFiles()) {
49+
if (file.getName().startsWith(RecordingDownloader.FILE_NAME_PREFIX)) {
50+
file.delete();
51+
}
52+
}
53+
} else {
54+
Files.createDirectories(path);
55+
}
56+
}
57+
58+
@Override
59+
public Response execute(@Nonnull Request request) throws IOException, ReCaptchaException {
60+
Downloader downloader = DownloaderTestImpl.getInstance();
61+
Response response = downloader.execute(request);
62+
63+
File outputFile = new File(path + File.separator + FILE_NAME_PREFIX + index + ".json");
64+
index++;
65+
outputFile.createNewFile();
66+
FileWriter writer = new FileWriter(outputFile);
67+
new GsonBuilder()
68+
.setPrettyPrinting()
69+
.create()
70+
.toJson(new TestRequestResponse(request, response), writer);
71+
writer.flush();
72+
writer.close();
73+
74+
return response;
75+
}
76+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.schabi.newpipe.downloader;
2+
3+
import org.schabi.newpipe.extractor.downloader.Request;
4+
import org.schabi.newpipe.extractor.downloader.Response;
5+
6+
final class TestRequestResponse {
7+
private final Request request;
8+
private final Response response;
9+
10+
public TestRequestResponse(Request request, Response response) {
11+
this.request = request;
12+
this.response = response;
13+
}
14+
15+
public Request getRequest() {
16+
return request;
17+
}
18+
19+
public Response getResponse() {
20+
return response;
21+
}
22+
}

extractor/src/test/java/org/schabi/newpipe/extractor/services/media_ccc/MediaCCCConferenceExtractorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import org.junit.BeforeClass;
44
import org.junit.Test;
5-
import org.schabi.newpipe.DownloaderTestImpl;
5+
import org.schabi.newpipe.downloader.DownloaderTestImpl;
66
import org.schabi.newpipe.extractor.NewPipe;
77
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCConferenceExtractor;
88

0 commit comments

Comments
 (0)