I had a need today for a Livewire component to set a cookie, and wanted to test that it was actually set correctly.
Livewire includes support for reading cookies, but not for writing them.
And unfortunately, the redirect helper method doesn’t include any way to set a cookie.
Thankfully, Laravel provides a Cookie::queue()
method that will attach set the cookie on the next outgoing response, and since Livewire method calls result in a HTTP response (unless you use the renderless attribute), the framework takes care of attaching the cookie for you:
Cookie::queue('name', 'value', $minutes);
However, I found it counterintuitive to test this behavior.
There is an assertCookie()
method available when testing the component, but it always fails because we’re testing a Livewire component, not a request, and so the framework doesn’t attach the queued cookie(s).
My solution: use Cookie::queued()
to retrieve the queued cookie, and then run assertions against that:
<?php | |
namespace App\Livewire; | |
use Illuminate\Support\Facades\Cookie; | |
use Livewire\Component; | |
class MyComponent extends Component | |
{ | |
public function render() | |
{ | |
return view('my-component'); | |
} | |
public function rememberMe() | |
{ | |
Cookie::queue( | |
name: 'contactId', | |
value: 'my-contact-id', | |
minutes: 60 * 24 * 365, | |
path: '/', | |
); | |
} | |
} |
<?php | |
namespace Tests\Feature\Livewire; | |
use App\Livewire\MyComponent; | |
use App\Models\User; | |
use Illuminate\Support\Facades\Cookie; | |
use Livewire\Livewire; | |
use Tests\TestCase; | |
class MyComponentTest extends TestCase | |
{ | |
public function testComponentSetsCookie() | |
{ | |
$user = User::factory()->create(); | |
Livewire::actingAs($user) | |
->test(MyComponent::class) | |
->call('rememberMe') | |
->assertCookie('contactId', $user->contact_id) // FAILs | |
->assertOk(); | |
// The assertCookie method exists on the testable livewire component, but always fails: | |
// because we’re testing a Livewire component and not an actual request, | |
// the framework doesn’t attach the queued cookie. | |
// So instead, use Cookie::queued() to read the queued cookie, and then run assertions against that: | |
$cookie = Cookie::queued( | |
key: 'contactId', | |
path: '/', | |
); | |
$this->assertEquals($user->contact_id, $cookie->getValue()); | |
$this->assertEquals(now()->addYear()->unix(), $cookie->getExpiresTime()); | |
} | |
} |