Basically, I'm unable to test if controller accepts cookie no matter what i try.
Here's my test:
public function test_cookie_passed_to_request(){
$cookie = cookie('name', 'value');
$this->call('get', 'test', [], [$cookie]);
$this->assertEquals('value', $this->response->content());
}
And here is the route:
Route::get('test', [
'middleware' => 'web',
function (\Illuminate\Http\Request $request) {
return $request->cookie('name');
}
]);
Test fails: expected "value", got "".
Discussion on laracasts for reference.
This is not a bug, but instead the cookie should be passed as an array of values, not as a Symfony\Component\HttpFoundation\Cookie instance. Test should be changed to read:
public function test_cookie_passed_to_request(){
$cookie = ['name' => Crypt::encrypt('value')];
$this->call('GET', 'test', [], $cookie);
$this->assertEquals('value', $this->response->content());
}
Top tip. Avoid calling global functions inside tests. ;)
@GrahamCampbell
And I did some more digging:
$cookie1 = ['name1' => Crypt::encrypt('value1')];
$cookie2 = ['name2' => Crypt::encrypt('value2')];
$this->call('get', 'test', [], [$cookie1, $cookie2]);
$this->assertEquals('value1', $this->response->content());
That test fails.
And here is method definition from src:
public function call($method, $uri, $parameters = [], $cookies = []...
It says $cookies and not cookie. Yet it accepts only one cookie and that one should be weirdly parsed.
as per my answer on the Laracasts thread, the cookies need to be set like:
public function test_cookies_passed_to_request()
{
$cookies = [
'name1' => Crypt::encrypt('value1'),
'name2' => Crypt::encrypt('value2')
];
$this->call('get', 'test', [], $cookies);
$this->assertEquals('value1', $this->response->content());
}
Here's the final solution.
The test:
public function test_cookie_passed_to_request()
{
$this->disableCookiesEncryption('name');
$cookie = [ 'name' => 'value' ];
$this->call('get', 'test', [ ], $cookie);
$this->assertEquals('value', $this->response->content());
}
The route:
Route::get('test', [
'middleware' => 'web',
function (\Illuminate\Http\Request $request) {
return $request->cookie('name');
}
]);
TestCase function to disable cookie encryption:
/**
* @param array|string $cookies
* @return $this
*/
protected function disableCookiesEncryption($cookies)
{
$this->app->resolving(EncryptCookies::class,
function ($object) use ($cookies) {
$object->disableFor($cookies);
});
return $this;
}
Working in 5.4
Thanks @asvae! Works perfectly in 5.6
Can we do it without creating routes?
Most helpful comment
Here's the final solution.
The test:
The route:
TestCase function to disable cookie encryption: