From 747475f35f53437111ed9d0a530f2a906f6cfe2b Mon Sep 17 00:00:00 2001 From: Amandus Butzer Date: Tue, 8 Nov 2022 16:13:58 +0100 Subject: [PATCH] tests: Add user_speed_limits test adds parameter and result tests for custom speeds Co-authored-by: koebi --- .../ors/v2/services/routing/ParamsTest.java | 211 ++++++++++++++++++ .../ors/v2/services/routing/ResultTest.java | 150 +++++++++++++ 2 files changed, 361 insertions(+) diff --git a/openrouteservice-api-tests/src/test/java/org/heigit/ors/v2/services/routing/ParamsTest.java b/openrouteservice-api-tests/src/test/java/org/heigit/ors/v2/services/routing/ParamsTest.java index e352b0cc2a..2df6903cf7 100644 --- a/openrouteservice-api-tests/src/test/java/org/heigit/ors/v2/services/routing/ParamsTest.java +++ b/openrouteservice-api-tests/src/test/java/org/heigit/ors/v2/services/routing/ParamsTest.java @@ -1828,4 +1828,215 @@ public void expectNoErrorOnSingleRadiusForMultipleCoordinates() { .body("any { it.key == 'routes' }", is(true)) .statusCode(200); } + // when given a user speed limit on a surface property, + // a route should be found and the user speed limit should be present in at least the returned query. + @Test + public void expectPassOnSurfaceSpeed() { + JSONObject userSpeedLimits = new JSONObject(); + JSONObject surfaceSpeedLimits = new JSONObject(); + surfaceSpeedLimits.put("gravel", 80); + userSpeedLimits.put("roadSpeeds", surfaceSpeedLimits); + + JSONObject body = new JSONObject(); + body.put("coordinates", getParameter("coordinatesShort")); + body.put("user_speed_limits", userSpeedLimits); + + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("profile")) + .body(body.toString()) + .when() + .post(getEndPointPath() + "/{profile}") + .then() + .assertThat() + .body("any { it.key == 'routes' }", is(true)) + .body("metadata.query.containsKey('user_speed_limits')", is(true)) + .statusCode(200); + } + + // when given a user speed limit on a road property, + // a route should be found and the user speed limit should be present in at least the returned query. + @Test + public void expectPassOnRoadSpeed() { + JSONObject userSpeedLimits = new JSONObject(); + JSONObject roadSpeedLimits = new JSONObject(); + roadSpeedLimits.put("motorway", 80); + userSpeedLimits.put("roadSpeeds", roadSpeedLimits); + + JSONObject body = new JSONObject(); + body.put("coordinates", getParameter("coordinatesShort")); + body.put("user_speed_limits", userSpeedLimits); + + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("profile")) + .body(body.toString()) + .when() + .post(getEndPointPath() + "/{profile}") + .then() + .assertThat() + .body("any { it.key == 'routes' }", is(true)) + .body("metadata.query.containsKey('user_speed_limits')", is(true)) + .statusCode(200); + } + + // when given a user speed limit and a custom unit, + // a route should be found and the user speed limit should be present in at least the returned query. + @Test + public void expectPassOnUserUnit() { + JSONObject userSpeedLimits = new JSONObject(); + JSONObject roadSpeedLimits = new JSONObject(); + roadSpeedLimits.put("motorway", 55); + userSpeedLimits.put("roadSpeeds", roadSpeedLimits); + userSpeedLimits.put("unit", "mph"); + + JSONObject body = new JSONObject(); + body.put("coordinates", getParameter("coordinatesShort")); + body.put("user_speed_limits", userSpeedLimits); + + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("profile")) + .body(body.toString()) + .when() + .post(getEndPointPath() + "/{profile}") + .then() + .assertThat() + .body("any { it.key == 'routes' }", is(true)) + .body("metadata.query.containsKey('user_speed_limits')", is(true)) + .body("metadata.query.user_speed_limits.containsKey('unit')", is(true)) + .body("metadata.query.user_speed_limits.unit", is("mph")) + .statusCode(200); + } + + @Test + public void expect2012OnUnknownKey() { + JSONObject userSpeedLimits = new JSONObject(); + JSONObject roadSpeedLimits = new JSONObject(); + roadSpeedLimits.put("primary", 80); + userSpeedLimits.put("unknownKey", roadSpeedLimits); + + JSONObject body = new JSONObject(); + body.put("coordinates", getParameter("coordinatesShort")); + body.put("user_speed_limits", userSpeedLimits); + + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("profile")) + .body(body.toString()) + .when() + .post(getEndPointPath() + "/{profile}") + .then() + .assertThat() + .body("any { it.key == 'routes' }", is(false)) + .body("error.code", is(2012)) + .statusCode(400); + } + + + // when given a non-supported road type, an error should appear + @Test + public void expect2012onUnknownRoadType() { + JSONObject userSpeedLimits = new JSONObject(); + JSONObject roadSpeedLimits = new JSONObject(); + roadSpeedLimits.put("unknownProperty", 80); + userSpeedLimits.put("roadSpeeds", roadSpeedLimits); + + JSONObject body = new JSONObject(); + body.put("coordinates", getParameter("coordinatesShort")); + body.put("user_speed_limits", userSpeedLimits); + + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("profile")) + .body(body.toString()) + .when() + .post(getEndPointPath() + "/{profile}") + .then() + .assertThat() + .body("any { it.key == 'routes' }", is(false)) + .body("error.code", is(2012)) + .statusCode(400); + } + + // when given a non-supported surface type, an error should appear + @Test + public void expect2012onUnknownSurfaceType() { + JSONObject userSpeedLimits = new JSONObject(); + JSONObject surfaceSpeedLimits = new JSONObject(); + surfaceSpeedLimits.put("unknownProperty", 80); + userSpeedLimits.put("surfaceSpeeds", surfaceSpeedLimits); + + JSONObject body = new JSONObject(); + body.put("coordinates", getParameter("coordinatesShort")); + body.put("user_speed_limits", userSpeedLimits); + + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("profile")) + .body(body.toString()) + .when() + .post(getEndPointPath() + "/{profile}") + .then() + .assertThat() + .body("any { it.key == 'routes' }", is(false)) + .body("error.code", is(2012)) + .statusCode(400); + } + + // when given an invalid speed, an error should appear + @Test + public void expect2003onInvalidSpeed() { + JSONObject userSpeedLimits = new JSONObject(); + JSONObject surfaceSpeedLimits = new JSONObject(); + surfaceSpeedLimits.put("gravel", -80); + userSpeedLimits.put("surfaceSpeeds", surfaceSpeedLimits); + + JSONObject body = new JSONObject(); + body.put("coordinates", getParameter("coordinatesShort")); + body.put("user_speed_limits", userSpeedLimits); + + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("profile")) + .body(body.toString()) + .when() + .post(getEndPointPath() + "/{profile}") + .then() + .assertThat() + .body("any { it.key == 'routes' }", is(false)) + .body("error.code", is(2003)) + .statusCode(400); + } + + // when given an unknown unit, an error should appear + @Test + public void expect2003onUnknownUnit(){ + JSONObject userSpeedLimits = new JSONObject(); + userSpeedLimits.put("unit", "unknownUnit"); + + JSONObject body = new JSONObject(); + body.put("coordinates", getParameter("coordinatesShort")); + body.put("user_speed_limits", userSpeedLimits); + + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("profile")) + .body(body.toString()) + .when() + .post(getEndPointPath() + "/{profile}") + .then() + .assertThat() + .body("any { it.key == 'routes' }", is(false)) + .body("error.code", is(2003)) + .statusCode(400); + } } diff --git a/openrouteservice-api-tests/src/test/java/org/heigit/ors/v2/services/routing/ResultTest.java b/openrouteservice-api-tests/src/test/java/org/heigit/ors/v2/services/routing/ResultTest.java index e008e52991..7f5bb2f04c 100644 --- a/openrouteservice-api-tests/src/test/java/org/heigit/ors/v2/services/routing/ResultTest.java +++ b/openrouteservice-api-tests/src/test/java/org/heigit/ors/v2/services/routing/ResultTest.java @@ -3710,6 +3710,156 @@ public void expectMaxpeedHgvForward() { .statusCode(200); } + @Test + public void testUserRoadSpeed() { + JSONObject body = new JSONObject(); + JSONArray coords = new JSONArray(); + JSONArray neuenheim = new JSONArray(); + neuenheim.put(8.685036); + neuenheim.put(49.4201314); + JSONArray dossenheim = new JSONArray(); + dossenheim.put(8.671297); + dossenheim.put(49.4436); + coords.put(neuenheim); + coords.put(dossenheim); + body.put("coordinates", coords); + + // since we're testing on the same profile, "shortest" would not be dependent on speed settings + // and "recommended" will make too many assumptions on what route could be preferred. + body.put("preference", "fastest"); + + // request route without specifying user Speed + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("carProfile")) + .body(body.toString()) + .when().log().ifValidationFails() + .post(getEndPointPath() + "/{profile}") + .then().log().ifValidationFails() + .assertThat() + .body("any { it.key == 'routes' }", is(true)) + .body("routes[0].summary.distance", is(3822.6f)) + .body("routes[0].summary.duration", is(550.0f)) + .statusCode(200); + + JSONObject userSpeedLimits = new JSONObject(); + JSONObject roadSpeedLimits = new JSONObject(); + roadSpeedLimits.put("primary", 30); + roadSpeedLimits.put("secondary", 30); + userSpeedLimits.put("roadSpeeds", roadSpeedLimits); + body.put("user_speed_limits", userSpeedLimits); + + // request route limiting speed on primary and secondary roads to 30 + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("carProfile")) + .body(body.toString()) + .when().log().ifValidationFails() + .post(getEndPointPath() + "/{profile}") + .then().log().ifValidationFails() + .assertThat() + .body("any { it.key == 'routes' }", is(true)) + .body("routes[0].summary.distance", is(3958.0f)) + .body("routes[0].summary.duration", is(625.7f)) + .statusCode(200); + } + + @Test + public void testUserSurfaceSpeed() { + JSONObject body = new JSONObject(); + JSONArray coords = new JSONArray(); + JSONArray south = new JSONArray(); + south.put(8.707808); + south.put(49.398337); + JSONArray north = new JSONArray(); + north.put(8.710012); + north.put(49.405015); + coords.put(south); + coords.put(north); + body.put("coordinates", coords); + + // use "shortest" as "recommended" will make too many assumptions on what route could be preferred. + body.put("preference", "shortest"); + + // request route without specifying user Speed + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", "cycling-mountain") + .body(body.toString()) + .when().log().ifValidationFails() + .post(getEndPointPath() + "/{profile}") + .then().log().ifValidationFails() + .assertThat() + .body("any { it.key == 'routes' }", is(true)) + .body("routes[0].summary.distance", is(1529.7f)) + .body("routes[0].summary.duration", is(349.2f)) + .statusCode(200); + + JSONObject userSpeedLimits = new JSONObject(); + JSONObject surfaceSpeedLimits = new JSONObject(); + surfaceSpeedLimits.put("gravel", 2); + surfaceSpeedLimits.put("ground", 2); + surfaceSpeedLimits.put("compacted", 2); + userSpeedLimits.put("surfaceSpeeds", surfaceSpeedLimits); + body.put("user_speed_limits", userSpeedLimits); + + // with modified speeds travel time should increase while the distance is expected to stay the same + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", "cycling-mountain") + .body(body.toString()) + .when().log().ifValidationFails() + .post(getEndPointPath() + "/{profile}") + .then().log().ifValidationFails() + .assertThat() + .body("any { it.key == 'routes' }", is(true)) + .body("routes[0].summary.distance", is(1529.7f)) + .body("routes[0].summary.duration", is(greaterThan(349.2f))) + .statusCode(200); + } + + @Test + public void testUserSpeedUnit() { + JSONObject body = new JSONObject(); + JSONArray coords = new JSONArray(); + JSONArray neuenheim = new JSONArray(); + neuenheim.put(8.685036); + neuenheim.put(49.4201314); + JSONArray dossenheim = new JSONArray(); + dossenheim.put(8.671297); + dossenheim.put(49.4436); + coords.put(neuenheim); + coords.put(dossenheim); + body.put("coordinates", coords); + + // this is the same query as testUserRoadSpeed uses, but has speeds in mph + JSONObject userSpeedLimits = new JSONObject(); + JSONObject roadSpeedLimits = new JSONObject(); + roadSpeedLimits.put("primary", 18.6412f); + roadSpeedLimits.put("secondary", 18.6412f); + userSpeedLimits.put("roadSpeeds", roadSpeedLimits); + userSpeedLimits.put("unit", "mph"); + body.put("user_speed_limits", userSpeedLimits); + + given() + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .pathParam("profile", getParameter("carProfile")) + .body(body.toString()) + .when().log().ifValidationFails() + .post(getEndPointPath() + "/{profile}") + .then().log().ifValidationFails() + .assertThat() + .body("any { it.key == 'routes' }", is(true)) + .body("routes[0].summary.distance", is(3958.0f)) + .body("routes[0].summary.duration", is(625.7f)) + .statusCode(200); + } + private JSONArray constructBearings(String coordString) { JSONArray coordinates = new JSONArray(); String[] coordPairs = coordString.split("\\|");