// Copyright © 2015 HSL <https://www.hsl.fi>
// This program is dual-licensed under the EUPL v1.2 and AGPLv3 licenses.
package fi.hsl.parkandride.itest;
import com.jayway.restassured.http.ContentType;
import fi.hsl.parkandride.core.domain.Facility;
import fi.hsl.parkandride.core.domain.NewUser;
import fi.hsl.parkandride.core.domain.Role;
import fi.hsl.parkandride.core.service.ValidationException;
import fi.hsl.parkandride.front.UrlSchema;
import org.junit.Test;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import static com.jayway.restassured.RestAssured.when;
import static org.hamcrest.Matchers.*;
public class ErrorHandlingITest extends AbstractIntegrationTest {
@Test
public void non_existing_resource_is_communicated_with_status_code_only() {
when()
.get(UrlSchema.FACILITIES + "/42")
.then()
.statusCode(HttpStatus.NOT_FOUND.value())
.body(is(""))
;
}
@Test
public void unauthorized_access() {
givenWithContent()
.body(new Facility())
.when()
.post(UrlSchema.FACILITIES)
.then()
.statusCode(HttpStatus.UNAUTHORIZED.value());
}
@Test
public void validation_errors_are_detailed_as_violations() {
devHelper.createOrUpdateUser(new NewUser(1l, "admin", Role.ADMIN, "admin"));
givenWithContent(devHelper.login("admin").token)
.body(new Facility())
.when()
.post(UrlSchema.FACILITIES)
.then()
.spec(assertResponse(HttpStatus.BAD_REQUEST, ValidationException.class))
.contentType(ContentType.JSON)
.body("message", startsWith("Invalid data. Violations in"))
.body("violations", is(notNullValue()))
;
}
@Test
public void typical_json_mapping_violations_are_detected() {
givenWithContent()
.body(resourceAsString("facility.create.JsonMappingException.json"))
.when()
.post(UrlSchema.FACILITIES)
.then()
.spec(assertResponse(HttpStatus.BAD_REQUEST, HttpMessageNotReadableException.class))
.body("violations[0].path", is("builtCapacity.CAR"))
;
}
@Test
public void geolatte_json_mapping_violations_are_detected() {
givenWithContent()
.body("{ \"name\": \"foo\", \"location\": \"this is not readable location\" }")
.when()
.post(UrlSchema.FACILITIES)
.then()
.spec(assertResponse(HttpStatus.BAD_REQUEST, HttpMessageNotReadableException.class))
.body("violations[0].path", is("location"))
;
}
@Test
public void unsupported_request_methods_are_detected() {
givenWithContent()
.body(new Facility())
.when()
.put(UrlSchema.FACILITIES)
.then()
.spec(assertResponse(HttpStatus.BAD_REQUEST, HttpRequestMethodNotSupportedException.class))
.body("message", is("Request method 'PUT' not supported"))
;
}
@Test
public void request_parameter_binding_errors_are_detailed_as_violations() {
when()
.get(UrlSchema.FACILITIES + "?ids=foo")
.then()
.spec(assertResponse(HttpStatus.BAD_REQUEST, BindException.class))
.body("message", is("Invalid request parameters"))
.body("violations[0].path", is("ids"))
.body("violations[0].message", is("Failed to convert property value of type 'java.lang.String' to required type 'java.util.Set' for property " +
"'ids'; nested exception is java.lang.NumberFormatException: For input string: \"foo\""))
;
}
@Test
public void invalid_path_variable_type_is_reported_as_internal_error() {
when()
.get(UrlSchema.FACILITIES + "/foo")
.then()
.spec(assertResponse(HttpStatus.INTERNAL_SERVER_ERROR, TypeMismatchException.class))
.body("message", is("Failed to convert value of type 'java.lang.String' to required type 'long'; nested exception is " +
"java.lang.NumberFormatException: For input string: \"foo\""))
.body("violations", is(nullValue()))
;
}
// HttpMediaTypeException: unclear how to trigger
}