Skip to content

Commit 0b8c005

Browse files
authored
Merge pull request #738 from inertiajs/test-helper-for-partial-requests
[2.x] Test helper for partial requests
2 parents a1f1626 + bfff228 commit 0b8c005

File tree

4 files changed

+195
-1
lines changed

4 files changed

+195
-1
lines changed

src/Testing/AssertableInertia.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Inertia\Testing;
44

5+
use Closure;
56
use Illuminate\Testing\Fluent\AssertableJson;
67
use Illuminate\Testing\TestResponse;
78
use InvalidArgumentException;
@@ -81,6 +82,69 @@ public function version(string $value): self
8182
return $this;
8283
}
8384

85+
/**
86+
* Reload the Inertia page and perform assertions on the response.
87+
*/
88+
public function reload(?Closure $callback = null, array|string|null $only = null, array|string|null $except = null): self
89+
{
90+
if (is_array($only)) {
91+
$only = implode(',', $only);
92+
}
93+
94+
if (is_array($except)) {
95+
$except = implode(',', $except);
96+
}
97+
98+
$reloadRequest = new ReloadRequest(
99+
$this->url,
100+
$this->component,
101+
$this->version,
102+
$only,
103+
$except,
104+
);
105+
106+
$assertable = AssertableInertia::fromTestResponse($reloadRequest());
107+
108+
// Make sure we get the same data as the original request.
109+
$assertable->component($this->component);
110+
$assertable->url($this->url);
111+
$assertable->version($this->version);
112+
113+
if ($callback) {
114+
$callback($assertable);
115+
}
116+
117+
return $this;
118+
}
119+
120+
/**
121+
* Reload the Inertia page as a partial request with only the specified props.
122+
*/
123+
public function reloadOnly(array|string $only, ?Closure $callback = null): self
124+
{
125+
return $this->reload(only: $only, callback: function (AssertableInertia $assertable) use ($only, $callback) {
126+
$assertable->hasAll(explode(',', $only));
127+
128+
if ($callback) {
129+
$callback($assertable);
130+
}
131+
});
132+
}
133+
134+
/**
135+
* Reload the Inertia page as a partial request excluding the specified props.
136+
*/
137+
public function reloadExcept(array|string $except, ?Closure $callback = null): self
138+
{
139+
return $this->reload(except: $except, callback: function (AssertableInertia $assertable) use ($except, $callback) {
140+
$assertable->missingAll(explode(',', $except));
141+
142+
if ($callback) {
143+
$callback($assertable);
144+
}
145+
});
146+
}
147+
84148
public function toArray()
85149
{
86150
return [

src/Testing/ReloadRequest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Inertia\Testing;
4+
5+
use Illuminate\Foundation\Application;
6+
use Illuminate\Foundation\Testing\Concerns\MakesHttpRequests;
7+
use Illuminate\Testing\TestResponse;
8+
use Inertia\Support\Header;
9+
10+
class ReloadRequest
11+
{
12+
use MakesHttpRequests;
13+
14+
/**
15+
* Create a new Inertia reload request instance.
16+
*/
17+
public function __construct(
18+
protected string $url,
19+
protected string $component,
20+
protected string $version,
21+
protected ?string $only = null,
22+
protected ?string $except = null,
23+
protected ?Application $app = null
24+
) {
25+
$this->app ??= app();
26+
}
27+
28+
/**
29+
* Request the Inertia page as a partial reload.
30+
*/
31+
public function __invoke(): TestResponse
32+
{
33+
$headers = [Header::VERSION => $this->version];
34+
35+
if (! blank($this->only)) {
36+
$headers[Header::PARTIAL_COMPONENT] = $this->component;
37+
$headers[Header::PARTIAL_ONLY] = $this->only;
38+
}
39+
40+
if (! blank($this->except)) {
41+
$headers[Header::PARTIAL_COMPONENT] = $this->component;
42+
$headers[Header::PARTIAL_EXCEPT] = $this->except;
43+
}
44+
45+
return $this->get($this->url, $headers);
46+
}
47+
}

tests/TestCase.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ protected function setUp(): void
3131
protected function makeMockRequest($view): TestResponse
3232
{
3333
app('router')->get('/example-url', function () use ($view) {
34-
return $view;
34+
return is_callable($view) ? $view() : $view;
3535
});
3636

3737
return $this->get('/example-url');

tests/Testing/AssertableInertiaTest.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Inertia\Tests\Testing;
44

55
use Inertia\Inertia;
6+
use Inertia\Testing\AssertableInertia;
67
use Inertia\Tests\TestCase;
78
use PHPUnit\Framework\AssertionFailedError;
89

@@ -193,4 +194,86 @@ public function test_the_asset_version_does_not_match(): void
193194
$inertia->version('different-version');
194195
});
195196
}
197+
198+
public function test_reloading_a_visit(): void
199+
{
200+
$foo = 0;
201+
202+
$response = $this->makeMockRequest(function () use (&$foo) {
203+
return Inertia::render('foo', [
204+
'foo' => $foo++,
205+
]);
206+
});
207+
208+
$called = false;
209+
210+
$response->assertInertia(function ($inertia) use (&$called) {
211+
$inertia->where('foo', 0);
212+
213+
$inertia->reload(function ($inertia) use (&$called) {
214+
$inertia->where('foo', 1);
215+
$called = true;
216+
});
217+
});
218+
219+
$this->assertTrue($called);
220+
}
221+
222+
public function test_lazy_props_can_be_evaluated(): void
223+
{
224+
$response = $this->makeMockRequest(
225+
Inertia::render('foo', [
226+
'foo' => 'bar',
227+
'lazy1' => Inertia::lazy(fn () => 'baz'),
228+
'lazy2' => Inertia::lazy(fn () => 'qux'),
229+
])
230+
);
231+
232+
$called = false;
233+
234+
$response->assertInertia(function ($inertia) use (&$called) {
235+
$inertia->where('foo', 'bar');
236+
$inertia->missing('lazy1');
237+
$inertia->missing('lazy2');
238+
239+
$result = $inertia->reloadOnly('lazy1', function ($inertia) use (&$called) {
240+
$inertia->missing('foo');
241+
$inertia->where('lazy1', 'baz');
242+
$inertia->missing('lazy2');
243+
$called = true;
244+
});
245+
246+
$this->assertSame($result, $inertia);
247+
});
248+
249+
$this->assertTrue($called);
250+
}
251+
252+
public function test_lazy_props_can_be_evaluated_with_except(): void
253+
{
254+
$response = $this->makeMockRequest(
255+
Inertia::render('foo', [
256+
'foo' => 'bar',
257+
'lazy1' => Inertia::lazy(fn () => 'baz'),
258+
'lazy2' => Inertia::lazy(fn () => 'qux'),
259+
])
260+
);
261+
262+
$called = false;
263+
264+
$response->assertInertia(function (AssertableInertia $inertia) use (&$called) {
265+
$inertia->where('foo', 'bar');
266+
$inertia->missing('lazy1');
267+
$inertia->missing('lazy2');
268+
269+
$inertia->reloadExcept('lazy1', function ($inertia) use (&$called) {
270+
$inertia->where('foo', 'bar');
271+
$inertia->missing('lazy1');
272+
$inertia->where('lazy2', 'qux');
273+
$called = true;
274+
});
275+
});
276+
277+
$this->assertTrue($called);
278+
}
196279
}

0 commit comments

Comments
 (0)