inertia-laravel icon indicating copy to clipboard operation
inertia-laravel copied to clipboard

Support invokable classes for response props. Added test.

Open dextercampos opened this issue 5 years ago • 1 comments

I'm working on an app where I have lots of shared props to lazy load coming from different sources (modules). I've noticed I have a growing number of Closures that I want to test properly in isolation (per module and per property). I want to replace these closures into invokable classes to be able to use them like this:

Sample Use Case

// Share data in the service provider or anywhere
Inertia::share('user', new GetAuthUser());

// Some Invokable class
class GetAuthUser {
    public function __invoke(AuthInteface $auth) 
    {
        if ($auth->getUser() === null) {
            return new GuestUser();
        }

        return $auth->getUser();
    }
}

Testing

// Contoller Testing
    public function test() {
        // Do a request call to a controller route that returns an Inertia response.
        ...
        // Then assert only if key prop exist wince value returned is already tested in unit test.
        static::assertNotNull($response->page->user);
    } 

// Unit Testing
    public function testHasUser() {
        // Do fake login
        ...
        $user = App::call(new GetAuthUser());
        // Do assertions
        ...
    }

This approach only works if the props check in Inertia response is using is_callable($prop) instead of $prop instanceof Closure. I think this way we have separated the logic of sharing and retrieving data. 😄

dextercampos avatar Apr 12 '20 15:04 dextercampos

The issue with is_callable is that if we were to give the name of existing global function, it would be used instead.

For instance, with your implementation, using Inertia::share('something', 'app') would call the app() function from Laravel. This can probably be mitigated by using function_exists before, but still, I think it's dangerous.

EDIT: is_object might be a better check than function_exists?

innocenzi avatar Feb 27 '22 01:02 innocenzi