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{
|
||||
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";
|
||||
|
||||
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.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.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
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
|
||||
public void testRightAPIKey() {
|
||||
WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey);
|
||||
int day = 0;
|
||||
// int hour = 10;
|
||||
int days = 7;
|
||||
String city = "Bordeaux";
|
||||
@BeforeEach
|
||||
public void setupWeatherApi() {
|
||||
this.weatherAPI = new WeatherAPI(WeatherAPITest.APIKey);
|
||||
this.weatherAPI.JSONFetcher = new FakeJSONFetcherWeatherAPI();
|
||||
}
|
||||
|
||||
Assertions.assertAll(
|
||||
() -> weatherAPI.getTemperature(day, city),
|
||||
// () -> weatherAPI.getTemperature(day, hour, city),
|
||||
() -> weatherAPI.getTemperatures(days, city)
|
||||
/**
|
||||
* List of args for Temperature testing
|
||||
* @return Args for testing
|
||||
*/
|
||||
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
|
||||
public void testWrongAPIKey() {
|
||||
WeatherAPI weatherAPI = new WeatherAPI("");
|
||||
int day = 0;
|
||||
// int hour = 10;
|
||||
int days = 7;
|
||||
@ParameterizedTest(name="Temperature fetch at Bordeaux D+{0}")
|
||||
@MethodSource
|
||||
public void testGetTemperature(int day, float expectedTemp, WeatherData.Condition expectedCond, float expectedWindSpeed, float expectedWindAngle) throws IOException {
|
||||
String city = "Bordeaux";
|
||||
WeatherData weatherData;
|
||||
weatherData = weatherAPI.getTemperature(day, city);
|
||||
|
||||
Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperature(day, city));
|
||||
Assertions.assertThrows(IOException.class, () -> weatherAPI.getTemperatures(days, city));
|
||||
/* Temperatures */
|
||||
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
|
||||
public void testWrongDay() {
|
||||
WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey);
|
||||
public void testGetTemperatureByHour() throws IOException {
|
||||
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(
|
||||
() -> weatherAPI.getTemperature(0, city),
|
||||
() -> weatherAPI.getTemperature(5, city),
|
||||
() -> weatherAPI.getTemperature(14, city),
|
||||
() -> weatherAPI.getTemperatures(0, city),
|
||||
() -> weatherAPI.getTemperatures(8, city),
|
||||
() -> weatherAPI.getTemperatures(14, city)
|
||||
() -> weatherAPI.getTemperature(0,1, 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
|
||||
public void testGetAPIName() {
|
||||
WeatherAPI weatherAPI = new WeatherAPI(WeatherAPITest.APIKey);
|
||||
Assertions.assertTrue(weatherAPI.getAPIName().equals("WeatherAPI"));
|
||||
Assertions.assertEquals("WeatherAPI", weatherAPI.getAPIName());
|
||||
}
|
||||
|
||||
}
|
||||
|
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