Jetstream with Inertia and shouldBeStrict throwing error
Hey Guys :)
I have setup a brand new Laravel installation with Jetstream and Inertia.
When I activate Model::shouldBeStrict(! $this->app->isProduction()); in the AppServiceProvider the default Laravel tests are failing because profile_photo_path is lazy loaded.
Any Ideas how to fix that?
• Tests\Feature\PasswordConfirmationTest > confirm password screen can be rendered
Expected response status code [200] but received 500.
Failed asserting that 200 is identical to 500.
The following exception occurred during the last request:
Illuminate\Database\Eloquent\MissingAttributeException: The attribute [profile_photo_path] either does not exist or was not retrieved for model [App\Models\User]. in /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:470
Stack trace:
#0 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(454): Illuminate\Database\Eloquent\Model->throwMissingAttributeExceptionIfApplicable()
#1 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2176): Illuminate\Database\Eloquent\Model->getAttribute()
#2 /var/www/html/vendor/laravel/jetstream/src/HasProfilePhoto.php(62): Illuminate\Database\Eloquent\Model->__get()
#3 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(653): App\Models\User->getProfilePhotoUrlAttribute()
#4 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(703): Illuminate\Database\Eloquent\Model->mutateAttribute()
#5 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php(213): Illuminate\Database\Eloquent\Model->mutateAttributeForArray()
#6 /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1587): Illuminate\Database\Eloquent\Model->attributesToArray()
#7 /var/www/html/vendor/laravel/jetstream/src/Http/Middleware/ShareInertiaData.php(53): Illuminate\Database\Eloquent\Model->toArray()
#8 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Laravel\Jetstream\Http\Middleware\ShareInertiaData->Laravel\Jetstream\Http\Middleware\{closure}()
#9 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#10 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(81): Illuminate\Container\Util::unwrapIfClosure()
#11 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod()
#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(651): Illuminate\Container\BoundMethod::call()
#13 /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(338): Illuminate\Container\Container->call()
#14 /var/www/html/vendor/inertiajs/inertia-laravel/src/Response.php(125): Illuminate\Support\Facades\Facade::__callStatic()
#15 /var/www/html/vendor/inertiajs/inertia-laravel/src/Response.php(97): Inertia\Response->resolvePropertyInstances()
#16 /var/www/html/vendor/laravel/fortify/src/Http/Responses/SimpleViewResponse.php(56): Inertia\Response->toResponse()
#17 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(815): Laravel\Fortify\Http\Responses\SimpleViewResponse->toResponse()
#18 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(802): Illuminate\Routing\Router::toResponse()
#19 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(725): Illuminate\Routing\Router->prepareResponse()
#20 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Routing\Router->Illuminate\Routing\{closure}()
#21 /var/www/html/vendor/inertiajs/inertia-laravel/src/Middleware.php(92): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#22 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Inertia\Middleware->handle()
#23 /var/www/html/vendor/laravel/jetstream/src/Http/Middleware/ShareInertiaData.php(66): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#24 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Laravel\Jetstream\Http\Middleware\ShareInertiaData->handle()
#25 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#26 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Routing\Middleware\SubstituteBindings->handle()
#27 /var/www/html/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(44): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#28 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Auth\Middleware\Authenticate->handle()
#29 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#30 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle()
#31 /var/www/html/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\View\Middleware\ShareErrorsFromSession->handle()
#33 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest()
#35 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Session\Middleware\StartSession->handle()
#36 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#37 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle()
#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#39 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Cookie\Middleware\EncryptCookies->handle()
#40 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#41 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(726): Illuminate\Pipeline\Pipeline->then()
#42 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(703): Illuminate\Routing\Router->runRouteWithinStack()
#43 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(667): Illuminate\Routing\Router->runRoute()
#44 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(656): Illuminate\Routing\Router->dispatchToRoute()
#45 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(190): Illuminate\Routing\Router->dispatch()
#46 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}()
#47 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#48 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#49 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle()
#50 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#51 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#52 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\TrimStrings->handle()
#53 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#54 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle()
#55 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#56 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle()
#57 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#58 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Http\Middleware\HandleCors->handle()
#59 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#60 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Http\Middleware\TrustProxies->handle()
#61 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#62 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(165): Illuminate\Pipeline\Pipeline->then()
#63 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(134): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
#64 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php(545): Illuminate\Foundation\Http\Kernel->handle()
#65 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php(312): Illuminate\Foundation\Testing\TestCase->call()
#66 /var/www/html/tests/Feature/PasswordConfirmationTest.php(18): Illuminate\Foundation\Testing\TestCase->get()
#67 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(1548): Tests\Feature\PasswordConfirmationTest->test_confirm_password_screen_can_be_rendered()
#68 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(1154): PHPUnit\Framework\TestCase->runTest()
#69 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestResult.php(728): PHPUnit\Framework\TestCase->runBare()
#70 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(904): PHPUnit\Framework\TestResult->run()
#71 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php(673): PHPUnit\Framework\TestCase->run()
#72 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php(673): PHPUnit\Framework\TestSuite->run()
#73 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php(673): PHPUnit\Framework\TestSuite->run()
#74 /var/www/html/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(673): PHPUnit\Framework\TestSuite->run()
#75 /var/www/html/vendor/phpunit/phpunit/src/TextUI/Command.php(144): PHPUnit\TextUI\TestRunner->run()
#76 /var/www/html/vendor/phpunit/phpunit/src/TextUI/Command.php(97): PHPUnit\TextUI\Command->run()
#77 /var/www/html/vendor/phpunit/phpunit/phpunit(98): PHPUnit\TextUI\Command::main()
#78 {main}
----------------------------------------------------------------------------------
The attribute [profile_photo_path] either does not exist or was not retrieved for model [App\Models\User].
@terlebach In model strict mode, lazy loading doesn't allow. So the error cause by lazy loading disable model strict mode or try to not use lazy loading?
I figured out that it's not because of the lazy loading but because of the dynamic attributes when using Traits like HasProfilePhoto and TwoFactorAuthenticatable together with Model::preventAccessingMissingAttributes(! $this->app->isProduction()); .
To disable lazy loading in my dev environment was more important for me and I can life without preventing accessing missing attributes. xD
I had the same issue, i noticed that the User::factory()->create()) didnt have the profile_photo_path as part of the setup so i just added it and strict was working again.
@FvsJson
~~Can you elaborate a bit on your solution? I'm having the same issue and nothing seems to be solving it. Thanks!!~~
Got it, making another comment to elaborate on my issue specifically.
My issue was Strict Mode with Jetstream on Unit Tests, same as OP here. Turns out all I had to do was add profile_photo_path into the UserFactory's definition.
'profile_photo_path' => $this->faker->filePath(),
I tried this blank too and it didn't work; it needs content.
Update: relevant thread for additional field/solutions: [Apologies, can't create a link, first registered day] -Github, Laravel/Jetstream, Issue #1164
I think this might still be an issue with Jetstream, it seems to be impossible to actually disable profile photos to a degree that actually lets you run in Strict Mode, as the application still wants to look for getProfilePhotoUrlAttribute() even with everything switched off. Had to override that method in User Model even though i'm not using the trait anymore (using the trait causes a different problem).
And removed the profile_photo_url from the $appends-array in my user model. (Appends automatically adds custom attributes to the Model, whenever it's cast to an array)