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

templates.Stub.peb Maven / Gradle / Ivy

package {# @pebvariable name="model" type="io.lsdconsulting.stub.model.ControllerModel" #}{{model.packageName}};

import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.client.MappingBuilder;
import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder;
import static java.lang.String.format;
import javax.annotation.processing.Generated;
{% if model.containsDateTimeFormat %}
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.Printer;
{% endif %}
import java.util.List;
import java.util.Locale;
import java.lang.annotation.Annotation;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static java.util.stream.Collectors.toList;
import static java.nio.charset.StandardCharsets.UTF_8;

@Generated("com.lsdconsulting.stub.plugin.ControllerProcessor")
public class {{model.stubClassName}} {

    private static final String CONTENT_TYPE_HEADER_NAME = "Content-Type";
    private static final String CONTENT_TYPE_HEADER_VALUE = "application/json; charset=utf-8";
    private static final int OK = 200;
    private static final int ONCE = 1;
    private static final int NEVER = 0;

    private ObjectMapper objectMapper = new ObjectMapper();
{% if model.containsDateTimeFormat %}
    private AnnotationFormatterFactory annotationFormatterFactory;
{% endif %}

    public {{model.stubClassName}}(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    public {{model.stubClassName}}() {
    }

{% if model.containsDateTimeFormat %}
    public {{model.stubClassName}}(ObjectMapper objectMapper, AnnotationFormatterFactory annotationFormatterFactory) {
        this.objectMapper = objectMapper;
        this.annotationFormatterFactory = annotationFormatterFactory;
    }
{% endif %}

{% for entry in model.getResources %}
    public static final String {{entry.value.methodName.toUpperCase()}}_URL = "{{model.rootResource}}{{entry.value.subResource}}";

    public void {{decapitaliseFirstLetterOf(entry.value.methodName)}}({{ entry.value.stubMethodArgumentList | join(', ') | raw}}) {
        {{ generateUrlWithPathVariables(entry) }}
        {% if entry.value.hasOptionalMultiValueRequestParams %}
            {{ addRequestParamsToUrl(entry) }}
            MappingBuilder mappingBuilder = {{entry.value.httpMethod.name() | lower}}(urlEqualTo(url));
            stub({% if entry.value.responseStatus is empty%}OK{% else %}{{ entry.value.responseStatus }}{% endif %}, {% if entry.value.responseType is not empty%}buildBody(response){% else %}null{% endif %}, mappingBuilder);
        {% else %}
            MappingBuilder mappingBuilder = {{entry.value.httpMethod.name() | lower}}(urlPathEqualTo(url));
            {{ addQueryParamsToMappingBuilder(entry) }}
            stub({% if entry.value.responseStatus is empty%}OK{% else %}{{ entry.value.responseStatus }}{% endif %}, {% if entry.value.responseType is not empty%}buildBody(response){% else %}null{% endif %}, mappingBuilder);
        {% endif %}
    }

    {% if entry.value.requestBody != null and ["POST", "PUT"] contains entry.value.httpMethod.name() %}
    public void {{decapitaliseFirstLetterOf(entry.value.methodName)}}({{ entry.value.stubMethodArgumentListWithRequest | join(', ') | raw}}) {
        {{ generateUrlWithPathVariables(entry) }}
        {% if entry.value.hasOptionalMultiValueRequestParams %}
            {{ addRequestParamsToUrl(entry) }}
            MappingBuilder mappingBuilder = {{entry.value.httpMethod.name() | lower}}(urlEqualTo(url)).withRequestBody(equalToJson(buildBody({{ entry.value.requestBody.name }})));
            stub({% if entry.value.responseStatus is empty%}OK{% else %}{{ entry.value.responseStatus }}{% endif %}, {% if entry.value.responseType is not empty%}buildBody(response){% else %}null{% endif %}, mappingBuilder);
        {% else %}
            MappingBuilder mappingBuilder = {{entry.value.httpMethod.name() | lower}}(urlPathEqualTo(url)).withRequestBody(equalToJson(buildBody({{ entry.value.requestBody.name }})));
            {{ addQueryParamsToMappingBuilder(entry) }}
            stub({% if entry.value.responseStatus is empty%}OK{% else %}{{ entry.value.responseStatus }}{% endif %}, {% if entry.value.responseType is not empty%}buildBody(response){% else %}null{% endif %}, mappingBuilder);
        {% endif %}
    }
    {% endif %}

    public void {{decapitaliseFirstLetterOf(entry.value.methodName)}}({{ entry.value.stubMethodArgumentListForCustomResponse | join(', ') | raw}}) {
        {{ generateUrlWithPathVariables(entry) }}
        {% if entry.value.hasOptionalMultiValueRequestParams %}
            {{ addRequestParamsToUrl(entry) }}
            stub(httpStatus, response, {{entry.value.httpMethod.name() | lower}}(urlEqualTo(url)));
        {% else %}
            MappingBuilder mappingBuilder = {{entry.value.httpMethod.name() | lower}}(urlPathEqualTo(url));
        {{ addQueryParamsToMappingBuilder(entry) }}
            stub(httpStatus, response, mappingBuilder);
        {% endif %}
    }

    public void verify{{entry.value.methodName}}({{ entry.value.verifyMethodArgumentList | join(', ') | raw}}) {
        verify{{entry.value.methodName}}({{ entry.value.verifyStubCallArgumentList | join(', ') | raw}});
    }

    public void verify{{entry.value.methodName}}({{ entry.value.verifyMethodArgumentListWithTimes | join(', ') | raw}}) {
        {{ generateUrlWithPathVariables(entry) }}
        RequestPatternBuilder requestPatternBuilder = {{entry.value.httpMethod.name() | lower}}RequestedFor(urlPathEqualTo(url));
        {{ addQueryParamsToRequestPatternBuilder(entry) }}
        {{ addRequestHeadersToRequestPatternBuilder(entry) }}
        {% if entry.value.requestBody is not empty%}
            requestPatternBuilder.withRequestBody(equalToJson(buildBody({{ entry.value.requestBody.name }})));
        {% endif %}
        verify(times, requestPatternBuilder);
    }

    {% if entry.value.verifyMethodArgumentListWithTimesWithoutBody != entry.value.verifyMethodArgumentListWithTimes %}
    public void verify{{entry.value.methodName}}({{ entry.value.verifyMethodArgumentListWithTimesWithoutBody | join(', ') | raw}}) {
        {{ generateUrlWithPathVariables(entry) }}
        RequestPatternBuilder requestPatternBuilder = {{entry.value.httpMethod.name() | lower}}RequestedFor(urlPathEqualTo(url));
        {{ addQueryParamsToRequestPatternBuilder(entry) }}
        {{ addRequestHeadersToRequestPatternBuilder(entry) }}
        verify(times, requestPatternBuilder);
    }
    {% endif %}

    public void verify{{entry.value.methodName}}NoInteraction({{ entry.value.verifyMethodArgumentList | join(', ') | raw}}) {
        {{ generateUrlWithPathVariables(entry) }}
        RequestPatternBuilder requestPatternBuilder = {{entry.value.httpMethod.name() | lower}}RequestedFor(urlPathEqualTo(url));
        {{ addQueryParamsToRequestPatternBuilder(entry) }}
        {{ addRequestHeadersToRequestPatternBuilder(entry) }}
        {% if entry.value.requestBody is not empty%}
            requestPatternBuilder.withRequestBody(equalToJson(buildBody({{ entry.value.requestBody.name }})));
        {% endif %}
        verify(NEVER, requestPatternBuilder);
    }

    {% if not entry.value.hasOptionalMultiValueRequestParams and entry.value.verifyMethodArgumentList != entry.value.verifyMethodArgumentListPathVariablesOnly %}
    public void verify{{entry.value.methodName}}NoInteraction({{ entry.value.verifyMethodArgumentListPathVariablesOnly | join(', ') | raw}}) {
        {{ generateUrlWithPathVariables(entry) }}
        verify(NEVER, {{entry.value.httpMethod.name() | lower}}RequestedFor(urlPathEqualTo(url)));
    }
    {% endif %}
{% endfor %}

    void stub(final int status, final String response, final MappingBuilder mappingBuilder) {
        stubFor(mappingBuilder
                .willReturn(
                        aResponse()
                                .withStatus(status)
                                .withBody(response)
                                .withHeader(CONTENT_TYPE_HEADER_NAME, CONTENT_TYPE_HEADER_VALUE)
                )
        );
    }

    String buildBody(final Object object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

{% if model.containsDateTimeFormat %}
    @SuppressWarnings("unchecked")
    String serialise(Object object, String clazz, String iso, String pattern, String style, String...fallbackPatterns) {
        if (annotationFormatterFactory == null) {
            throw new IllegalStateException("annotationFormatterFactory not set");
        }

        DateTimeFormat dateTimeFormat= new DateTimeFormat() {

            @Override
            public Class annotationType() {
                return null;
            }

            @Override
            public String style() {
                return style;
            }

            @Override
            public ISO iso() {
                return ISO.valueOf(iso);
            }

            @Override
            public String pattern() {
                return pattern;
            }

            @Override
            public String[] fallbackPatterns() {
                return fallbackPatterns;
            }
        };
        try {
            Printer printer = annotationFormatterFactory.getPrinter(
                                dateTimeFormat,
                                Class.forName(clazz)
                            );
            return printer.print(object, Locale.getDefault());
        } catch(ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public String joinWithFirstSeparator(String firstSep, String sep, List strings) {
        if (strings.isEmpty()) return "";
        StringBuilder sb = new StringBuilder(strings.get(0));
        for (int i = 1; i < strings.size(); i++) {
            sb.append(i == 1 ? firstSep : sep).append(strings.get(i));
        }
        return sb.toString();
    }
{% endif %}
}
{% macro generateUrlWithPathVariables(entry) %}
String url = String.format({{entry.value.methodName.toUpperCase()}}_URL{% for entry2 in entry.value.pathVariables %}, {{entry2.value.name}} {% endfor %});
{% endmacro %}

{% macro decapitaliseFirstLetterOf(name) %}
{{ name|first|lower }}{{ name | slice(1,name|length) }}
{% endmacro %}

{% macro addRequestParamsToUrl(entry) %}
    {% for entry2 in entry.value.requestParameters %}
if ({{entry2.value.name}} != null) {
        if (!url.contains("?")) { url = url + "?"; } else { url = url + "&"; }
        {% if entry2.value.iterable %}
            url = url + "{{entry2.value.name}}=";
            {% if entry2.value.dateTimeFormatAnnotation is not empty %}
                if (!url.contains("?")) {
                    url = url + joinWithFirstSeparator("?{{entry2.value.name}}=", "&{{entry2.value.name}}=", {{entry2.value.name}}.stream().map(x -> serialise(x, "{{entry2.value.dateTimeFormatAnnotation.clazz}}", "{{entry2.value.dateTimeFormatAnnotation.iso}}", "{{entry2.value.dateTimeFormatAnnotation.pattern | raw}}", "{{entry2.value.dateTimeFormatAnnotation.style}}", "{{entry2.value.dateTimeFormatAnnotation.fallbackPatterns | join('","') | raw}}")).collect(toList()));
                } else {
                    url = url + String.join("&{{entry2.value.name}}=", {{entry2.value.name}}.stream().map(x -> serialise(x, "{{entry2.value.dateTimeFormatAnnotation.clazz}}", "{{entry2.value.dateTimeFormatAnnotation.iso}}", "{{entry2.value.dateTimeFormatAnnotation.pattern | raw}}", "{{entry2.value.dateTimeFormatAnnotation.style}}", "{{entry2.value.dateTimeFormatAnnotation.fallbackPatterns | join('","') | raw}}")).collect(toList()));
                }
            {% else %}
                if (!url.contains("?")) {
                    url = url + joinWithFirstSeparator("?{{entry2.value.name}}=", "&{{entry2.value.name}}=", {{entry2.value.name}}.stream().map(x -> x.toString()).collect(toList()));
                } else {
                    url = url + String.join("&{{entry2.value.name}}=", {{entry2.value.name}}.stream().map(x -> x.toString()).collect(toList()));
                }
            {% endif %}
        {% else %}
            {% if entry2.value.dateTimeFormatAnnotation is not empty %}
                url = url + "{{entry2.value.name}}=" + serialise({{entry2.value.name}}, "{{entry2.value.dateTimeFormatAnnotation.clazz}}", "{{entry2.value.dateTimeFormatAnnotation.iso}}", "{{entry2.value.dateTimeFormatAnnotation.pattern | raw}}", "{{entry2.value.dateTimeFormatAnnotation.style}}", "{{entry2.value.dateTimeFormatAnnotation.fallbackPatterns | join('","') | raw}}");
            {% else %}
                url = url + "{{entry2.value.name}}=" + {{entry2.value.name}};
            {% endif %}
        {% endif %}
}
    {% endfor %}
{% endmacro %}

{% macro addQueryParamsToMappingBuilder(entry) %}
    {% for entry2 in entry.value.requestParameters %}
        {% if entry2.value.iterable %}
            {#Optional iterable cannot be handled with mapping builder.  #}
            {% if entry2.value.dateTimeFormatAnnotation is not empty %}
                mappingBuilder.withQueryParam("{{entry2.value.name}}", havingExactly({{entry2.value.name}}.stream().map(x -> serialise(x, "{{entry2.value.dateTimeFormatAnnotation.clazz}}", "{{entry2.value.dateTimeFormatAnnotation.iso}}", "{{entry2.value.dateTimeFormatAnnotation.pattern | raw}}", "{{entry2.value.dateTimeFormatAnnotation.style}}", "{{entry2.value.dateTimeFormatAnnotation.fallbackPatterns | join('","') | raw}}")).toArray(String[]::new)));
            {% else %}
                mappingBuilder.withQueryParam("{{entry2.value.name}}", havingExactly({{entry2.value.name}}.stream().map(x -> x.toString()).toArray(String[]::new)));
            {% endif %}

        {% else %}

            {% if entry2.value.optional %}
                {% if entry2.value.dateTimeFormatAnnotation is not empty %}
                    mappingBuilder.withQueryParam("{{entry2.value.name}}", equalTo(serialise({{entry2.value.name}}, "{{entry2.value.dateTimeFormatAnnotation.clazz}}", "{{entry2.value.dateTimeFormatAnnotation.iso}}", "{{entry2.value.dateTimeFormatAnnotation.pattern | raw}}", "{{entry2.value.dateTimeFormatAnnotation.style}}", "{{entry2.value.dateTimeFormatAnnotation.fallbackPatterns | join('","') | raw}}")).or(absent()));
                {% else %}
                    mappingBuilder.withQueryParam("{{entry2.value.name}}", equalTo(String.valueOf({{entry2.value.name}})).or(absent()));
                {% endif %}
            {% else %}
                {% if entry2.value.dateTimeFormatAnnotation is not empty %}
                    mappingBuilder.withQueryParam("{{entry2.value.name}}", equalTo(serialise({{entry2.value.name}}, "{{entry2.value.dateTimeFormatAnnotation.clazz}}", "{{entry2.value.dateTimeFormatAnnotation.iso}}", "{{entry2.value.dateTimeFormatAnnotation.pattern | raw}}", "{{entry2.value.dateTimeFormatAnnotation.style}}", "{{entry2.value.dateTimeFormatAnnotation.fallbackPatterns | join('","') | raw}}")));
                {% else %}
                    mappingBuilder.withQueryParam("{{entry2.value.name}}", equalTo(String.valueOf({{entry2.value.name}})));
                {% endif %}
            {% endif %}

        {% endif %}
    {% endfor %}
{% endmacro %}

{% macro addQueryParamsToRequestPatternBuilder(entry) %}
    {% for entry2 in entry.value.requestParameters %}
        {% if entry2.value.optional %}
if ({{entry2.value.name}} != null) {
        {% endif %}
        {% if entry2.value.iterable %}
            {% if entry2.value.dateTimeFormatAnnotation is not empty %}
            requestPatternBuilder.withQueryParam("{{entry2.value.name}}", havingExactly({{entry2.value.name}}.stream().map(x -> serialise(x, "{{entry2.value.dateTimeFormatAnnotation.clazz}}", "{{entry2.value.dateTimeFormatAnnotation.iso}}", "{{entry2.value.dateTimeFormatAnnotation.pattern | raw}}", "{{entry2.value.dateTimeFormatAnnotation.style}}", "{{entry2.value.dateTimeFormatAnnotation.fallbackPatterns | join('","') | raw}}")).toArray(String[]::new)));
            {% else %}
            requestPatternBuilder.withQueryParam("{{entry2.value.name}}", havingExactly({{entry2.value.name}}.stream().map(x -> x.toString()).toArray(String[]::new)));
            {% endif %}
        {% else %}
            {% if entry2.value.dateTimeFormatAnnotation is not empty %}
            requestPatternBuilder.withQueryParam("{{entry2.value.name}}", equalTo(serialise({{entry2.value.name}}, "{{entry2.value.dateTimeFormatAnnotation.clazz}}", "{{entry2.value.dateTimeFormatAnnotation.iso}}", "{{entry2.value.dateTimeFormatAnnotation.pattern | raw}}", "{{entry2.value.dateTimeFormatAnnotation.style}}", "{{entry2.value.dateTimeFormatAnnotation.fallbackPatterns | join('","') | raw}}")));
            {% else %}
            requestPatternBuilder.withQueryParam("{{entry2.value.name}}", equalTo(String.valueOf({{entry2.value.name}})));
            {% endif %}
        {% endif %}
        {% if entry2.value.optional %}
}
        {% endif %}
    {% endfor %}
{% endmacro %}

{% macro addRequestHeadersToRequestPatternBuilder(entry) %}
    {% for entry2 in entry.value.requestHeaders %}
        {% if entry2.value.optional %}
            if ({{entry2.value.name}} != null) {
        {% endif %}
        requestPatternBuilder.withHeader("{{entry2.value.headerName}}", matching(String.valueOf({{entry2.value.name}})));
        {% if entry2.value.optional %}
            }
        {% endif %}
    {% endfor %}
{% endmacro %}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy