feat: OpenWeatherMap tests
This commit is contained in:
parent
423e1a44f3
commit
68abfe66fa
@ -9,6 +9,7 @@ import eirb.pg203.utils.JSONFetcher;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.time.Clock;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
@ -23,29 +24,29 @@ import eirb.pg203.WeatherData.Condition;
|
||||
public class OpenWeatherMap implements WeatherDataAPI {
|
||||
private static final String forecastBaseURL = "https://api.openweathermap.org/data/2.5/forecast";
|
||||
private String APIKey;
|
||||
private static final JSONFetcherInterface JSONFetcher = new JSONFetcher();
|
||||
Clock clock = Clock.systemUTC();
|
||||
JSONFetcherInterface JSONFetcher = new JSONFetcher();
|
||||
|
||||
OpenWeatherMap(String APIKey) {
|
||||
this.APIKey = APIKey;
|
||||
}
|
||||
|
||||
private JSONObject fetchWeather(int days, City city) throws IOException {
|
||||
private JSONObject fetchWeather(City city) throws IOException {
|
||||
URL url = URI.create(
|
||||
String.format(Locale.ENGLISH, forecastBaseURL + "?appid=%s&lat=%.2f&lon=%.2f&units=metric",
|
||||
APIKey,
|
||||
city.getCityCoords().getLat(),
|
||||
city.getCityCoords().getLon(),
|
||||
days
|
||||
city.getCityCoords().getLon()
|
||||
)
|
||||
).toURL();
|
||||
|
||||
return JSONFetcher.fetch(url);
|
||||
}
|
||||
|
||||
private static WeatherData getWeatherDataFromForecast(JSONObject response, int day, String city) {
|
||||
private WeatherData getWeatherDataFromForecast(JSONObject response, int day, String city) {
|
||||
JSONArray list = response.getJSONArray("list");
|
||||
|
||||
DayOfWeek targetedDay = Instant.now().plusSeconds(day * 24 * 3600).atZone(ZoneId.systemDefault()).getDayOfWeek();
|
||||
DayOfWeek targetedDay = Instant.now(clock).plusSeconds(day * 24 * 3600).atZone(ZoneId.systemDefault()).getDayOfWeek();
|
||||
DayOfWeek dayOfWeek;
|
||||
int dataCount = 0;
|
||||
float temp_c = 0;
|
||||
@ -91,7 +92,7 @@ public class OpenWeatherMap implements WeatherDataAPI {
|
||||
|
||||
return new WeatherData(
|
||||
new City(city),
|
||||
Instant.now().plusSeconds(day * 24 * 3600),
|
||||
Instant.now(clock).plusSeconds(day * 24 * 3600),
|
||||
temp_c,
|
||||
windSpeed,
|
||||
windDirection,
|
||||
@ -104,7 +105,7 @@ public class OpenWeatherMap implements WeatherDataAPI {
|
||||
*/
|
||||
@Override
|
||||
public WeatherData getTemperature(int day, String city) throws IOException {
|
||||
JSONObject result = fetchWeather(day+1, new City(city));
|
||||
JSONObject result = fetchWeather(new City(city));
|
||||
|
||||
return getWeatherDataFromForecast(result, day, city);
|
||||
}
|
||||
@ -116,7 +117,7 @@ public class OpenWeatherMap implements WeatherDataAPI {
|
||||
|
||||
@Override
|
||||
public ArrayList<WeatherData> getTemperatures(int days, String city) throws IOException {
|
||||
JSONObject result = fetchWeather(days, new City(city));
|
||||
JSONObject result = fetchWeather(new City(city));
|
||||
|
||||
ArrayList<WeatherData> weatherDatas = new ArrayList<>();
|
||||
|
||||
@ -133,4 +134,9 @@ public class OpenWeatherMap implements WeatherDataAPI {
|
||||
public String getAPIName() {
|
||||
return "OpenWeatherMap";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getAPIName();
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import java.util.stream.Stream;
|
||||
|
||||
public class WeatherAPITest {
|
||||
private static final String APIKey = "realKey";
|
||||
private static final float epsilon = 0.01F;
|
||||
private WeatherAPI weatherAPI;
|
||||
|
||||
@BeforeEach
|
||||
@ -23,19 +22,6 @@ public class WeatherAPITest {
|
||||
this.weatherAPI.JSONFetcher = new FakeJSONFetcherWeatherAPI();
|
||||
}
|
||||
|
||||
/**
|
||||
* For coverage (hour not yet implemented)
|
||||
* @throws IOException never
|
||||
*/
|
||||
@Test
|
||||
public void testGetTemperatureByHour() throws IOException {
|
||||
String city = "Bordeaux";
|
||||
Assertions.assertAll(
|
||||
() -> weatherAPI.getTemperature(0,1, city)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAPIName() {
|
||||
Assertions.assertEquals("WeatherAPI", weatherAPI.getAPIName());
|
||||
|
@ -1,5 +1,6 @@
|
||||
package eirb.pg203;
|
||||
|
||||
import eirb.pg203.fakeJSONFetcher.FakeJSONFetcherOpenWeatherMap;
|
||||
import eirb.pg203.fakeJSONFetcher.FakeJSONFetcherWeatherAPI;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
@ -9,6 +10,9 @@ import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -22,6 +26,18 @@ public class WeatherDataAPITest {
|
||||
return weatherAPI;
|
||||
}
|
||||
|
||||
private static OpenWeatherMap openWeatherMap(){
|
||||
// Fix clock for testing
|
||||
String instantExpected = "2024-11-24T00:00:00.00Z";
|
||||
Clock clock = Clock.fixed(Instant.parse(instantExpected), ZoneId.systemDefault());
|
||||
|
||||
OpenWeatherMap openWeatherMap= new OpenWeatherMap(APIKey);
|
||||
openWeatherMap.JSONFetcher = new FakeJSONFetcherOpenWeatherMap();
|
||||
openWeatherMap.clock = clock;
|
||||
return openWeatherMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List of args for Temperature testing
|
||||
* @return Args for testing
|
||||
@ -32,7 +48,11 @@ public class WeatherDataAPITest {
|
||||
Arguments.arguments(weatherAPI(), 0, 8.1F,WeatherData.Condition.PARTIAL, 17.45F, 142.08F),
|
||||
Arguments.arguments(weatherAPI(), 1, 13F, WeatherData.Condition.SUNNY, 23.03F, 142.58F),
|
||||
Arguments.arguments(weatherAPI(), 2, 12.7F, WeatherData.Condition.RAINY, 13.19F, 222.92F),
|
||||
Arguments.arguments(weatherAPI(), 3, 8.1F,WeatherData.Condition.CLOUDY, 17.45F, 142.08F)
|
||||
Arguments.arguments(weatherAPI(), 3, 8.1F,WeatherData.Condition.CLOUDY, 17.45F, 142.08F),
|
||||
Arguments.arguments(openWeatherMap(), 0, 13.41F,WeatherData.Condition.PARTIAL, 5.74F, 142.13F),
|
||||
Arguments.arguments(openWeatherMap(), 1, 13.29F,WeatherData.Condition.CLOUDY, 3.62F, 225.25F),
|
||||
Arguments.arguments(openWeatherMap(), 2, 10.06F,WeatherData.Condition.RAINY, 2.22F, 191.75F),
|
||||
Arguments.arguments(openWeatherMap(), 3, 9.88F,WeatherData.Condition.SUNNY, 2.00F, 160.00F)
|
||||
);
|
||||
}
|
||||
|
||||
@ -44,12 +64,12 @@ public class WeatherDataAPITest {
|
||||
weatherData = weatherDataAPI.getTemperature(day, city);
|
||||
|
||||
/* Temperatures */
|
||||
Assertions.assertEquals(expectedTemp, weatherData.getTemp());
|
||||
Assertions.assertEquals(expectedTemp, weatherData.getTemp(), epsilon);
|
||||
/* Condition */
|
||||
Assertions.assertEquals(expectedCond, weatherData.getCondition());
|
||||
/* Wind */
|
||||
Assertions.assertTrue(expectedWindSpeed - weatherData.getWindSpeed() < epsilon);
|
||||
Assertions.assertTrue(expectedWindAngle - weatherData.getWindDirectionAngle() < epsilon);
|
||||
Assertions.assertEquals(expectedWindSpeed, weatherData.getWindSpeed(), epsilon);
|
||||
Assertions.assertEquals(expectedWindAngle, weatherData.getWindDirectionAngle(),epsilon);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testGetTemperatures() {
|
||||
@ -57,8 +77,15 @@ public class WeatherDataAPITest {
|
||||
WeatherData.Condition[] weatherAPIExpectedConditions = {WeatherData.Condition.PARTIAL, WeatherData.Condition.SUNNY, WeatherData.Condition.RAINY, WeatherData.Condition.CLOUDY};
|
||||
float[] weatherAPIExpectedWindSpeed = {17.45F, 23.03F, 13.19F, 17.45F};
|
||||
float[] weatherAPIExpectedWindDirection = {142.08F, 142.58F, 222.92F, 142.08F};
|
||||
|
||||
float[] openWeatherMapExpectedTemperatures = {13.41F, 13.29F, 10.06F, 9.88F};
|
||||
WeatherData.Condition[] openWeatherMapExpectedConditions = {WeatherData.Condition.PARTIAL, WeatherData.Condition.CLOUDY, WeatherData.Condition.RAINY, WeatherData.Condition.SUNNY};
|
||||
float[] openWeatherMapExpectedWindSpeed = {5.74F, 3.62F, 2.22F, 2.00F};
|
||||
float[] openWeatherMapExpectedWindDirection = {142.13F, 225.25F, 191.75F, 160F};
|
||||
|
||||
return Stream.of(
|
||||
Arguments.arguments(weatherAPI(), 4, weatherAPIExpectedTemperatures, weatherAPIExpectedConditions, weatherAPIExpectedWindSpeed, weatherAPIExpectedWindDirection)
|
||||
Arguments.arguments(weatherAPI(), 4, weatherAPIExpectedTemperatures, weatherAPIExpectedConditions, weatherAPIExpectedWindSpeed, weatherAPIExpectedWindDirection),
|
||||
Arguments.arguments(openWeatherMap(), 4, openWeatherMapExpectedTemperatures, openWeatherMapExpectedConditions, openWeatherMapExpectedWindSpeed, openWeatherMapExpectedWindDirection)
|
||||
);
|
||||
|
||||
}
|
||||
@ -75,12 +102,29 @@ public class WeatherDataAPITest {
|
||||
weatherData = weatherDatas.get(index);
|
||||
|
||||
/* Temperatures */
|
||||
Assertions.assertEquals(expectedTemperatures[index], weatherData.getTemp());
|
||||
Assertions.assertEquals(expectedTemperatures[index], weatherData.getTemp(), epsilon);
|
||||
/* Weather condition */
|
||||
Assertions.assertEquals(expectedConditions[index], weatherData.getCondition());
|
||||
/* Wind */
|
||||
Assertions.assertTrue(expectedWindSpeed[index] - weatherData.getWindSpeed() < epsilon);
|
||||
Assertions.assertTrue(expectedWindDirection[index] - weatherData.getWindDirectionAngle() < epsilon);
|
||||
Assertions.assertEquals(expectedWindSpeed[index],weatherData.getWindSpeed(), epsilon);
|
||||
Assertions.assertEquals(expectedWindDirection[index], weatherData.getWindDirectionAngle(), epsilon);
|
||||
}
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testGetTemperatureByHours() {
|
||||
|
||||
return Stream.of(
|
||||
Arguments.arguments(weatherAPI()),
|
||||
Arguments.arguments(openWeatherMap())
|
||||
);
|
||||
}
|
||||
@ParameterizedTest(name = "[{0}] Get temperature for a specific hour")
|
||||
@MethodSource
|
||||
public void testGetTemperatureByHours(WeatherDataAPI weatherDataAPI) {
|
||||
String city = "Bordeaux";
|
||||
Assertions.assertAll(
|
||||
() -> weatherDataAPI.getTemperature(0,1, city)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
package eirb.pg203.fakeJSONFetcher;
|
||||
|
||||
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.IOException;
|
||||
import java.net.URL;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
|
||||
public class FakeJSONFetcherOpenWeatherMap implements JSONFetcherInterface {
|
||||
private final String apiKey = "realKey";
|
||||
private final JSONObject wrongKeyResponse = FileResourcesUtils.getFileFromResourceAsJson("OpenWeatherMap/wrong-apikey.json");
|
||||
|
||||
private JSONObject responseExample() {
|
||||
return FileResourcesUtils.getFileFromResourceAsJson("OpenWeatherMap/Bordeaux-partial-cloudy-rain-sunny.json");
|
||||
}
|
||||
@Override
|
||||
public JSONObject fetch(URL url) throws IOException {
|
||||
Map<String, String> params = SplitQueryUrl.splitQuery(url);
|
||||
if (!params.getOrDefault("appid", "").contentEquals(apiKey))
|
||||
return wrongKeyResponse;
|
||||
return responseExample();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONArray fetchArray(URL url) throws IOException {
|
||||
return null;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
4
src/test/resources/OpenWeatherMap/wrong-apikey.json
Normal file
4
src/test/resources/OpenWeatherMap/wrong-apikey.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"cod": 401,
|
||||
"message": "Invalid API key. Please see https://openweathermap.org/faq#error401 for more info."
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user