[restassured] Skip request validation with OpenApiValidationFilter

Issue #332 new
Jannick Hemelhof created an issue

Hello,

I’ve looked at the documentation & the class itself, but there doesn’t seem to be a way to skip request validation when using the OpenApiValidationFilter? My use-case is to test if my API behaves correctly when it receives an “faulty” request (e.g. invalid parameter value): Is a correct error response being generated & returned.

Is there currently a way to do this with the current implementation?

Comments (2)

  1. James Navin

    The way I do this in my projects is to ignore the request validation errors. Something like:

    private val responseOnlyValidator = OpenApiInteractionValidator
            .createForSpecificationUrl(swaggerSpec)
            .withLevelResolver(
                LevelResolver.create().withLevel("validation.request", WARN).build()
            )
            .withWhitelist(
                ValidationErrorsWhitelist.create()
                    .withRule(
                        "Ignore request entities", WhitelistRules.isRequest()
                    )
            )
            .build()
    
    private val responseOnlyValidation = OpenApiValidationFilter(responseOnlyValidator)
    

    Then you can use the filter in your RestAssured tests:

    @Test
    fun submit_returnsBadRequest_whenMissingHeader() {
        whenARequestWith(asapAuth)
            .filter(responseOnlyValidation)
            .contentType(ContentType.JSON)
            .header("SomeHeader", "value")
            .body(loadRequest("valid-request-body"))
            .post(submitPath)
            .then().assertThat()
            .statusCode(HttpServletResponse.SC_BAD_REQUEST)
    }
    

  2. Jannick Hemelhof reporter

    That’s an interesting take, but would there be a consideration so simply put that logic in the OpenApiValidationFilter itself? Something like:

        private OpenApiValidationFilter(final OpenApiInteractionValidator validator, final ToValidate toValidate) {
            Objects.requireNonNull(validator, "A validator is required");
    
            this.validator = validator;
            this.toValidate = toValidate;
        }
    
        @Override
        public Response filter(final FilterableRequestSpecification requestSpec,
                               final FilterableResponseSpecification responseSpec,
                               final FilterContext ctx) {
    
            final Response response = ctx.next(requestSpec, responseSpec);
    
            final ValidationReport validationReport = validate(RestAssuredRequest.of(requestSpec), RestAssuredResponse.of(response));
    
            if (validationReport.hasErrors()) {
                throw new OpenApiValidationException(validationReport);
            }
    
            return response;
        }
    
        private ValidationReport validate(Request request, com.atlassian.oai.validator.model.Response response) {
            if (ToValidate.RESPONSE.equals(toValidate)) {
                return validator.validateResponse(request.getPath(), request.getMethod(), response);
            } else if (ToValidate.REQUEST_RESPONSE.equals(toValidate)) {
                return validator.validate(request, response);
            } else {
                throw new IllegalArgumentException(String.format("%s validation is not supported", toValidate));
            }
        }
    
        public static OpenApiValidationFilter forResponseValidation(OpenApiInteractionValidator validator) {
            return new OpenApiValidationFilter(validator, ToValidate.RESPONSE);
        }
    
        public static OpenApiValidationFilter forRequestAndResponseValidation(OpenApiInteractionValidator validator) {
            return new OpenApiValidationFilter(validator, ToValidate.REQUEST_RESPONSE);
        }
    
        private enum ToValidate {
            RESPONSE,
            REQUEST_RESPONSE
        }
    

    That’s how I’m currently doing it. To me it has the advantage of being clearer and making it more resistant against changes to the OpenApiInteractionValidator builder (as I usually don’t need any additional configuration so could just call build()method immediately).

  3. Log in to comment