diff --git a/page-factory-api/src/main/java/ru/sbtqa/tag/pagefactory/annotations/rest/Endpoint.java b/page-factory-api/src/main/java/ru/sbtqa/tag/pagefactory/annotations/rest/Endpoint.java index a40a5e3bd..483b19418 100644 --- a/page-factory-api/src/main/java/ru/sbtqa/tag/pagefactory/annotations/rest/Endpoint.java +++ b/page-factory-api/src/main/java/ru/sbtqa/tag/pagefactory/annotations/rest/Endpoint.java @@ -48,4 +48,10 @@ * @return path to template */ String template() default ""; + + /** + * Remove empty objects like "key":{} from template + * @return {@link Boolean} + */ + boolean shouldRemoveEmptyObjects() default false; } diff --git a/page-factory-doc/src/main/asciidoc/rest-plugin.asciidoc b/page-factory-doc/src/main/asciidoc/rest-plugin.asciidoc index 3cb0b7b3e..0a677a335 100644 --- a/page-factory-doc/src/main/asciidoc/rest-plugin.asciidoc +++ b/page-factory-doc/src/main/asciidoc/rest-plugin.asciidoc @@ -33,6 +33,8 @@ include::rest_build_request.asciidoc[] include::rest_steps_en.asciidoc[] +include::rest_properties.asciidoc[] + === SSL Включить упрощенную схему работы с ssl можно следующим образом: [source,] diff --git a/page-factory-doc/src/main/asciidoc/rest_entries.asciidoc b/page-factory-doc/src/main/asciidoc/rest_entries.asciidoc index ad3b5a853..d0c6d5685 100644 --- a/page-factory-doc/src/main/asciidoc/rest_entries.asciidoc +++ b/page-factory-doc/src/main/asciidoc/rest_entries.asciidoc @@ -9,6 +9,7 @@ * `path` - путь, относительно заданного в `api.baseURI` * `title` - имя метода для обращения из тестового сценария * `template` - шаблон запроса +* `shouldRemoveEmptyObjects` - необходимо ли удалять пустые объекты в шаблоне *__Пример:__* [source,] diff --git a/page-factory-doc/src/main/asciidoc/rest_entries_param.asciidoc b/page-factory-doc/src/main/asciidoc/rest_entries_param.asciidoc index 153da2317..96cbb00c4 100644 --- a/page-factory-doc/src/main/asciidoc/rest_entries_param.asciidoc +++ b/page-factory-doc/src/main/asciidoc/rest_entries_param.asciidoc @@ -48,6 +48,8 @@ public class ReplacerEntry extends EndpointEntry { При этом подстановка в шаблон будет выполнена по соответствию параметра `name` аннотации `@Body` и значения, обозначенного через `${}` +Если необходимо из шаблона удалять пустые объекты вида `"key": { }`, то в конфигурационном файле необходимо указать параметр `api.template.remove.empties = true` + BodyArray используется для параметризации массивов. Элементы массива приводятся к одному типу. Если надо в строковом типе поставить запятую, то она экранируется обратным слешем в фиче. diff --git a/page-factory-doc/src/main/asciidoc/rest_properties.asciidoc b/page-factory-doc/src/main/asciidoc/rest_properties.asciidoc new file mode 100644 index 000000000..e2f6ad3ac --- /dev/null +++ b/page-factory-doc/src/main/asciidoc/rest_properties.asciidoc @@ -0,0 +1,38 @@ +=== Настройки проекта +[width="100%",options="header,footer"] +|==================== +^.^| Параметр ^.^| Описание ^.^| Значение по умолчанию +| api.baseURI +| Базовый урл + +Пример: https//localhost:8080 +| + +| api.endpoint.package +| Путь к Endpoint объектам + +Пример: ru.qa.rest +| + +| api.template.encoding +| Кодировка шаблона +| UTF-8 + +| api.ssl.relaxed +| Упрощенная схема работы с ssl + +Возможные значения: true или false. +| false + +| api.template.remove.optional +| Удалять опциональные параметры, которые после подстановки параметров в шаблон, остались с плейхолдером + +Возможные значения: true или false. +| true + +| api.template.remove.empties +| Удалять пустые вида "key": { } из шаблона + +Возможные значения: true или false. +| false +|==================== \ No newline at end of file diff --git a/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/EndpointEntry.java b/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/EndpointEntry.java index c00286f65..5e4147cb9 100644 --- a/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/EndpointEntry.java +++ b/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/EndpointEntry.java @@ -40,6 +40,7 @@ public class EndpointEntry implements ApiEndpoint { private String path; private final String template; private final String title; + private final boolean shouldRemoveEmptyObjects; public EndpointEntry() { Endpoint endpoint = this.getClass().getAnnotation(Endpoint.class); @@ -48,6 +49,7 @@ public EndpointEntry() { host = endpoint.host(); template = endpoint.template(); title = endpoint.title(); + shouldRemoveEmptyObjects = endpoint.shouldRemoveEmptyObjects(); reflection = new EndpointEntryReflection(this); blankStorage = ApiEnvironment.getBlankStorage(); @@ -151,10 +153,18 @@ private RequestSpecification buildRequest() { public String getBody() { String body = TemplateUtils.loadFromResources(this.getClass(), template, PROPERTIES.getTemplateEncoding()); + Map parameters = getParameters(); if(template.endsWith(".json")) { - return PlaceholderUtils.replaceJsonTemplatePlaceholders(this.reflection.getEndpoint(), body, getParameters()); + String result = PlaceholderUtils.replaceJsonTemplatePlaceholders(this.reflection.getEndpoint(), body, parameters); + if (PROPERTIES.shouldRemoveOptional()) { + result = PlaceholderUtils.removeOptionals(result, parameters); + } + if (PROPERTIES.shouldRemoveEmptyObjects() || shouldRemoveEmptyObjects) { + result = PlaceholderUtils.removeEmptyObjects(result); + } + return result; } else { - return PlaceholderUtils.replaceTemplatePlaceholders(this.reflection.getEndpoint(), body, getParameters()); + return PlaceholderUtils.replaceTemplatePlaceholders(this.reflection.getEndpoint(), body, parameters); } } diff --git a/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/properties/ApiConfiguration.java b/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/properties/ApiConfiguration.java index 077de184e..c54093b9f 100644 --- a/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/properties/ApiConfiguration.java +++ b/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/properties/ApiConfiguration.java @@ -20,6 +20,14 @@ public interface ApiConfiguration extends Config { @DefaultValue("false") boolean isSslRelaxed(); + @Key("api.template.remove.optional") + @DefaultValue("true") + boolean shouldRemoveOptional(); + + @Key("api.template.remove.empties") + @DefaultValue("false") + boolean shouldRemoveEmptyObjects(); + static ApiConfiguration create() { return Configuration.init(ApiConfiguration.class); } diff --git a/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/utils/PlaceholderUtils.java b/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/utils/PlaceholderUtils.java index 3d28bbeec..b150abd32 100644 --- a/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/utils/PlaceholderUtils.java +++ b/plugins/rest-plugin/src/main/java/ru/sbtqa/tag/api/utils/PlaceholderUtils.java @@ -87,7 +87,7 @@ public static String replaceJsonTemplatePlaceholders(EndpointEntry entry, String } - return removeOptionals(jsonString, parameters); + return jsonString; } private static boolean isFieldExists(EndpointEntry entry, String fieldName) { @@ -95,7 +95,7 @@ private static boolean isFieldExists(EndpointEntry entry, String fieldName) { .anyMatch(field -> field.getName().equals(fieldName)); } - private static String removeOptionals(String jsonString, Map parameters) { + public static String removeOptionals(String jsonString, Map parameters) { Set> optionals = parameters.entrySet().stream() .filter(stringObjectEntry -> stringObjectEntry.getValue() == null) .collect(Collectors.toSet()); @@ -109,6 +109,11 @@ private static String removeOptionals(String jsonString, Map par return jsonString.replaceAll(orphanCommaRegex, "$2"); } + public static String removeEmptyObjects(String jsonString) { + String regex = "\"[\\w]+\"[\\s\\r\\n]*:[\\s\\r\\n]*\\{[\\s\\r\\n]*}[\\s\\r\\n,]*"; + return jsonString.replaceAll(regex, ""); + } + /** * Replace placeholder in string on value * diff --git a/plugins/rest-plugin/src/test/java/ru/sbtqa/tag/api/entries/template/EmptyObjectsEntry.java b/plugins/rest-plugin/src/test/java/ru/sbtqa/tag/api/entries/template/EmptyObjectsEntry.java new file mode 100644 index 000000000..ae335de4f --- /dev/null +++ b/plugins/rest-plugin/src/test/java/ru/sbtqa/tag/api/entries/template/EmptyObjectsEntry.java @@ -0,0 +1,24 @@ +package ru.sbtqa.tag.api.entries.template; + +import ru.sbtqa.tag.api.EndpointEntry; +import ru.sbtqa.tag.api.annotation.Body; +import ru.sbtqa.tag.api.annotation.Header; +import ru.sbtqa.tag.api.annotation.Validation; +import ru.sbtqa.tag.pagefactory.Rest; +import ru.sbtqa.tag.pagefactory.annotations.rest.Endpoint; + +import static org.hamcrest.Matchers.equalTo; + +@Endpoint(method = Rest.POST, path = "client/typed-arrays", title = "empty objects", template = "templates/EmptyObjects.json", shouldRemoveEmptyObjects = true) +public class EmptyObjectsEntry extends EndpointEntry { + + @Body(name = "first") + private String first; + + @Validation(title = "result") + public void validate() { + String expected = "{ " + + "\"first\" : \"parameter\" }"; + getResponse().body("result", equalTo(expected)); + } +} \ No newline at end of file diff --git a/plugins/rest-plugin/src/test/java/ru/sbtqa/tag/api/entries/template/TypedArraysEntry.java b/plugins/rest-plugin/src/test/java/ru/sbtqa/tag/api/entries/template/TypedArraysEntry.java index b25911094..0e5ed533a 100644 --- a/plugins/rest-plugin/src/test/java/ru/sbtqa/tag/api/entries/template/TypedArraysEntry.java +++ b/plugins/rest-plugin/src/test/java/ru/sbtqa/tag/api/entries/template/TypedArraysEntry.java @@ -35,4 +35,4 @@ public void validate() { "}] }"; getResponse().body("result", equalTo(expected)); } -} +} \ No newline at end of file diff --git a/plugins/rest-plugin/src/test/resources/features/Template.feature b/plugins/rest-plugin/src/test/resources/features/Template.feature index 1b4d14366..ca1ee4b08 100644 --- a/plugins/rest-plugin/src/test/resources/features/Template.feature +++ b/plugins/rest-plugin/src/test/resources/features/Template.feature @@ -8,3 +8,9 @@ Feature: Test template placeholder replacing | day1 | null | | day11 | "null" | * system returns "works correctly" + + @empty-objects + Scenario: Test template placeholder replacing with empty objects + * user sends request for "empty objects" with parameters + | first | parameter | + * system returns "result" diff --git a/plugins/rest-plugin/src/test/resources/templates/EmptyObjects.json b/plugins/rest-plugin/src/test/resources/templates/EmptyObjects.json new file mode 100644 index 000000000..5d80a8fb6 --- /dev/null +++ b/plugins/rest-plugin/src/test/resources/templates/EmptyObjects.json @@ -0,0 +1,16 @@ +{ + "minusOne": { + + }, + "zero": { }, + "first": "${first}", + "second": { }, + "third": { + + + + }, + "four": {} +, "fifth":{},"sixth":{},"seventh": +{ } +} \ No newline at end of file