feat: WeatherAPI tests
This commit is contained in:
parent
52e63be79c
commit
e62635c057
@ -19,7 +19,7 @@ import java.util.Locale;
|
|||||||
*/
|
*/
|
||||||
public class WeatherAPI implements WeatherDataAPI{
|
public class WeatherAPI implements WeatherDataAPI{
|
||||||
private final String weatherAPIKey;
|
private final String weatherAPIKey;
|
||||||
private static final JSONFetcherInterface JSONFetcher = new JSONFetcher();
|
JSONFetcherInterface JSONFetcher = new JSONFetcher();
|
||||||
private static final String forecastBaseURL = "https://api.weatherapi.com/v1/forecast.json";
|
private static final String forecastBaseURL = "https://api.weatherapi.com/v1/forecast.json";
|
||||||
|
|
||||||
WeatherAPI(String weatherAPIKey) {
|
WeatherAPI(String weatherAPIKey) {
|
||||||
|
43
src/test/java/eirb/pg203/FakeJSONFetcherWeatherAPI.java
Normal file
43
src/test/java/eirb/pg203/FakeJSONFetcherWeatherAPI.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package eirb.pg203;
|
||||||
|
|
||||||
|
import eirb.pg203.utils.FileResourcesUtils;
|
||||||
|
import eirb.pg203.utils.JSONFetcherInterface;
|
||||||
|
import eirb.pg203.utils.SplitQueryUrl;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class FakeJSONFetcherWeatherAPI implements JSONFetcherInterface {
|
||||||
|
private final static String baseUrlFormat = "https://api.weatherapi.com/v1/forecast.json?key=%s&q=%s&days=%d";
|
||||||
|
private final String apiKey = "realKey";
|
||||||
|
private static final JSONObject wrongKeyRequest = FileResourcesUtils.getFileFromResourceAsJson("WeatherAPI/wrong-apikey.json");
|
||||||
|
private static ArrayList<JSONObject> bordeauxRequests() {
|
||||||
|
ArrayList<JSONObject> bordeauxRequest = new ArrayList<>();
|
||||||
|
bordeauxRequest.add(FileResourcesUtils.getFileFromResourceAsJson("WeatherAPI/Bordeaux-1-partial.json"));
|
||||||
|
bordeauxRequest.add(FileResourcesUtils.getFileFromResourceAsJson("WeatherAPI/Bordeaux-2-partial-sunny.json"));
|
||||||
|
bordeauxRequest.add(FileResourcesUtils.getFileFromResourceAsJson("WeatherAPI/Bordeaux-3-partial-sunny-rain.json"));
|
||||||
|
bordeauxRequest.add(FileResourcesUtils.getFileFromResourceAsJson("WeatherAPI/Bordeaux-4-partial-sunny-rain-cloudy.json"));
|
||||||
|
return bordeauxRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject fetch(URL url) throws IOException {
|
||||||
|
Map<String, String> params = SplitQueryUrl.splitQuery(url);
|
||||||
|
int days = Integer.parseInt(params.get("days"));
|
||||||
|
|
||||||
|
if (!params.get("key").contentEquals(apiKey))
|
||||||
|
return wrongKeyRequest;
|
||||||
|
|
||||||
|
return bordeauxRequests().get(days - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONArray fetchArray(URL url) throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -2,70 +2,100 @@ package eirb.pg203;
|
|||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class WeatherAPITest {
|
public class WeatherAPITest {
|
||||||
private static String APIKey = "cef8e1b6ea364994b5072423240111";
|
private static final String APIKey = "realKey";
|
||||||
|
private static final float epsilon = 0.01F;
|
||||||
|
private WeatherAPI weatherAPI;
|
||||||
|
|
||||||
@Test
|
@BeforeEach
|
||||||
public void testRightAPIKey() {
|
public void setupWeatherApi() {
|
||||||
WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey);
|
this.weatherAPI = new WeatherAPI(WeatherAPITest.APIKey);
|
||||||
int day = 0;
|
this.weatherAPI.JSONFetcher = new FakeJSONFetcherWeatherAPI();
|
||||||
// int hour = 10;
|
}
|
||||||
int days = 7;
|
|
||||||
String city = "Bordeaux";
|
|
||||||
|
|
||||||
Assertions.assertAll(
|
/**
|
||||||
() -> weatherAPI.getTemperature(day, city),
|
* List of args for Temperature testing
|
||||||
// () -> weatherAPI.getTemperature(day, hour, city),
|
* @return Args for testing
|
||||||
() -> weatherAPI.getTemperatures(days, city)
|
*/
|
||||||
|
private static Stream<Arguments> testGetTemperature(){
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.arguments(0, 8.1F,WeatherData.Condition.PARTIAL, 17.45F, 142.08F),
|
||||||
|
Arguments.arguments(1, 13F, WeatherData.Condition.SUNNY, 23.03F, 142.58F),
|
||||||
|
Arguments.arguments(2, 12.7F, WeatherData.Condition.RAINY, 13.19F, 222.92F),
|
||||||
|
Arguments.arguments(3, 8.1F,WeatherData.Condition.CLOUDY, 17.45F, 142.08F)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest(name="Temperature fetch at Bordeaux D+{0}")
|
||||||
public void testWrongAPIKey() {
|
@MethodSource
|
||||||
WeatherAPI weatherAPI = new WeatherAPI("");
|
public void testGetTemperature(int day, float expectedTemp, WeatherData.Condition expectedCond, float expectedWindSpeed, float expectedWindAngle) throws IOException {
|
||||||
int day = 0;
|
|
||||||
// int hour = 10;
|
|
||||||
int days = 7;
|
|
||||||
String city = "Bordeaux";
|
String city = "Bordeaux";
|
||||||
|
WeatherData weatherData;
|
||||||
|
weatherData = weatherAPI.getTemperature(day, city);
|
||||||
|
|
||||||
Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperature(day, city));
|
/* Temperatures */
|
||||||
Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperatures(days, city));
|
Assertions.assertEquals(expectedTemp, weatherData.getTemp());
|
||||||
|
/* Condition */
|
||||||
|
Assertions.assertEquals(expectedCond, weatherData.getCondition());
|
||||||
|
/* Wind */
|
||||||
|
Assertions.assertTrue(expectedWindSpeed - weatherData.getWindSpeed() < epsilon);
|
||||||
|
Assertions.assertTrue(expectedWindAngle - weatherData.getWindDirectionAngle() < epsilon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For coverage (hour not yet implemented)
|
||||||
|
* @throws IOException never
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWrongDay() {
|
public void testGetTemperatureByHour() throws IOException {
|
||||||
WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey);
|
|
||||||
String city = "Bordeaux";
|
String city = "Bordeaux";
|
||||||
|
|
||||||
Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperature(-1, city));
|
|
||||||
Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperature(15, city));
|
|
||||||
Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperatures(15, city));
|
|
||||||
Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperatures(-1, city));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRightDay() {
|
|
||||||
WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey);
|
|
||||||
String city = "Bordeaux";
|
|
||||||
|
|
||||||
Assertions.assertAll(
|
Assertions.assertAll(
|
||||||
() -> weatherAPI.getTemperature(0, city),
|
() -> weatherAPI.getTemperature(0,1, city)
|
||||||
() -> weatherAPI.getTemperature(5, city),
|
|
||||||
() -> weatherAPI.getTemperature(14, city),
|
|
||||||
() -> weatherAPI.getTemperatures(0, city),
|
|
||||||
() -> weatherAPI.getTemperatures(8, city),
|
|
||||||
() -> weatherAPI.getTemperatures(14, city)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Multiple day temperature fetch")
|
||||||
|
public void testGetTemperatures() throws IOException {
|
||||||
|
String city = "Bordeaux";
|
||||||
|
int days = 3;
|
||||||
|
float[] expectedTemperatures = {8.1F, 13F, 12.7F, 8.1F};
|
||||||
|
WeatherData.Condition[] expectedConditions = {WeatherData.Condition.PARTIAL, WeatherData.Condition.SUNNY, WeatherData.Condition.RAINY, WeatherData.Condition.CLOUDY};
|
||||||
|
float[] expectedWindSpeed = {17.45F, 23.03F, 13.19F, 17.45F};
|
||||||
|
float[] expectedWindDirection = {142.08F, 142.58F, 222.92F, 142.08F};
|
||||||
|
|
||||||
|
ArrayList<WeatherData> weatherDatas;
|
||||||
|
WeatherData weatherData;
|
||||||
|
weatherDatas = weatherAPI.getTemperatures(days, city);
|
||||||
|
|
||||||
|
for (int index = 0; index < days; index++) {
|
||||||
|
weatherData = weatherDatas.get(index);
|
||||||
|
|
||||||
|
|
||||||
|
/* Temperatures */
|
||||||
|
Assertions.assertEquals(expectedTemperatures[index], weatherData.getTemp());
|
||||||
|
/* Weather condition */
|
||||||
|
Assertions.assertEquals(expectedConditions[index], weatherData.getCondition());
|
||||||
|
/* Wind */
|
||||||
|
Assertions.assertTrue(expectedWindSpeed[index] - weatherData.getWindSpeed() < epsilon);
|
||||||
|
Assertions.assertTrue(expectedWindDirection[index] - weatherData.getWindDirectionAngle() < epsilon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAPIName() {
|
public void testGetAPIName() {
|
||||||
WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey);
|
Assertions.assertEquals("WeatherAPI", weatherAPI.getAPIName());
|
||||||
Assertions.assertTrue(weatherAPI.getAPIName().equals("WeatherAPI"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
53
src/test/java/eirb/pg203/utils/FileResourcesUtils.java
Normal file
53
src/test/java/eirb/pg203/utils/FileResourcesUtils.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package eirb.pg203.utils;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
public class FileResourcesUtils {
|
||||||
|
/**
|
||||||
|
* Fetch ressource file
|
||||||
|
* Code from https://mkyong.com
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static InputStream getFileFromResourceAsStream(String fileName) {
|
||||||
|
|
||||||
|
// The class loader that loaded the class
|
||||||
|
ClassLoader classLoader = FileResourcesUtils.class.getClassLoader();
|
||||||
|
InputStream inputStream = classLoader.getResourceAsStream(fileName);
|
||||||
|
|
||||||
|
// the stream holding the file content
|
||||||
|
if (inputStream == null) {
|
||||||
|
throw new IllegalArgumentException("file not found! " + fileName);
|
||||||
|
} else {
|
||||||
|
return inputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject getFileFromResourceAsJson(String fileName) {
|
||||||
|
InputStream inputStream = getFileFromResourceAsStream(fileName);
|
||||||
|
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while(true){
|
||||||
|
try {
|
||||||
|
if (!bufferedReader.ready()) break;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
line = bufferedReader.readLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
stringBuilder.append(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JSONObject(stringBuilder.toString());
|
||||||
|
}
|
||||||
|
}
|
20
src/test/java/eirb/pg203/utils/SplitQueryUrl.java
Normal file
20
src/test/java/eirb/pg203/utils/SplitQueryUrl.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package eirb.pg203.utils;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SplitQueryUrl {
|
||||||
|
public static Map<String, String> splitQuery(URL url) throws UnsupportedEncodingException {
|
||||||
|
Map<String, String> query_pairs = new LinkedHashMap<String, String>();
|
||||||
|
String query = url.getQuery();
|
||||||
|
String[] pairs = query.split("&");
|
||||||
|
for (String pair : pairs) {
|
||||||
|
int idx = pair.indexOf("=");
|
||||||
|
query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
|
||||||
|
}
|
||||||
|
return query_pairs;
|
||||||
|
}
|
||||||
|
}
|
3057
src/test/resources/WeatherAPI/Bordeaux-1-partial.json
Normal file
3057
src/test/resources/WeatherAPI/Bordeaux-1-partial.json
Normal file
File diff suppressed because it is too large
Load Diff
3057
src/test/resources/WeatherAPI/Bordeaux-2-partial-sunny.json
Normal file
3057
src/test/resources/WeatherAPI/Bordeaux-2-partial-sunny.json
Normal file
File diff suppressed because it is too large
Load Diff
3057
src/test/resources/WeatherAPI/Bordeaux-3-partial-sunny-rain.json
Normal file
3057
src/test/resources/WeatherAPI/Bordeaux-3-partial-sunny-rain.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
6
src/test/resources/WeatherAPI/wrong-apikey.json
Normal file
6
src/test/resources/WeatherAPI/wrong-apikey.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"error": {
|
||||||
|
"code": 2008,
|
||||||
|
"message": "API key has been disabled."
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user