package fi.hsl.parkandride.itest;

import static com.jayway.restassured.RestAssured.when;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;

import java.io.IOException;

import org.junit.Test;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;

import fi.hsl.parkandride.core.domain.Facility;
import fi.hsl.parkandride.core.service.ValidationException;
import fi.hsl.parkandride.front.UrlSchema;

public class ErrorHandlingITest extends AbstractIntegrationTest {
    @Test
    public void notFound() {
        when()
            .get(UrlSchema.FACILITIES + "/42")
        .then()
            .statusCode(HttpStatus.NOT_FOUND.value())
            .body(is(""))
        ;
    }

    @Test
    public void validationException() {
        givenWithContent()
            .body(new Facility())
        .when()
            .post(UrlSchema.FACILITIES)
        .then()
            .spec(assertResponse(HttpStatus.BAD_REQUEST, ValidationException.class))
            .body("violations", is(notNullValue()))
        ;
    }

    @Test
    public void httpMessageNotReadableException_geolatte_violations_are_not_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", is(nullValue()))
        ;
    }

    @Test
    public void httpMessageNotReadableException_typical_json_mapping_violations_are_detected() throws IOException {
        givenWithContent()
            .body(resourceAsString("facility.create.JsonMappingException.json"))
        .when()
            .post(UrlSchema.FACILITIES)
        .then()
            .spec(assertResponse(HttpStatus.BAD_REQUEST, HttpMessageNotReadableException.class))
            .body("violations[0].path", is("capacities.built"))
        ;
    }

    @Test
    public void httpRequestMethodNotSupportedException() {
        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 invalid_path_variable_type_is_reported_with_status_code_500() {
        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\""))
        ;
    }

    // HttpMediaTypeException: unclear how to trigger
    // bindException: unclear how to trigger
}

@@ -486,32 +486,85 @@
 dableException;%0A
+import org.springframework.validation.BindException;%0A
 import org.sprin
@@ -2711,32 +2711,636 @@
        ;%0A    %7D%0A%0A
+    @Test%0A    public void bindException() %7B%0A        when()%0A            .get(UrlSchema.FACILITIES + %22?ids=foo%22)%0A        .then()%0A            .spec(assertResponse(HttpStatus.BAD_REQUEST, BindException.class))%0A            .body(%22message%22, is(%22Invalid request parameters%22))%0A            .body(%22violations%5B0%5D.path%22, is(%22ids%22))%0A            .body(%22violations%5B0%5D.message%22, is(%22Failed to convert property value of type 'java.lang.String' to required type 'java.util.Set' for property %22 +%0A                    %22'ids'; nested exception is java.lang.NumberFormatException: For input string: %5C%22foo%5C%22%22))%0A        ;%0A    %7D%0A%0A
     @Test%0A    pu
@@ -3710,32 +3710,57 @@
 ed exception is 
+%22 +%0A                    %22
 java.lang.Number
@@ -3817,82 +3817,86 @@
     
-;%0A    %7D%0A%0A    // HttpMediaTypeException: unclear how to trigger%0A    // bind
+    .body(%22violations%22, is(nullValue()))%0A        ;%0A    %7D%0A%0A    // HttpMediaType
 Exce

test request parameter binding error