Skip to content

Commit 07da425

Browse files
authored
Include scrollProps metadata when prop is requested to reset (#781)
* Include `scrollProps` metadata when prop is requested to reset * PHP 8.1 support
1 parent 3fad483 commit 07da425

File tree

2 files changed

+126
-4
lines changed

2 files changed

+126
-4
lines changed

src/Response.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -445,14 +445,24 @@ public function resolveCacheDirections(Request $request): array
445445
];
446446
}
447447

448+
/**
449+
* Get the props that should be reset based on the request headers.
450+
*
451+
* @return array<int, string>
452+
*/
453+
public function getResetProps(Request $request): array
454+
{
455+
return array_filter(explode(',', $request->header(Header::RESET, '')));
456+
}
457+
448458
/**
449459
* Get the props that should be considered for merging based on the request headers.
450460
*
451461
* @return \Illuminate\Support\Collection<string, \Inertia\Mergeable>
452462
*/
453-
protected function getMergePropsForRequest(Request $request): Collection
463+
protected function getMergePropsForRequest(Request $request, bool $rejectResetProps = true): Collection
454464
{
455-
$resetProps = array_filter(explode(',', $request->header(Header::RESET, '')));
465+
$resetProps = $rejectResetProps ? $this->getResetProps($request) : [];
456466
$onlyProps = array_filter(explode(',', $request->header(Header::PARTIAL_ONLY, '')));
457467
$exceptProps = array_filter(explode(',', $request->header(Header::PARTIAL_EXCEPT, '')));
458468

@@ -589,9 +599,14 @@ public function resolveDeferredProps(Request $request): array
589599
*/
590600
public function resolveScrollProps(Request $request): array
591601
{
592-
$scrollProps = $this->getMergePropsForRequest($request)
602+
$resetProps = $this->getResetProps($request);
603+
604+
$scrollProps = $this->getMergePropsForRequest($request, false)
593605
->filter(fn (Mergeable $prop) => $prop instanceof ScrollProp)
594-
->mapWithKeys(fn (ScrollProp $prop, string $key) => [$key => $prop->metadata()]);
606+
->mapWithKeys(fn (ScrollProp $prop, string $key) => [$key => [
607+
...$prop->metadata(),
608+
'reset' => in_array($key, $resetProps),
609+
]]);
595610

596611
return $scrollProps->isNotEmpty() ? ['scrollProps' => $scrollProps->toArray()] : [];
597612
}

tests/ResponseTest.php

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
use Inertia\LazyProp;
1818
use Inertia\MergeProp;
1919
use Inertia\ProvidesInertiaProperties;
20+
use Inertia\ProvidesScrollMetadata;
2021
use Inertia\RenderContext;
2122
use Inertia\Response;
23+
use Inertia\ScrollProp;
2224
use Inertia\Tests\Stubs\FakeResource;
2325
use Inertia\Tests\Stubs\MergeWithSharedProp;
2426
use Mockery;
27+
use PHPUnit\Framework\Attributes\DataProvider;
2528

2629
class ResponseTest extends TestCase
2730
{
@@ -138,6 +141,78 @@ public function test_server_response_with_deferred_prop_and_multiple_groups(): v
138141
$this->assertSame('<div id="app" data-page="{&quot;component&quot;:&quot;User\/Edit&quot;,&quot;props&quot;:{&quot;user&quot;:{&quot;name&quot;:&quot;Jonathan&quot;}},&quot;url&quot;:&quot;\/user\/123&quot;,&quot;version&quot;:&quot;123&quot;,&quot;clearHistory&quot;:false,&quot;encryptHistory&quot;:false,&quot;deferredProps&quot;:{&quot;default&quot;:[&quot;foo&quot;,&quot;bar&quot;],&quot;custom&quot;:[&quot;baz&quot;]}}"></div>', $view->render());
139142
}
140143

144+
/**
145+
* @return array<string, array{0: bool}>
146+
*/
147+
public static function resetUsersProp(): array
148+
{
149+
return [
150+
'no reset' => [false],
151+
'with reset' => [true],
152+
];
153+
}
154+
155+
#[DataProvider('resetUsersProp')]
156+
public function test_server_response_with_scroll_props(bool $resetUsersProp): void
157+
{
158+
$request = Request::create('/user/123', 'GET');
159+
160+
if ($resetUsersProp) {
161+
$request->headers->add(['X-Inertia-Reset' => 'users']);
162+
}
163+
164+
$response = new Response(
165+
'User/Index',
166+
[
167+
'users' => new ScrollProp(['data' => [['id' => 1]]], 'data', new class implements ProvidesScrollMetadata
168+
{
169+
public function getPageName(): string
170+
{
171+
return 'page';
172+
}
173+
174+
public function getPreviousPage(): ?int
175+
{
176+
return null;
177+
}
178+
179+
public function getNextPage(): int
180+
{
181+
return 2;
182+
}
183+
184+
public function getCurrentPage(): int
185+
{
186+
return 1;
187+
}
188+
}),
189+
],
190+
'app',
191+
'123'
192+
);
193+
$response = $response->toResponse($request);
194+
/** @var BaseResponse $response */
195+
$view = $response->getOriginalContent();
196+
$page = $view->getData()['page'];
197+
198+
$this->assertInstanceOf(BaseResponse::class, $response);
199+
$this->assertInstanceOf(View::class, $view);
200+
201+
$this->assertSame('User/Index', $page['component']);
202+
$this->assertSame(['data' => [['id' => 1]]], $page['props']['users']);
203+
$this->assertSame('/user/123', $page['url']);
204+
$this->assertSame('123', $page['version']);
205+
$this->assertSame([
206+
'users' => [
207+
'pageName' => 'page',
208+
'previousPage' => null,
209+
'nextPage' => 2,
210+
'currentPage' => 1,
211+
'reset' => $resetUsersProp,
212+
],
213+
], $page['scrollProps']);
214+
}
215+
141216
public function test_server_response_with_merge_props(): void
142217
{
143218
$request = Request::create('/user/123', 'GET');
@@ -501,6 +576,38 @@ public function test_exclude_merge_props_from_partial_except_response(): void
501576
$this->assertSame(['bar'], $page->mergeProps);
502577
}
503578

579+
public function test_exclude_merge_props_when_passed_in_reset_header(): void
580+
{
581+
$request = Request::create('/user/123', 'GET');
582+
$request->headers->add(['X-Inertia' => 'true']);
583+
$request->headers->add(['X-Inertia-Partial-Component' => 'User/Edit']);
584+
$request->headers->add(['X-Inertia-Partial-Data' => 'foo']);
585+
$request->headers->add(['X-Inertia-Reset' => 'foo']);
586+
587+
$user = ['name' => 'Jonathan'];
588+
$response = new Response(
589+
'User/Edit',
590+
[
591+
'user' => $user,
592+
'foo' => new MergeProp('foo value'),
593+
'bar' => new MergeProp('bar value'),
594+
],
595+
'app',
596+
'123'
597+
);
598+
599+
/** @var JsonResponse $response */
600+
$response = $response->toResponse($request);
601+
$page = $response->getData();
602+
603+
$props = get_object_vars($page->props);
604+
605+
$this->assertInstanceOf(JsonResponse::class, $response);
606+
$this->assertSame($props['foo'], 'foo value');
607+
$this->assertArrayNotHasKey('bar', $props);
608+
$this->assertFalse(isset($page->mergeProps));
609+
}
610+
504611
public function test_xhr_response(): void
505612
{
506613
$request = Request::create('/user/123', 'GET');

0 commit comments

Comments
 (0)