Введение
Недавно я сделал pull request, который был объединен с фреймворком Laravel и выпущен в версии v8.55. Он добавил новый метод assertRedirectToSignedRoute()
, который вы можете использовать в своих тестах.
Я уже давно использую этот метод в нескольких своих проектах, добавляя его с помощью макросов, но я решил сделать запрос на включение в фреймворк, чтобы попытаться помочь другим разработчикам, которые, вероятно, тоже могли бы его использовать.
Кстати, если вам интересно узнать о макросах, ознакомьтесь с моей статьей Как поменять местами элементы в массиве с помощью макросов Laravel.
Что такое подписанные маршруты?
Прежде чем мы рассмотрим тестирование подписанных URL-адресов, давайте кратко рассмотрим, что они из себя представляют и для чего их можно использовать.
Подписанные URL-адреса — это просто URL-адреса именованных маршрутов в вашем приложении, которые содержат подпись в строке запроса.
Вот пример подписанного URL:
Как видите, URL-адрес содержит параметр signature
.
Теперь, если бы мы попытались пойти по этому пути, мы могли бы использовать промежуточное ПО signed
, чтобы убедиться, что URL-адрес не был изменен с момента его создания. Это может быть очень полезно, когда мы хотим создать маршрут, который должен быть общедоступным, но нуждается в некоторой защите. Если URL-адрес каким-либо образом изменился, когда кто-то перейдет к нему, он получит ответ об ошибке 403.
Вы можете сгенерировать подписанные URL-адреса, используя такой код:
use Illuminate\Support\Facades\URL;
return URL::signedRoute('protected-route', ['user' => 1]);
Если вы подписаны на мою рассылку и у вас орлиный взгляд, вы могли заметить, что я использую подписанные маршруты в электронном письме «Подтвердить подписку». Подписанный маршрут выглядит так:
Когда кто-то переходит по этому маршруту, это подтверждает, что он хочет подписаться на информационный бюллетень. Подписывая этот URL-адрес, я могу быть уверен, что он не был подделан и что кто-то не пытается залить мою рассылку и подписать множество случайных адресов электронной почты.
Что такое временные подписанные URL-адреса?
Обсужденные выше подписанные URL-адреса не имеют срока действия и, как правило, должны быть доступны в течение неопределенного времени. Однако могут быть случаи, когда вы хотите создать подписанный URL-адрес, к которому можно получить доступ в течение определенного периода времени. Они работают так же, как общие подписанные URL-адреса, но у них также есть время истечения срока действия в строке запроса.
Вот пример временного подписанного URL:
Как видите, URL содержит параметры signature
и expires
.
Как и в случае с общими подписанными URL-адресами, если URL-адрес подделан или кто-то пытается перейти к нему после истечения срока действия, будет возвращен ответ об ошибке 403.
Тестирование перенаправлений на подписанные маршруты
Теперь, когда мы кратко рассмотрели подписанные маршруты в Laravel, мы можем посмотреть, как написать тест, подтверждающий, что контроллер перенаправляет на подписанный URL-адрес. Обратите внимание, что приведенные ниже тесты будут очень простыми, и мы будем тестировать только перенаправление; но, надеюсь, они должны помочь объяснить общую концепцию.
Давайте представим, что у нас есть следующий одноразовый контроллер с маршрутом /my-route
:
class RandomController extends Controller
{
public function __invoke(): RedirectResponse
{
// Do something...
return redirect()->signedRoute(
'example.route', ['param' => 'hello']
);
}
}
Если бы мы хотели проверить, что контроллер возвращает перенаправление на подписанный маршрут, но не особенно заботился о том, какой URL-адрес, мы могли бы написать такой тест:
/** @test */
public function user_is_redirected_to_signed_route(): void
{
$this->get('/my-route')
->assertRedirectToSignedRoute();
}
В качестве альтернативы, если мы хотим быть более строгими и проверять, что перенаправление было на определенный маршрут, мы могли бы написать следующий тест:
/** @test */
public function user_is_redirected_to_signed_route(): void
{
$this->get('/my-route')
->assertRedirectToSignedRoute(
route('example.route', ['param' => 'hello']
)
);
}
Метод assertRedirectToSignedRoute()
также работает с временными подписанными маршрутами. Таким образом, если бы наш контроллер возвращал redirect()->temporarySignedRoute()
, а не redirect()->signedRoute()
, приведенные выше тесты все равно работали бы.
Вывод
Хотя этот пост немного короче обычного, надеюсь, он должен был дать вам краткий обзор подписанных URL-адресов в Laravel и того, как правильно писать тесты, которые ваши контроллеры перенаправляют на них.
Если этот пост помог вам, я хотел бы услышать об этом. Точно так же, если у вас есть какие-либо отзывы, чтобы улучшить этот пост, я тоже хотел бы их услышать.
Если вы хотите получать обновления каждый раз, когда я публикую новый пост, не стесняйтесь подписаться на мою рассылку.
Продолжайте создавать потрясающие вещи! 🚀
Первоначально опубликовано на https://ashallendesign.co.uk.