Ответ
Основная опасность метода PUT с точки зрения тестирования заключается в его идемпотентности — повторный вызов с теми же данными полностью перезаписывает ресурс. Это может привести к следующим рискам, которые необходимо проверять в тестах:
- Потеря данных: Если клиент отправляет запрос с неполным представлением ресурса (например, только одно поле), сервер может заменить весь существующий ресурс, удалив остальные поля. Тесты должны проверять, как API обрабатывает такие неполные запросы.
- Нарушение целостности данных (Race Conditions): Если два параллельных PUT-запроса приходят к одному ресурсу, последний выиграет, что может привести к потере изменений из первого запроса. Это требует тестирования на конкурентность.
- Проблемы с безопасностью: Без должной авторизации PUT может позволить перезаписать конфиденциальные данные другого пользователя.
Пример сценария для тестирования:
# Исходное состояние ресурса
GET /api/users/123
{
"id": 123,
"name": "Иван",
"email": "ivan@example.com",
"role": "user"
}
# PUT-запрос, изменяющий только имя
PUT /api/users/123
Content-Type: application/json
{"name": "Петр"}
# Ожидаемый результат зависит от реализации API.
# Плохой сценарий (полная замена):
GET /api/users/123
{"name": "Петр"} # Поля email и role потеряны!
# Хороший сценарий (валидация или использование PATCH):
# API должен вернуть ошибку 400 Bad Request или 422 Unprocessable Entity,
# требуя отправки полного представления ресурса.
Что проверять в тестах:
- Валидация входящих данных (требуется ли полное представление ресурса?).
- Механизмы предотвращения конфликтов (заголовки
ETag,If-Match). - Корректная обработка конкурентных запросов.
- Строгая проверка прав доступа (может ли пользователь A изменить ресурс пользователя B?).
Ответ 18+ 🔞
А, ну ты держись, сейчас расскажу про эту вашу идемпотентность, которая всех так ебёт. Смотри, метод PUT — он как тот упоротый сосед, который приходит к тебе в гости и, не спрашивая, вываливает все твои вещи из шкафа, а на их место ставит свой одинокий свитер. И так может делать хоть сто раз подряд — результат один: твои вещи в жопе, а его свитер торжественно лежит на полке. Это и есть идемпотентность, ёпта. Повторяешь действие — получаешь тот же пиздец.
Основная засада, которую надо ловить тестами, — это три кита дерьма, на которых держится кривая реализация.
Первый кит — потеря данных, овердохуища какая. Представь: у пользователя в базе имя, почта, роль. Какой-то криворукий клиент шлёт PUT-запрос, где только поле "name" обновлено. А сервер-дурак, не глядя, берёт и хуяк — заменяет всю запись в базе на этот кусок JSON. И всё, пиши пропало: почта и роль накрылись медным тазом. Пользователь теперь просто «Петя» без почты и прав. Красота, да? Тесты должны этот сценарий гонять по полной: а что будет, если отправить неполные данные? API должен либо орать, что ему не хватает полей (ошибка 400 или 422), либо сам дозаполнять недостающее из старой версии. Но ни в коем случае не молча всё стирать!
Второй кит — гонки (Race Conditions), или «гомосеки налетели». Ситуация: два запроса летят на сервер одновременно, чтобы обновить одну и ту же сущность. Один хочет поменять имя, другой — почту. Кто прилетел последним, тот и прав. В итоге побеждает второй запрос, а изменения из первого — просто испаряются, как будто их и не было. Пользователь думает, что имя обновил, а на деле там уже совсем другие данные. Тестами надо имитировать эту адскую гонку и смотреть, как API будет выкручиваться: может, через заголовки ETag или If-Match, чтобы конфликты обнаруживать.
Третий кит — безопасность, тут доверия ебать ноль. Если не проверить права доступа, то любой шутник может отправить PUT на чужой ресурс и перезаписать его. Ты был админом, а стал гостем. Всё, приехали. Тесты должны долбить эту границу: а может ли юзер А ебнуть ресурс юзера Б? Если может — это пиздец, а не API.
Вот, смотри на примере, как это выглядит в жизни:
# Исходное состояние ресурса
GET /api/users/123
{
"id": 123,
"name": "Иван",
"email": "ivan@example.com",
"role": "user"
}
# PUT-запрос, изменяющий только имя
PUT /api/users/123
Content-Type: application/json
{"name": "Петр"}
# Ожидаемый результат зависит от реализации API.
# Плохой сценарий (полная замена):
GET /api/users/123
{"name": "Петр"} # Поля email и role потеряны! Вот это пизда рулю!
# Хороший сценарий (валидация или использование PATCH):
# API должен вернуть ошибку 400 Bad Request или 422 Unprocessable Entity,
# требуя отправки полного представления ресурса.
Итак, что тесты должны делать, чтобы все спать спокойно могли:
- Валидация входящих данных — а что, если прислали хуйню? А если не всё? API должен чётко сказать: «Чувак, ты мне не полный объект прислал, иди нахуй с таким PUT'ом, используй PATCH или присылай всё».
- Механизмы предотвращения конфликтов — проверяй работу с
ETagиIf-Match. Чтобы если данные уже кто-то успел поменять, второй запрос не затёр их, как говно. - Конкурентные запросы — устраивай настоящую бойню, гони десятки параллельных запросов на один ресурс. Смотри, чтобы данные не превратились в кашу.
- Проверка прав доступа — это святое. Под разными пользователями пытайся трогать чужие ресурсы. Если прокатило — значит, пора бить в колокола и нестись с криком «вилкой в глаз или в жопу раз» к разработчикам.
Вот так-то, дружище. PUT — он мощный, но опасный, как хуй с горы. Не тестируешь его — готовься к сюрпризам, от которых сам от себя охуеешь.