#Test component state from `get` request

47 messages · Page 1 of 1 (latest)

quiet raptor
#

I have a Signup component on a /signup route. The component loads a code property from a cookie (Cookie::get('code')).

How can I test that a call the /signup route actually sets the code property properly?

I know how to test the component if the property is set but I don't see how to call /signup but then how to get access to the component to test?

quiet raptor
#

To be clear here's what I want:

#
$this->get('/signup?code=foobar');

$component = // some magic here

expect($component->code)->toEqual('foobar');
#

my code in my component looks like this:

#
    public function __construct()
    {
        $this->code = Cookie::get('code');
    }
crimson escarp
#

see the example, its exactly what youre looking for

#
        Livewire::test(CreatePost::class)
            ->set('title', 'foo')
            ->call('create');
 
        $this->assertTrue(Post::whereTitle('foo')->exists());
#
        Livewire::test(CreatePost::class, ['initialTitle' => 'foo'])
            ->assertSet('title', 'foo');
#

etc.

dense tiger
quiet raptor
#

setting cookie in middleware:

#
    public function handle($request, Closure $next)
    {
        if ($request->hasCookie('code')) {
            return $next($request);
        }

        if (($code = $request->query('code')) && Referrer::referralCodeExists($code)) {
            return redirect($request->fullUrl())->withCookie(cookie()->forever('code', $code));
        }

        return $next($request);
    }
#

As it's not recommended to use the constructor with Livewire components, instead use mount().

#

bah of course, been a while since I've been in livewire land, I'll move it, thanks for the reminder

#

Just stepped out, I’ll share the route and component when I’m back

dense tiger
# quiet raptor ```php public function handle($request, Closure $next) { if ($re...

Ah right, yep.

So I think I would test this in two parts, one test for the middleware to ensure the cookie is set correctly and another for the component to ensure it reads the cookie correctly.

Test one:

$this->get('/signup?code=foobar')
  ->assertCookie('code', 'foobar');

Test two:

// Set cookie manually in test to 'foobar'

livewire(MyComponent::class)->assertSet('code', 'foobar');

So in typing this out, I realised that I don't actually know how to set a cookie in a test 😂

Looking into it, it seems normally you'd do something like $this->withCookie()->get();.

But Livewire's test object doesn't have anything like that, that I know of. So that's a problem 🤔

quiet raptor
#

yes, that is indeed my problem

#

...and why I asked here

#

glad you came around, lol

dense tiger
# quiet raptor glad you came around, lol

Haha 😂 I don't event know what a good way would be to add it.

Typically a livewire test would be

Livewire::test(Component::class) which mounts the component. But ideally it needs a Livewire::withCookie()->test(Component::class).

Problem with that is Livewire:: returns the Livewire manager where as Livewire::test() returns a Testable Livewire object. The cookies method really should be on the testable Livewire object, but somehow run before it runs mount on the component. Bit of a chicken and egg problem

quiet raptor
#

yup

#

welcome to my world

#

"just" fix it josh come on

dense tiger
#

Haha you found the fix for the test already, sitting between keyboard and chair 😬

quiet raptor
#

SEBKAC instead of PEBKAC, got it

dense tiger
#

Haha yeah exactly

quiet raptor
#

imo it's not a totally unreasonable use case

dense tiger
#

I've made a note of it to make sure we have a solution for V3 because yeah I agree there should be a solution for it

#

If we can come up with a clean way to do it in V2, I'm sure Caleb would be willing to add it

quiet raptor
#

no rush, this won't be launching for months yet

#

no need to jam into v2

dense tiger
#

Ok sweet! 😁

quiet raptor
#

like it's a 1 min manual test, no biggie

#

but nice to have it all automated

dense tiger
#

Yup! One other way around it is to wrap the component in a controller (🤮) and use the controller to load the cookie (which you can test using Laravel methods) and pass the cookie value to the component

quiet raptor
#

blasphemy

#

a CONTROLLER? sheesh

dense tiger
#

My thoughts exactly

#

But it's possible

quiet raptor
#

might as well just rewrite it using inertia

quiet raptor
#

kk tell caleb i'm re-writing this in inertia kthxbye

dense tiger
#

Need to make sure theres cookies to keep the devs happy

quiet raptor
#

exactly

#

we run on cookies