/
koskv
/
TeamSync-Tests
Обзор
Документация
Войти
/
koskv
/
TeamSync-Tests
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/main/java/TeamSyncTest/utils/api/ApiMethods_old.java
1 007 строк
42 KB
Koskv
Ref: Правка тестового класса TaskContract
17 ноя 2025, 23:06
17 ноя 2025, 23:06
1a00e45
Код
Авторство
О чём код?
package TeamSyncTest.utils.api; import TeamSyncTest.constants.Endpoints; import TeamSyncTest.models.auth.AuthRequest; import TeamSyncTest.models.response.ApiResponse; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import io.qameta.allure.Allure; import io.qameta.allure.Step; import io.restassured.RestAssured; import io.restassured.common.mapper.TypeRef; import io.restassured.config.ObjectMapperConfig; import io.restassured.http.ContentType; import io.restassured.response.Response; import io.restassured.response.ValidatableResponse; import io.restassured.specification.RequestSpecification; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springframework.util.StringUtils; import org.springframework.stereotype.Component; import org.springframework.http.HttpHeaders; import java.util.List; import java.util.Map; import static TeamSyncTest.constants.HttpStatus.*; import static io.restassured.RestAssured.given; @Component @Slf4j @RequiredArgsConstructor public class ApiMethods_old { /* private final ObjectMapper objectMapper; // Константы private static final String CONTENT_TYPE_HEADER = HttpHeaders.CONTENT_TYPE; private static final String APPLICATION_JSON = MediaType.APPLICATION_JSON_VALUE; private static final String APPLICATION_XML = MediaType.APPLICATION_XML_VALUE; private static final String AUTHORIZATION_HEADER = "Authorization"; private static final String BEARER_PREFIX = "Bearer "; // ======================================================================== // Инициализация Rest RestAssured с нашим ObjectMapper // ======================================================================== @PostConstruct public void init() { RestAssured.config = RestAssured.config() .objectMapperConfig(new ObjectMapperConfig() .jackson2ObjectMapperFactory((cls, charset) -> objectMapper)); log.info("RestAssured настроен с ObjectMapper: JavaTimeModule={}, FAIL_ON_UNKNOWN={}", objectMapper.getRegisteredModuleIds().contains("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule"), objectMapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); } // Метод получения токена для выполнения API тестов ---------------------- public String getAuthenticationToken(String username, String password) { try { // Данные для аутентификации AuthRequest authRequest = new AuthRequest(username, password); // Замените на реальные credentials // Отправляем запрос на аутентификацию String token = given() .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .body(authRequest) .when() .post(Endpoints.BASE_URL + Endpoints.AUTH_API) .then() .statusCode(OK) .extract() .path("token"); // Убираем "Bearer " если он есть в ответе if (token != null && token.startsWith("Bearer ")) { token = token.substring(7); } log.info("JWT token successfully obtained"); System.out.println("Получен токен: " + token); return token; } catch (Exception e) { log.error("Failed to obtain JWT token: {}", e.getMessage()); throw new RuntimeException("Authentication failed", e); } } // Основной метод создания запроса ================================================ protected RequestSpecification createRequest(String authToken) { RequestSpecification request = given() .header(CONTENT_TYPE_HEADER, APPLICATION_JSON); if (StringUtils.hasText(authToken)) { request.header(AUTHORIZATION_HEADER, BEARER_PREFIX + authToken.trim()); } return request; } // Основной метод создания запроса с возможностью указать Content-Type protected RequestSpecification createRequest(String authToken, String contentType) { RequestSpecification request = given() .header(CONTENT_TYPE_HEADER, contentType); if (StringUtils.hasText(authToken)) { request.header(AUTHORIZATION_HEADER, BEARER_PREFIX + authToken.trim()); } return request; } // Универсальный метод для выполнения запросов private <T> T executeRequest(Class<T> responseType, String method, String url, Object body, String authToken, int expectedStatus) { RequestSpecification request = createRequest(authToken); if (body != null) { request.body(body); } return request .when() .request(method, url) .then() .log().ifError() .statusCode(expectedStatus) .extract() .as(responseType); } *//** * Выполняет запрос и возвращает сырой Response (без десериализации и без проверки статуса) *//* private Response executeRawRequest(String method, String url, Object body, String authToken) { RequestSpecification request = createRequest(authToken); if (body != null) { request.body(body); } return request .when() .request(method, url) .then() .log().ifError() .extract().response(); } *//** * Универсальный метод для выполнения запросов, возвращающих списки *//* private <T> List<T> executeRequestForList(Class<T> elementType, String method, String url, Object body, String authToken, int expectedStatus) { RequestSpecification request = createRequest(authToken); if (body != null) { request.body(body); } return request .when() .request(method, url) .then() .log().ifError() .statusCode(expectedStatus) .extract() .body() .jsonPath() .getList(".", elementType); } *//** * * @param elementType * @param method - метод * @param url - эндпоинт * @param body - тело запроса если нужно * @param object - объект со списком для извлечения (точное указание) * @param authToken - токен авторизации * @param expectedStatus - ожидаемый статус код * @return * @param <T> *//* private <T> List<T> executeRequestGetList(Class<T> elementType, String method, String url, Object body, String object, String authToken, int expectedStatus) { RequestSpecification request = createRequest(authToken); if (body != null) { request.body(body); } return request .when() .request(method, url) .then() .log().ifError() .statusCode(expectedStatus) .extract() .body() .jsonPath() .getList(object, elementType); } // ----- GET BY ID записи ---------------------------- *//** * GET запрос для получения одной записи по ID БЕЗ авторизации *//* @Step("Получение одной записи из базы данных") public <T> T getById(Class<T> clazz, String service, Long id) { return getById(clazz, service, id, null); } *//** * GET запрос для получения одной записи по ID с авторизацией *//* @Step("Получение одной записи из базы данных") public <T> T getById(Class<T> clazz, String service, Long id, String authToken) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("GET request to: {}", url); T response = executeRequest(clazz, "GET", url, null, authToken, OK); // Добавляем полученную сущность как вложение в Allure attachResponseToAllure(response, "Полученная запись", service, id, OK); return response; } *//** * GET запрос для получения одной записи по ID с возвратом статуса и тела *//* @Step("Получение записи по ID: {id}") public <T> ApiResponse<T> getByIdWithResponse( Class<T> clazz, String service, Long id, String authToken ) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("GET request to: {}", url); Response response = executeRawRequest("GET", url, null, authToken); int statusCode = response.getStatusCode(); T body = response.as(clazz); attachResponseToAllure(body, "Полученная запись", service, id, statusCode); return new ApiResponse<>(statusCode, body); } *//** * Запрос на получение несуществующей записи - Negative - БЕЗ авторизации *//* @Step("Получение одной записи из базы данных") public <T> T getByIdExpectingError(Class<T> clazz, String service, Long id, int statusCode) { return getByIdExpectingError(clazz, service, id, statusCode, null); } *//** * Запрос на получение несуществующей записи - Negative - с авторизацией *//* @Step("Получение одной записи из базы данных - ожидается ошибка") public <T> T getByIdExpectingError(Class<T> clazz, String service, Long id, int statusCode, String authToken) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("GET request to: {}", url); return executeRequest(clazz, "GET", url, null, authToken, statusCode); } @Step("Получение записи по ID: {id} → ожидается ошибка") public <T> ApiErrorResponse<T> getByIdExpectingErrorWithResponse( Class<T> clazz, String service, Long id, String authToken ) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("GET request to: {}", url); Response response = executeRawRequest("GET", url, null, authToken); int statusCode = response.getStatusCode(); T body = response.as(clazz); String attachmentName = "Ошибка " + statusCode + " при GET"; attachResponseToAllure(body, attachmentName, service, id, statusCode); return new ApiErrorResponse<>(statusCode, body); } *//** * Запрос на получение несуществующей записи - Negative - с авторизацией * Для строковых ID (для тестирования валидации) *//* @Step("Получение одной записи по строковому ID - ожидается ошибка") public <T> T getByIdExpectingError(Class<T> clazz, String service, String id, int statusCode, String authToken) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("GET request to: {}", url); return executeRequest(clazz, "GET", url, null, authToken, statusCode); } @Step("Получение записи по строковому ID: {id} → ожидается ошибка") public <T> ApiErrorResponse<T> getByIdExpectingErrorWithResponse( Class<T> clazz, String service, String id, String authToken ) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("GET request to: {}", url); Response response = executeRawRequest("GET", url, null, authToken); int statusCode = response.getStatusCode(); T body = response.as(clazz); attachResponseToAllure(body, "Ошибка " + statusCode + " (строковый ID)", service, null, statusCode); return new ApiErrorResponse<>(statusCode, body); } //------------------------------------------------------------------------------------ *//** * GET запрос для получения ПОСЛЕДНЕЙ записи по ID *//* @Step("Получение одной записи из базы данных") public <T> T getLastById(Class<T> clazz, String service, int statusCode) { return getLastById(clazz, service, null, statusCode); } *//** * GET запрос для получения ПОСЛЕДНЕЙ записи по ID - с авторизацией *//* @Step("Получение одной - последней записи из базы данных") public <T> T getLastById(Class<T> clazz, String service, String authToken, int statusCode) { String url = Endpoints.BASE_URL + service + "/last"; log.debug("GET request to: {}", url); return executeRequest(clazz, "GET", url, null, authToken, statusCode); } //------ GET_ALL ------------------------------------------------------------ *//** * GET запрос для получения всех записей *//* @Step("Получение всех записей из базы данных") public <T> List<T> getAll(Class<T> clazz, String service) { return getAll(clazz, service, null); } *//** * GET запрос для получения всех записей с авторизацией *//* @Step("Получение всех записей из базы данных") public <T> List<T> getAll(Class<T> clazz, String service, String authToken) { String url = Endpoints.BASE_URL + service; log.debug("GET ALL request to: {}", url); return executeRequestForList(clazz, "GET", url, null, authToken, OK); } *//** * GET запрос для получения всех записей с авторизацией из Content * @param clazz - указать класс для парсинга * @param service - эндпоинт * @param object - поле которое содержит нужный список * @param authToken - токен авторизации * @return * @param <T> *//* @Step("Получение всех записей из базы данных - из нужного объекта ") public <T> List<T> getAllContent(Class<T> clazz, String service, String object, String authToken) { String url = Endpoints.BASE_URL + service; log.debug("GET ALL request to: {}", url); return executeRequestGetList(clazz, "GET", url, null, object, authToken, OK); } //------------------------------------------------------------------------------------ *//** * GET all By запрос для получения всех записей по какому то ID *//* @Step("Получение всех записей из базы данных") public <T> List<T> getAllById(Class<T> clazz, String service, Long id) { return getAllById(clazz, service, id, null); } *//** * GET all By запрос для получения всех записей по какому то ID - с авторизацией *//* @Step("Получение всех записей из базы данных") public <T> List<T> getAllById(Class<T> clazz, String service, Long id, String authToken) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("GET ALL By ID request to: {}", url); return executeRequestForList(clazz, "GET", url, null, authToken, OK); } //----------- CREATE ---------------------------------------------------------------- *//** * POST запрос для создания новой записи *//* @Step("Создать запись в базе данных") public <T, A> T create(Class<T> clazz, A requestBody, String service) { return create(clazz, requestBody, service, null); } *//** * POST запрос для создания новой записи с авторизацией *//* @Step("Создать запись в базе данных") public <T, A> T create(Class<T> clazz, A requestBody, String service, String authToken) { String url = Endpoints.BASE_URL + service; log.debug("POST request to: {}", url); T response = executeRequest(clazz, "POST", url, requestBody, authToken, CREATED); // Добавляем созданную сущность как вложение в Allure attachResponseToAllure(response, "Созданная запись в БД", service, null, CREATED); return response; } @Step("Создать запись в базе данных") public <T, A> ApiResponse<T> createNew(Class<T> clazz, A requestBody, String service, String authToken) { String url = Endpoints.BASE_URL + service; log.debug("POST request to: {}", url); // Предполагается, что executeRequest возвращает ValidatableResponse или Response Response response = given() .header("Authorization", "Bearer " + authToken) .contentType(ContentType.JSON) .body(requestBody) .when() .post(url) .then() // Уберите .assertThat().statusCode(CREATED) — проверку перенесём в тест .extract().response(); int statusCode = response.getStatusCode(); T body = response.as(clazz); // Вложение в Allure: тело + статус attachResponseToAllure(body, "Созданная запись (HTTP " + statusCode + ")", service, null, statusCode); return new ApiResponse<>(statusCode, body); } *//** * PUT запрос для обновления записи с авторизацией *//* @Step("Обновить запись в базе данных - успех") public <T, R> ApiResponse<T> updateNew(Class<T> clazz, R requestBody, String service, Long id, String authToken) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("PUT request to: {}", url); Response response = given() .header("Authorization", "Bearer " + authToken) .contentType(ContentType.JSON) .body(requestBody) .when() .put(url) .then() // .assertThat().statusCode(OK) — проверка в тестах .extract().response(); int statusCode = response.getStatusCode(); T body = response.as(clazz); // Добавляем обновленную сущность как вложение в Allure attachResponseToAllure(body,"Обновлена запись с id: " + id + " (HTTP " + statusCode + ")", service, id, statusCode); return new ApiResponse<>(statusCode, body); } //--------CREATE EXPECTING ERROR -------------------------------------------------------------------- *//** * Запрос возвращающий ошибку создания записи *//* @Step("Создание записи сопровождающееся ошибкой") public <T, A> T createExpectingError(Class<T> clazz, A requestBody, String service, int statusCode) { return createExpectingError(clazz, requestBody, service, null, statusCode); } *//** * Запрос возвращающий ошибку создания записи с авторизацией *//* @Step("Создание записи сопровождающееся ошибкой") public <T, A> T createExpectingError(Class<T> clazz, A requestBody, String service, String authToken, int expectedStatus) { String url = Endpoints.BASE_URL + service; log.debug("POST request to: {}", url); T response = executeRequest(clazz, "POST", url, requestBody, authToken, expectedStatus); attachResponseToAllure(response, "Сообщение об ошибке: ", service, null, expectedStatus); return response; } *//** * Запрос возвращающий ошибку создания записи с авторизацией *//* @Step("Создание записи сопровождающееся ошибкой") public <T> T createExpectingError(Class<T> clazz, String service, String authToken, int expectedStatus) { String url = Endpoints.BASE_URL + service; log.debug("POST request to: {}", url); return executeRequest(clazz, "POST", url, null, authToken, expectedStatus); } @Step("Создание записи с ожидаемой ошибкой {expectedStatus}") public <T, A> ApiErrorResponse<T> createExpectingErrorNew( Class<T> clazz, A requestBody, String service, String authToken, int expectedStatus ) { String url = Endpoints.BASE_URL + service; log.debug("POST request to: {} (ожидается {})", url, expectedStatus); // Выполняем запрос БЕЗ автоматической проверки статуса внутри executeRequest Response response = given() .header("Authorization", "Bearer " + authToken) .contentType(ContentType.JSON) .body(requestBody) .when() .post(url) // НЕ вызываем .then().statusCode(expectedStatus) здесь! .then() .extract().response(); int actualStatus = response.getStatusCode(); T body = response.as(clazz); // Проверяем статус уже в тесте (через assert) // Но для логики — возвращаем его String attachmentName = String.format("Ошибка %d: %s", actualStatus, clazz.getSimpleName()); attachResponseToAllure(body, attachmentName, service, null, actualStatus); // ← добавили statusCode return new ApiErrorResponse<>(actualStatus, body); } @Step("Обновление записи сопровождающееся ошибкой") public <T, A> ApiErrorResponse<T> updateExpectingErrorNew(Class<T> clazz, A requestBody, String service, Long id, String authToken, int statusCode) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("POST request to: {}", url); // Выполняем запрос БЕЗ автоматической проверки статуса внутри executeRequest Response response = given() .header("Authorization", "Bearer " + authToken) .contentType(ContentType.JSON) .body(requestBody) .when() .put(url) // НЕ вызываем .then().statusCode(expectedStatus) здесь! .then() .extract().response(); int actualStatus = response.getStatusCode(); T body = response.as(clazz); String attachmentName = String.format("Ошибка %d: %s", actualStatus, clazz.getSimpleName()); attachResponseToAllure(body, attachmentName, service, null, actualStatus); // ← добавили statusCode return new ApiErrorResponse<>(actualStatus, body); } // ======================================================================== @Step("Создание записи с не-JSON телом") public <T> T createWithNonJsonBody(Class<T> clazz, String nonJsonBody, String contentType, String service, String authToken, int expectedStatus) { String url = Endpoints.BASE_URL + service; log.debug("POST request to: {} with Content-Type: {}", url, contentType); RequestSpecification request = createRequest(authToken); // Явно устанавливаем Content-Type и отправляем как строку request.contentType(contentType) .body(nonJsonBody); return request .when() .post(url) .then() .log().ifError() .statusCode(expectedStatus) .extract() .as(clazz); } // -------- UPDATE ----------------------------------------------------------------- *//** * PUT запрос для обновления записи *//* @Step("Обновить запись в базе данных - успех") public <T, R> T update(Class<T> clazz, R requestBody, String service, Long id) { return update(clazz, requestBody, service, null); } *//** * PUT запрос для обновления записи с авторизацией *//* @Step("Обновить запись в базе данных - успех") public <T, R> T update(Class<T> clazz, R requestBody, String service, Long id, String authToken) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("POST request to: {}", url); T response = executeRequest(clazz, "PUT", url, requestBody, authToken, OK); // Добавляем обновленную сущность как вложение в Allure attachResponseToAllure(response, "Обновленная запись в БД", service, id, OK); return response; } *//** * Запрос возвращающий ошибку на обновлении записи - с авторизацией *//* @Step("Обновление записи сопровождающееся ошибкой") public <T, A> T updateExpectingError(Class<T> clazz, A requestBody, String service, Long id, int statusCode) { return updateExpectingError(clazz, requestBody, service, id, null, statusCode); } *//** * Запрос возвращающий ошибку на обновлении записи - с авторизацией *//* @Step("Обновление записи сопровождающееся ошибкой") public <T, A> T updateExpectingError(Class<T> clazz, A requestBody, String service, Long id, String authToken, int statusCode) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("POST request to: {}", url); return executeRequest(clazz, "PUT", url, requestBody, authToken, statusCode); } @Step("Создание записи с не-JSON телом") public <T> T updateWithNonJsonBody(Class<T> clazz, String nonJsonBody, String contentType, String service, String authToken, int expectedStatus) { String url = Endpoints.BASE_URL + service; log.debug("POST request to: {} with Content-Type: {}", url, contentType); RequestSpecification request = createRequest(authToken); // Явно устанавливаем Content-Type и отправляем как строку request.contentType(contentType) .body(nonJsonBody); return request .when() .put(url) .then() .log().ifError() .statusCode(expectedStatus) .extract() .as(clazz); } // --------------- PATCH ------------------------------------------------------- *//** * PATCH запрос для частичного обновления записи * @param clazz класс объекта ответа * @param pathParams параметры пути (например, ID) * @param queryParams параметры запроса (например, status) * @param service endpoint сервиса * @return обновленный объект *//* @Step("Обновить запись в базе данных") public <T> T patch(Class<T> clazz, Map<String, ?> pathParams, Map<String, ?> queryParams, String service) { return given() .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .pathParams(pathParams) .queryParams(queryParams) .when() .patch(Endpoints.BASE_URL + service) .then() .log().all() .statusCode(OK) .extract() .as(clazz); } // --------------- DELETE ------------------------------------------------- *//** * DELETE запрос для удаления записи *//* @Step("Удалить запись из базы данных") public void delete(String service, Long id, int statusCode) { delete(service, id, null, statusCode); } *//** * DELETE запрос для удаления записи с авторизацией *//* @Step("Удалить запись из базы данных") public void delete(String service, Long id, String authToken, int statusCode) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("DELETE request to: {} for ID: {}", url, id); createRequest(authToken) .when() .delete(url) .then() .statusCode(statusCode); } *//** * DELETE запрос для удаления записи - вызывает ошибку - с авторизацией * @param service endpoint сервиса (должен включать ID) *//* @Step("Удалить запись из базы данных - ожидаем ошибку") public <T> T deleteExpectingError(Class<T> clazz, String service, int statusCode, Long id) { return deleteExpectingError(clazz, service, id, null, statusCode); } *//** * DELETE запрос для удаления записи - вызывает ошибку - с авторизацией * @param service endpoint сервиса (должен включать ID) *//* @Step("Удалить запись из базы данных - ожидаем ошибку") public <T> T deleteExpectingError(Class<T> clazz, String service, Long id, String authToken, int statusCode) { System.out.println("Try delete Item with ID: " + id); System.out.println("ENDPOINT: " + Endpoints.BASE_URL + service + "/" + id); RequestSpecification request = given() .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); // Добавляем заголовок авторизации если передан токен if (authToken != null && !authToken.trim().isEmpty()) { request.header("Authorization", "Bearer " + authToken); } return request .when() .delete(Endpoints.BASE_URL + service + "/" + id) .then() .log().ifError() .statusCode(statusCode) .extract() .as(clazz); } //----------------------------------------------------------------------------------- *//** * Получение записи по параметрам *//* @Step("Получить список данных с параметрами") public <T> List<T> getWithParams(Class<T> clazz, Map<String, ?> pathParams, Map<String, ?> queryParams, String service) { return given() .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .pathParams(pathParams) .queryParams(queryParams) .when() .get(Endpoints.BASE_URL + service) .then() .log().ifError() .statusCode(OK) .extract() .body() .jsonPath() .getList(".", clazz); } *//** * Универсальный метод для отправки запросов с path параметрами *//* @Step("Отправить запрос с path параметрами") public <T> T sendRequestWithPathParams(Class<T> clazz, String method, Map<String, ?> pathParams, String service, int expectedStatus) { ValidatableResponse response = given() .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .pathParams(pathParams) .when() .request(method, Endpoints.BASE_URL + service) .then() .log().ifError() .statusCode(expectedStatus); return clazz != Void.class ? response.extract().as(clazz) : null; } // запрос с параметрами --------------------------------------------------------------------------- *//** * Универсальный метод для отправки запросов с path параметрами (для generic типов) *//* @Step("Отправить запрос с path параметрами (generic)") public <T> T sendRequestWithPathParams(TypeRef<T> typeRef, String method, Map<String, ?> pathParams, String service, int expectedStatus, String authToken) { return executeRequest(method, pathParams, service, expectedStatus, authToken) .extract().body().as(typeRef); } *//** * Для возврата одной сущности с query параметрами *//* @Step("Отправить запрос с query параметрами (один объект)") public <T> T sendRequestWithQueryParams(Class<T> responseClass, String method, Map<String, ?> queryParams, String service, int expectedStatus, String authToken) { return createRequest(authToken) .queryParams(queryParams) .when() .request(method, Endpoints.BASE_URL + service) .then() .log().ifError() .statusCode(expectedStatus) .extract().body().as(responseClass); } *//** * Отправляет запрос с query-параметрами и возвращает ответ со статусом *//* @Step("Запрос с query-параметрами → {method} {service}") public <T> ApiResponse<T> sendRequestWithQueryParamsWithResponse( Class<T> responseClass, String method, Map<String, ?> queryParams, String service, String authToken ) { String url = Endpoints.BASE_URL + service; log.debug("{} request to: {} with params: {}", method, url, queryParams); Response response = given() .spec(createRequest(authToken)) .queryParams(queryParams) .when() .request(method, url) .then() .log().ifError() .extract().response(); int statusCode = response.getStatusCode(); T body = response.as(responseClass); String attachmentName = String.format("%s %s (HTTP %d)", method, service, statusCode); attachResponseToAllure(body, attachmentName, service, null, statusCode); return new ApiResponse<>(statusCode, body); } *//** * Для возврата одной сущности *//* @Step("Отправить запрос с path параметрами {param} (один объект)") public <T> T sendRequestWithPathParams(Class<T> responseClass, String method, Map<String, ?> pathParams, String service, int expectedStatus, String authToken) { return executeRequest(method, pathParams, service, expectedStatus, authToken) .extract().body().as(responseClass); } // Общий метод выполнения запроса private ValidatableResponse executeRequest(String method, Map<String, ?> pathParams, String service, int expectedStatus, String authToken) { return createRequest(authToken) .pathParams(pathParams) .when() .request(method, Endpoints.BASE_URL + service) .then() .log().ifError() .statusCode(expectedStatus); } // ===================================================================== *//** * Универсальный метод для выполнения запросов с кастомным Content-Type *//* private <T> T executeRequestWithContentType(Class<T> responseType, String method, String url, Object body, String authToken, String contentType, int expectedStatus) { RequestSpecification request = createRequest(authToken, contentType); if (body != null) { request.body(body); } return request .when() .request(method, url) .then() .log().ifError() .statusCode(expectedStatus) .extract() .as(responseType); } *//** * POST запрос с XML content type *//* @Step("Отправить POST запрос с XML телом") public <T, A> T postWithXml(Class<T> responseClass, A requestBody, String service, String authToken, int expectedStatus) { String url = Endpoints.BASE_URL + service; log.debug("POST request to: {} with Content-Type: {}", url, APPLICATION_XML); return executeRequestWithContentType(responseClass, "POST", url, requestBody, authToken, APPLICATION_XML, expectedStatus); } *//** * PUT запрос с XML content type *//* @Step("Отправить PUT запрос с XML телом") public <T, A> T putWithXml(Class<T> responseClass, A requestBody, String service, Long id, String authToken, int expectedStatus) { String url = Endpoints.BASE_URL + service + "/" + id; log.debug("PUT request to: {} with Content-Type: {}", url, APPLICATION_XML); return executeRequestWithContentType(responseClass, "PUT", url, requestBody, authToken, APPLICATION_XML, expectedStatus); } *//** * Универсальный метод для XML запросов с raw строкой *//* @Step("Отправить XML запрос с raw телом") public <T> T sendXmlRequest(Class<T> responseClass, String method, String xmlBody, String service, String authToken, int expectedStatus) { String url = Endpoints.BASE_URL + service; log.debug("{} request to: {} with Content-Type: {}", method, url, APPLICATION_XML); RequestSpecification request = createRequest(authToken, APPLICATION_XML) .body(xmlBody); return request .when() .request(method, url) .then() .log().ifError() .statusCode(expectedStatus) .extract() .as(responseClass); } *//** * Прикрепляет ответ к Allure отчету *//* private <T> void attachResponseToAllure(T response, String attachmentName, String service, Long id, int statusCode) { try { if (response == null) { Allure.addAttachment(attachmentName, "text/plain", "Получен пустой ответ"); return; } String responseJson; try { ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); responseJson = mapper.writeValueAsString(response); } catch (Exception e) { responseJson = "Ошибка сериализации: " + e.getMessage() + "\n" + response.toString(); } String description = String.format( "%s (HTTP %d)\nService: %s%s", attachmentName, statusCode, service, id != null ? "\nID: " + id : "" ); Allure.addAttachment(description, "application/json", responseJson); log.debug("Вложение '{}' добавлено в Allure (HTTP {})", attachmentName, statusCode); } catch (Exception e) { log.warn("Ошибка при добавлении вложения в Allure: {}", e.getMessage()); Allure.addAttachment(attachmentName + " - FAIL", "text/plain", e.toString()); } } */ }