@@ -735,6 +735,211 @@ public function test_multiple_flash_calls_are_merged(): void
735735 ]);
736736 }
737737
738+ public function test_shared_props_tracking_can_be_disabled (): void
739+ {
740+ config ()->set ('inertia.expose_shared_prop_keys ' , false );
741+
742+ Route::middleware ([StartSession::class, ExampleMiddleware::class])->get ('/ ' , function () {
743+ Inertia::share ('app_name ' , 'My App ' );
744+
745+ return Inertia::render ('User/Edit ' );
746+ });
747+
748+ $ response = $ this ->withoutExceptionHandling ()->get ('/ ' , ['X-Inertia ' => 'true ' ]);
749+
750+ $ response ->assertSuccessful ();
751+ $ data = $ response ->json ();
752+ $ this ->assertArrayNotHasKey ('sharedProps ' , $ data );
753+ $ this ->assertSame ('My App ' , $ data ['props ' ]['app_name ' ]);
754+ }
755+
756+ public function test_shared_props_metadata_includes_keys_from_middleware_share (): void
757+ {
758+
759+ Route::middleware ([StartSession::class, ExampleMiddleware::class])->get ('/ ' , function () {
760+ return Inertia::render ('User/Edit ' , [
761+ 'user ' => ['name ' => 'Jonathan ' ],
762+ ]);
763+ });
764+
765+ $ response = $ this ->withoutExceptionHandling ()->get ('/ ' , ['X-Inertia ' => 'true ' ]);
766+
767+ $ response ->assertSuccessful ();
768+ $ response ->assertJson ([
769+ 'component ' => 'User/Edit ' ,
770+ 'props ' => [
771+ 'user ' => ['name ' => 'Jonathan ' ],
772+ ],
773+ 'sharedProps ' => ['errors ' ],
774+ ]);
775+ }
776+
777+ public function test_shared_props_metadata_includes_keys_from_inertia_share (): void
778+ {
779+
780+ Route::middleware ([StartSession::class, ExampleMiddleware::class])->get ('/ ' , function () {
781+ Inertia::share ('app_name ' , 'My App ' );
782+
783+ return Inertia::render ('User/Edit ' );
784+ });
785+
786+ $ response = $ this ->withoutExceptionHandling ()->get ('/ ' , ['X-Inertia ' => 'true ' ]);
787+
788+ $ response ->assertSuccessful ();
789+ $ response ->assertJson ([
790+ 'sharedProps ' => ['errors ' , 'app_name ' ],
791+ ]);
792+ }
793+
794+ public function test_shared_props_metadata_includes_dot_notation_keys_as_top_level (): void
795+ {
796+
797+ Route::middleware ([StartSession::class, ExampleMiddleware::class])->get ('/ ' , function () {
798+ Inertia::share ('auth.user ' , ['name ' => 'Jonathan ' ]);
799+
800+ return Inertia::render ('User/Edit ' );
801+ });
802+
803+ $ response = $ this ->withoutExceptionHandling ()->get ('/ ' , ['X-Inertia ' => 'true ' ]);
804+
805+ $ response ->assertSuccessful ();
806+ $ response ->assertJson ([
807+ 'sharedProps ' => ['errors ' , 'auth ' ],
808+ ]);
809+ }
810+
811+ public function test_shared_props_metadata_includes_keys_from_share_once (): void
812+ {
813+
814+ Route::middleware ([StartSession::class, ExampleMiddleware::class])->get ('/ ' , function () {
815+ Inertia::shareOnce ('permissions ' , fn () => ['admin ' => true ]);
816+
817+ return Inertia::render ('User/Edit ' );
818+ });
819+
820+ $ response = $ this ->withoutExceptionHandling ()->get ('/ ' , ['X-Inertia ' => 'true ' ]);
821+
822+ $ response ->assertSuccessful ();
823+ $ response ->assertJson ([
824+ 'props ' => [
825+ 'permissions ' => ['admin ' => true ],
826+ ],
827+ 'sharedProps ' => ['errors ' , 'permissions ' ],
828+ ]);
829+ }
830+
831+ public function test_shared_props_metadata_includes_keys_from_provides_inertia_properties (): void
832+ {
833+
834+ Route::middleware ([StartSession::class, ExampleMiddleware::class])->get ('/ ' , function () {
835+ Inertia::share (new ExampleInertiaPropsProvider ([
836+ 'app_name ' => 'My App ' ,
837+ 'locale ' => 'en ' ,
838+ ]));
839+
840+ return Inertia::render ('User/Edit ' );
841+ });
842+
843+ $ response = $ this ->withoutExceptionHandling ()->get ('/ ' , ['X-Inertia ' => 'true ' ]);
844+
845+ $ response ->assertSuccessful ();
846+ $ response ->assertJson ([
847+ 'props ' => [
848+ 'app_name ' => 'My App ' ,
849+ 'locale ' => 'en ' ,
850+ ],
851+ 'sharedProps ' => ['errors ' , 'app_name ' , 'locale ' ],
852+ ]);
853+ }
854+
855+ public function test_shared_props_metadata_includes_page_specific_override_keys (): void
856+ {
857+
858+ Route::middleware ([StartSession::class, ExampleMiddleware::class])->get ('/ ' , function () {
859+ Inertia::share ('auth ' , ['user ' => null ]);
860+
861+ return Inertia::render ('User/Edit ' , [
862+ 'auth ' => ['user ' => ['name ' => 'Jonathan ' ]],
863+ ]);
864+ });
865+
866+ $ response = $ this ->withoutExceptionHandling ()->get ('/ ' , ['X-Inertia ' => 'true ' ]);
867+
868+ $ response ->assertSuccessful ();
869+ $ response ->assertJson ([
870+ 'props ' => [
871+ 'auth ' => ['user ' => ['name ' => 'Jonathan ' ]],
872+ ],
873+ 'sharedProps ' => ['errors ' , 'auth ' ],
874+ ]);
875+ }
876+
877+ public function test_shared_props_metadata_with_multiple_share_calls (): void
878+ {
879+
880+ Route::middleware ([StartSession::class, ExampleMiddleware::class])->get ('/ ' , function () {
881+ Inertia::share ('app_name ' , 'My App ' );
882+ Inertia::share ('locale ' , 'en ' );
883+ Inertia::shareOnce ('permissions ' , fn () => ['admin ' => true ]);
884+
885+ return Inertia::render ('User/Edit ' );
886+ });
887+
888+ $ response = $ this ->withoutExceptionHandling ()->get ('/ ' , ['X-Inertia ' => 'true ' ]);
889+
890+ $ response ->assertSuccessful ();
891+ $ response ->assertJson ([
892+ 'sharedProps ' => ['errors ' , 'app_name ' , 'locale ' , 'permissions ' ],
893+ ]);
894+ }
895+
896+ public function test_shared_props_metadata_with_array_share (): void
897+ {
898+
899+ Route::middleware ([StartSession::class, ExampleMiddleware::class])->get ('/ ' , function () {
900+ Inertia::share ([
901+ 'flash ' => fn () => ['message ' => 'Hello ' ],
902+ 'auth ' => fn () => ['user ' => ['name ' => 'Jonathan ' ]],
903+ ]);
904+
905+ return Inertia::render ('User/Edit ' );
906+ });
907+
908+ $ response = $ this ->withoutExceptionHandling ()->get ('/ ' , ['X-Inertia ' => 'true ' ]);
909+
910+ $ response ->assertSuccessful ();
911+ $ response ->assertJson ([
912+ 'sharedProps ' => ['errors ' , 'flash ' , 'auth ' ],
913+ ]);
914+ }
915+
916+ public function test_shared_props_metadata_includes_already_loaded_once_props (): void
917+ {
918+
919+ Route::middleware ([StartSession::class, ExampleMiddleware::class])->get ('/ ' , function () {
920+ Inertia::shareOnce ('permissions ' , fn () => ['admin ' => true ]);
921+
922+ return Inertia::render ('User/Edit ' );
923+ });
924+
925+ $ response = $ this ->withoutExceptionHandling ()->get ('/ ' , [
926+ 'X-Inertia ' => 'true ' ,
927+ 'X-Inertia-Except-Once-Props ' => 'permissions ' ,
928+ ]);
929+
930+ $ response ->assertSuccessful ();
931+ $ data = $ response ->json ();
932+
933+ // The once-prop value should be excluded from props since the client already has it
934+ $ this ->assertArrayNotHasKey ('permissions ' , $ data ['props ' ]);
935+
936+ // But its key should still appear in the sharedProps metadata
937+ $ this ->assertContains ('permissions ' , $ data ['sharedProps ' ]);
938+
939+ // And its onceProps metadata should also be preserved
940+ $ this ->assertArrayHasKey ('permissions ' , $ data ['onceProps ' ]);
941+ }
942+
738943 public function test_without_ssr_registers_paths_with_gateway (): void
739944 {
740945 Inertia::withoutSsr (['admin/* ' , 'nova/* ' ]);
0 commit comments