|
# Тестирование cookies в Laravel и phpunit |
|
Бегло пробежавшись глазами по мануалу, может показаться, что вопрос это простой. Но давайте посмотрим на простейший случай. |
|
|
|
## Условие |
|
Пользователь вбивает в браузере `register/123` и переходит на страницу. Его редиректит на `register`, выдавая параллельно кукез `referral: 123`. Пользователь регистрируется — реферал должен закрепиться в базе. Нужно протестировать юзкеис. |
|
|
|
## Решение 1 (?) |
|
Казалось бы, все просто: |
|
``` |
|
$this->visit('register/123')->seeCookie('referral'); |
|
``` |
|
Вот только тест красный. Разберемся: |
|
|
|
Заглянув в код, наблюдаем, что `visit()` вызывает `$this->followRedirects()`. А ларавель не передает кукезы при редиректе. |
|
Почему бы не разбить тест на два. |
|
|
|
## Решение 2 (?) |
|
#### Тест 1 |
|
``` |
|
$this->get('register/123'); |
|
$this->seeCookie('referral'); |
|
``` |
|
C первым тестом все хорошо. Он зеленый, как огурчик. Дальше мы его трогать не будем. |
|
#### Тест 2 |
|
``` |
|
$this->call('post', 'register', $this->userData, ['referral' => '123']); |
|
$this-assertTrue($this->checkUserHasReferral('123')); // Проверить, сохранилось ли значение в базе. |
|
``` |
|
А вот второй — снова неумолимо краснеет. Мало того, `dd($request->cookies)` в контроллере сообщает, что никаких кукезов не было и вообще вы адресом ошиблись. |
|
|
|
Проблема здесь в том, что ларавель куки еще и шифрует по-умолчанию. Что приводит нас к финальному решению: |
|
## Решение 3 (!) |
|
#### Тест 2 |
|
``` |
|
$this->app->resolving(App\Http\Middleware\EncryptCookies::class, |
|
function ($object) { |
|
$object->disableFor('referral'); |
|
}); |
|
$cookie = ['referral' => '123']; |
|
$this->call('post', 'register', $this->userData, ['referral' => '123']); |
|
$this-assertTrue($this->checkUserHasReferral('123')); |
|
``` |
|
Что здесь происходит? В тот момент, когда ларавель попытается вызвать инстант класса `EnctyptCookies`, отвечающего за шифрование кукезов, триггерится [вышеописанное замыкание](https://laravel.com/docs/5.2/container#container-events), которое модифицирует объект так, чтобы он игнорировал куки с определенным значением. |
|
|
|
Функционал по снятию шифрования с определенных кукезов легко можно выделить в родительский тест-кейс: |
|
``` |
|
/** |
|
* @param array|string $cookies |
|
* @return $this |
|
*/ |
|
protected function disableCookiesEncryption($cookies) |
|
{ |
|
$this->app->resolving(EncryptCookies::class, |
|
function ($object) use ($cookies) { |
|
$object->disableFor($cookies); |
|
}); |
|
|
|
return $this; |
|
} |
|
``` |
|
А в конкретном тест-кейсе, уже запустить в методе `setUp()`: |
|
``` |
|
public function setUp() |
|
{ |
|
parent::setUp(); |
|
$this->disableCookiesEncryption(Referral::COOKIE_NAME); |
|
} |
|
``` |
|
Альтернативным вариантом будет, наоборот, шифровать куки перед тем, как положить в запрос: |
|
``` |
|
$cookie = [ 'referral' => \Crypt::encrypt('123') ]; |
|
``` |
|
# Заключение |
|
И вот, тесты позеленели, а вы научились автоматически проверять кукезы без лишней головной боли. |
Тестирование cookies в Laravel и phpunit
Бегло пробежавшись глазами по мануалу, может показаться, что вопрос это простой. Но давайте посмотрим на простейший случай.
Условие
Пользователь вбивает в браузере
register/123
и переходит на страницу. Его редиректит наregister
, выдавая параллельно кукезreferral: 123
. Пользователь регистрируется — реферал должен закрепиться в базе. Нужно протестировать юзкеис.Решение 1 (?)
Казалось бы, все просто:
Вот только тест красный. Разберемся:
Заглянув в код, наблюдаем, что
visit()
вызывает$this->followRedirects()
. А ларавель не передает кукезы при редиректе.Почему бы не разбить тест на два.
Решение 2 (?)
Тест 1
C первым тестом все хорошо. Он зеленый, как огурчик. Дальше мы его трогать не будем.
Тест 2
А вот второй — снова неумолимо краснеет. Мало того,
dd($request->cookies)
в контроллере сообщает, что никаких кукезов не было и вообще вы адресом ошиблись.Проблема здесь в том, что ларавель куки еще и шифрует по-умолчанию. Что приводит нас к финальному решению:
Решение 3 (!)
Тест 2
Что здесь происходит? В тот момент, когда ларавель попытается вызвать инстант класса
EnctyptCookies
, отвечающего за шифрование кукезов, триггерится вышеописанное замыкание, которое модифицирует объект так, чтобы он игнорировал куки с определенным значением.Функционал по снятию шифрования с определенных кукезов легко можно выделить в родительский тест-кейс:
А в конкретном тест-кейсе, уже запустить в методе
setUp()
:Альтернативным вариантом будет, наоборот, шифровать куки перед тем, как положить в запрос:
Заключение
И вот, тесты позеленели, а вы научились автоматически проверять кукезы без лишней головной боли.