From d3ad85e26793e6a534a0d0e3df2d540b43ce70b5 Mon Sep 17 00:00:00 2001 From: Martin Eyben Date: Sat, 23 Nov 2024 20:50:11 +0100 Subject: [PATCH] feat: city test --- src/main/java/eirb/pg203/City.java | 20 ++++--- src/test/java/eirb/pg203/CityTest.java | 52 +++++++++++++++++++ .../fakeJSONFetcher/FakeJSONFetcherCity.java | 40 ++++++++++++++ src/test/resources/City/bordeaux.json | 37 +++++++++++++ src/test/resources/City/fakeCity.json | 9 ++++ src/test/resources/City/paris.json | 36 +++++++++++++ 6 files changed, 187 insertions(+), 7 deletions(-) create mode 100644 src/test/java/eirb/pg203/CityTest.java create mode 100644 src/test/java/eirb/pg203/fakeJSONFetcher/FakeJSONFetcherCity.java create mode 100644 src/test/resources/City/bordeaux.json create mode 100644 src/test/resources/City/fakeCity.json create mode 100644 src/test/resources/City/paris.json diff --git a/src/main/java/eirb/pg203/City.java b/src/main/java/eirb/pg203/City.java index e89e682..77fab5d 100644 --- a/src/main/java/eirb/pg203/City.java +++ b/src/main/java/eirb/pg203/City.java @@ -11,6 +11,7 @@ import java.util.Locale; import eirb.pg203.utils.JSONFetcher; import eirb.pg203.utils.JSONFetcherInterface; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import eirb.pg203.utils.Coords; @@ -22,13 +23,13 @@ import eirb.pg203.utils.Coords; public class City { private String cityName; private Coords cityCoords; - private static final JSONFetcherInterface JSONFetcher = new JSONFetcher(); + JSONFetcherInterface JSONFetcher = new JSONFetcher(); /** * Fetch data from adresse.data.gouv.fr * @throws IOException if the request fails */ - private static JSONObject getDataFromName(String cityName) throws IOException { + private JSONObject getDataFromName(String cityName) throws IOException { StringBuilder result = new StringBuilder(); URL url = URI.create( String.format(Locale.ENGLISH, "https://api-adresse.data.gouv.fr/search/?q=%s&autocomplete=0&limit=1", @@ -39,12 +40,17 @@ public class City { return JSONFetcher.fetch(url); } - private static Coords getCoordsFromName(String cityName) throws IOException { + private Coords getCoordsFromName(String cityName) throws IOException { JSONObject data = getDataFromName(cityName); - JSONArray rawCoords = data.getJSONArray("features") - .getJSONObject(0) - .getJSONObject("geometry") - .getJSONArray("coordinates"); + JSONArray rawCoords; + try { + rawCoords = data.getJSONArray("features") + .getJSONObject(0) + .getJSONObject("geometry") + .getJSONArray("coordinates"); + } catch (JSONException e) { + throw new IOException(); + } final float lon = rawCoords.getFloat(0); final float lat = rawCoords.getFloat(1); diff --git a/src/test/java/eirb/pg203/CityTest.java b/src/test/java/eirb/pg203/CityTest.java new file mode 100644 index 0000000..bc3af92 --- /dev/null +++ b/src/test/java/eirb/pg203/CityTest.java @@ -0,0 +1,52 @@ +package eirb.pg203; + +import eirb.pg203.fakeJSONFetcher.FakeJSONFetcherCity; +import eirb.pg203.utils.Coords; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import java.io.IOException; + +public class CityTest { + private final static float epsilon = 0.001F; + @ParameterizedTest(name = "{0} is located at [lat:{1}, lon:{2}]") + @CsvSource({ + "Paris,48.859F,2.347F,'City(Paris, lat: 48.859001, lon: 2.347000)'", + "Bordeaux,44.851895F,-0.587877F,'City(Bordeaux, lat: 44.851894, lon: -0.587877)'" + }) + void testRealCity(String cityName, float expectedLat, float expectedLon, String expectedString) throws IOException { + City city = new City(cityName); + city.JSONFetcher = new FakeJSONFetcherCity(); + + /* Name coherence */ + Assertions.assertEquals(cityName, city.getCityName()); + /* Localisation */ + Coords coords = city.getCityCoords(); + float lat = coords.getLat(); + float lon = coords.getLon(); + System.out.println(city); + + Assertions.assertTrue(Math.abs(lat - expectedLat) < epsilon); + Assertions.assertTrue(Math.abs(lon - expectedLon) < epsilon); + + /* String representation */ + Assertions.assertEquals(expectedString, city.toString()); + } + + @Test + void testFakeCity(){ + String fakeCity = "farlmjmjfkl"; + String fakeCityRepresentation = "City("+ fakeCity +", lat: Request failed, lon: Request Failed)"; + City city = new City(fakeCity); + + /* String representation */ + Assertions.assertEquals(fakeCityRepresentation, city.toString()); + + /* Throw exception */ + Assertions.assertThrows(IOException.class, city::getCityCoords); + + } + +} diff --git a/src/test/java/eirb/pg203/fakeJSONFetcher/FakeJSONFetcherCity.java b/src/test/java/eirb/pg203/fakeJSONFetcher/FakeJSONFetcherCity.java new file mode 100644 index 0000000..6259e41 --- /dev/null +++ b/src/test/java/eirb/pg203/fakeJSONFetcher/FakeJSONFetcherCity.java @@ -0,0 +1,40 @@ +package eirb.pg203.fakeJSONFetcher; + +import eirb.pg203.utils.FileResourcesUtils; +import eirb.pg203.utils.JSONFetcher; +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.util.HashMap; +import java.util.Locale; +import java.util.Map; + +public class FakeJSONFetcherCity implements JSONFetcherInterface { + JSONObject unknownCity = FileResourcesUtils.getFileFromResourceAsJson("City/fakeCity.json"); + + private static HashMap cities(){ + HashMap cities = new HashMap<>(); + cities.put("bordeaux", FileResourcesUtils.getFileFromResourceAsJson("City/bordeaux.json")); + cities.put("paris", FileResourcesUtils.getFileFromResourceAsJson("City/paris.json")); + cities.put("unknown", FileResourcesUtils.getFileFromResourceAsJson("City/fakeCity.json")); + return cities; + } + + + @Override + public JSONObject fetch(URL url) throws IOException { + Map params = SplitQueryUrl.splitQuery(url); + + String city = params.get("q").toLowerCase(Locale.ENGLISH); + return cities().getOrDefault(city, unknownCity); + } + + @Override + public JSONArray fetchArray(URL url) throws IOException { + return null; + } +} diff --git a/src/test/resources/City/bordeaux.json b/src/test/resources/City/bordeaux.json new file mode 100644 index 0000000..76577c9 --- /dev/null +++ b/src/test/resources/City/bordeaux.json @@ -0,0 +1,37 @@ +{ + "type": "FeatureCollection", + "version": "draft", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + -0.587877, + 44.851895 + ] + }, + "properties": { + "label": "Bordeaux", + "score": 0.9608036363636362, + "id": "33063", + "banId": "f38fe08f-c87b-4b3f-8f05-1566b8da9c39", + "type": "municipality", + "name": "Bordeaux", + "postcode": "33000", + "citycode": "33063", + "x": 416627.63, + "y": 6423408.37, + "population": 261804, + "city": "Bordeaux", + "context": "33, Gironde, Nouvelle-Aquitaine", + "importance": 0.56884, + "municipality": "Bordeaux" + } + } + ], + "attribution": "BAN", + "licence": "ETALAB-2.0", + "query": "Bordeaux", + "limit": 1 +} \ No newline at end of file diff --git a/src/test/resources/City/fakeCity.json b/src/test/resources/City/fakeCity.json new file mode 100644 index 0000000..21a422a --- /dev/null +++ b/src/test/resources/City/fakeCity.json @@ -0,0 +1,9 @@ +{ + "type": "FeatureCollection", + "version": "draft", + "features": [], + "attribution": "BAN", + "licence": "ETALAB-2.0", + "query": "farmjfakj", + "limit": 1 +} \ No newline at end of file diff --git a/src/test/resources/City/paris.json b/src/test/resources/City/paris.json new file mode 100644 index 0000000..d1e0e1f --- /dev/null +++ b/src/test/resources/City/paris.json @@ -0,0 +1,36 @@ +{ + "type": "FeatureCollection", + "version": "draft", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 2.347, + 48.859 + ] + }, + "properties": { + "label": "Paris", + "score": 0.9703381818181818, + "id": "75056", + "type": "municipality", + "name": "Paris", + "postcode": "75001", + "citycode": "75056", + "x": 652089.7, + "y": 6862305.26, + "population": 2133111, + "city": "Paris", + "context": "75, Paris, Île-de-France", + "importance": 0.67372, + "municipality": "Paris" + } + } + ], + "attribution": "BAN", + "licence": "ETALAB-2.0", + "query": "Paris", + "limit": 1 +} \ No newline at end of file