inertia-laravel
inertia-laravel copied to clipboard
Support invokable classes for response props. Added test.
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. 😄
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?