All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jayway.restassured.assertion.BodyMatcher.groovy Maven / Gradle / Ivy

/*
 * Copyright 2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */



package com.jayway.restassured.assertion

import com.jayway.restassured.config.RestAssuredConfig
import com.jayway.restassured.internal.ResponseParserRegistrar
import com.jayway.restassured.response.Response
import org.hamcrest.Matcher
import org.hamcrest.StringDescription
import org.hamcrest.xml.HasXPath
import org.w3c.dom.Element

import javax.xml.parsers.DocumentBuilderFactory

import static java.lang.String.format
import static org.apache.commons.lang3.StringUtils.*

class BodyMatcher {
    private static final String XPATH = "XPath"
    def key
    def Matcher matcher
    def ResponseParserRegistrar rpr

    def validate(Response response, contentParser, RestAssuredConfig config) {
        def success = true
        def errorMessage = "";

        contentParser = fallbackToResponseBodyIfContentParserIsNull(response, contentParser)
        if (key == null) {
            if (isXPathMatcher()) {
                def xmlConfig = config.getXmlConfig();
                boolean namespaceAware = xmlConfig.isNamespaceAware()
                def Map features = xmlConfig.features()

                def factory = DocumentBuilderFactory.newInstance()
                factory.setNamespaceAware(namespaceAware)
                if (!features.isEmpty()) {
                    features.each { featureName, isEnabled ->
                        factory.setFeature(featureName, isEnabled)
                    }
                }

                Element node = factory.newDocumentBuilder().parse(new ByteArrayInputStream(response.asByteArray())).getDocumentElement();
                if (!matcher.matches(node)) {
                    success = false
                    errorMessage = format("Expected: %s\n  Actual: %s\n", trim(matcher.toString()), contentParser)
                }
            } else if (!matcher.matches(response.asString())) {
                success = false
                errorMessage = "Response body doesn't match expectation.\nExpected: $matcher\n  Actual: $contentParser\n"
            }
        } else {
            def assertion = StreamVerifier.newAssertion(response, key, rpr)
            def result = null
            if (contentParser != null) {
                if (contentParser instanceof String) {
                    // This happens for example when expecting JSON/XML assertion but response content is empty
                    def isEmpty = contentParser?.isEmpty()
                    errorMessage = format("Cannot assert that path \"$key\" matches $matcher because the response body %s.", isEmpty ? "is empty" : "equal to \"$contentParser\"")
                    success = false
                } else {
                    result = assertion.getResult(contentParser, config)
                }
            }

            if (success && !matcher.matches(result)) {
                success = false
                if (result instanceof Object[]) {
                    result = result.join(",")
                }
                errorMessage = format("%s %s doesn't match.\nExpected: %s\n  Actual: %s\n", assertion.description(), key, removeQuotesIfString(matcher.toString()), result)
            }
        }
        return [success: success, errorMessage: errorMessage];
    }

    private static String removeQuotesIfString(String string) {
        if (startsWith(string, "\"") && endsWith(string, "\"")) {
            def start = removeStart(string, "\"")
            string = removeEnd(start, "\"")
        }
        string
    }

    static def fallbackToResponseBodyIfContentParserIsNull(Response response, contentParser) {
        if (contentParser == null) {
            return response.asString()
        }
        return contentParser
    }

    private boolean isXPathMatcher() {
        def isNestedMatcherContainingXPathMatcher = {
            def description = new StringDescription()
            matcher.describeTo(description)
            description.toString().contains(XPATH)
        }

        matcher instanceof HasXPath || isNestedMatcherContainingXPathMatcher()
    }

    def boolean requiresTextParsing() {
        key == null || isXPathMatcher()
    }

    def boolean requiresPathParsing() {
        !requiresTextParsing()
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy