Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions src/Testing/AssertableInertia.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Inertia\Testing;

use Closure;
use Illuminate\Testing\Fluent\AssertableJson;
use Illuminate\Testing\TestResponse;
use InvalidArgumentException;
Expand Down Expand Up @@ -81,6 +82,69 @@ public function version(string $value): self
return $this;
}

/**
* Reload the Inertia page and perform assertions on the response.
*/
public function reload(?Closure $callback = null, array|string|null $only = null, array|string|null $except = null): self
{
if (is_array($only)) {
$only = implode(',', $only);
}

if (is_array($except)) {
$except = implode(',', $except);
}

$reloadRequest = new ReloadRequest(
$this->url,
$this->component,
$this->version,
$only,
$except,
);

$assertable = AssertableInertia::fromTestResponse($reloadRequest());

// Make sure we get the same data as the original request.
$assertable->component($this->component);
$assertable->url($this->url);
$assertable->version($this->version);

if ($callback) {
$callback($assertable);
}

return $this;
}

/**
* Reload the Inertia page as a partial request with only the specified props.
*/
public function reloadOnly(array|string $only, ?Closure $callback = null): self
{
return $this->reload(only: $only, callback: function (AssertableInertia $assertable) use ($only, $callback) {
$assertable->hasAll(explode(',', $only));

if ($callback) {
$callback($assertable);
}
});
}

/**
* Reload the Inertia page as a partial request excluding the specified props.
*/
public function reloadExcept(array|string $except, ?Closure $callback = null): self
{
return $this->reload(except: $except, callback: function (AssertableInertia $assertable) use ($except, $callback) {
$assertable->missingAll(explode(',', $except));

if ($callback) {
$callback($assertable);
}
});
}

public function toArray()
{
return [
Expand Down
47 changes: 47 additions & 0 deletions src/Testing/ReloadRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Inertia\Testing;

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Testing\Concerns\MakesHttpRequests;
use Illuminate\Testing\TestResponse;
use Inertia\Support\Header;

class ReloadRequest
{
use MakesHttpRequests;

/**
* Create a new Inertia reload request instance.
*/
public function __construct(
protected string $url,
protected string $component,
protected string $version,
protected ?string $only = null,
protected ?string $except = null,
protected ?Application $app = null
) {
$this->app ??= app();
}

/**
* Request the Inertia page as a partial reload.
*/
public function __invoke(): TestResponse
{
$headers = [Header::VERSION => $this->version];

if (! blank($this->only)) {
$headers[Header::PARTIAL_COMPONENT] = $this->component;
$headers[Header::PARTIAL_ONLY] = $this->only;
}

if (! blank($this->except)) {
$headers[Header::PARTIAL_COMPONENT] = $this->component;
$headers[Header::PARTIAL_EXCEPT] = $this->except;
}

return $this->get($this->url, $headers);
}
}
2 changes: 1 addition & 1 deletion tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ protected function getTestResponseClass(): string
protected function makeMockRequest($view)
{
app('router')->get('/example-url', function () use ($view) {
return $view;
return is_callable($view) ? $view() : $view;
});

return $this->get('/example-url');
Expand Down
83 changes: 83 additions & 0 deletions tests/Testing/AssertableInertiaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Inertia\Tests\Testing;

use Inertia\Inertia;
use Inertia\Testing\AssertableInertia;
use Inertia\Tests\TestCase;
use PHPUnit\Framework\AssertionFailedError;

Expand Down Expand Up @@ -193,4 +194,86 @@ public function test_the_asset_version_does_not_match(): void
$inertia->version('different-version');
});
}

public function test_reloading_a_visit(): void
{
$foo = 0;

$response = $this->makeMockRequest(function () use (&$foo) {
return Inertia::render('foo', [
'foo' => $foo++,
]);
});

$called = false;

$response->assertInertia(function ($inertia) use (&$called) {
$inertia->where('foo', 0);

$inertia->reload(function ($inertia) use (&$called) {
$inertia->where('foo', 1);
$called = true;
});
});

$this->assertTrue($called);
}

public function test_lazy_props_can_be_evaluated(): void
{
$response = $this->makeMockRequest(
Inertia::render('foo', [
'foo' => 'bar',
'lazy1' => Inertia::lazy(fn () => 'baz'),
'lazy2' => Inertia::lazy(fn () => 'qux'),
])
);

$called = false;

$response->assertInertia(function ($inertia) use (&$called) {
$inertia->where('foo', 'bar');
$inertia->missing('lazy1');
$inertia->missing('lazy2');

$result = $inertia->reloadOnly('lazy1', function ($inertia) use (&$called) {
$inertia->missing('foo');
$inertia->where('lazy1', 'baz');
$inertia->missing('lazy2');
$called = true;
});

$this->assertSame($result, $inertia);
});

$this->assertTrue($called);
}

public function test_lazy_props_can_be_evaluated_with_except(): void
{
$response = $this->makeMockRequest(
Inertia::render('foo', [
'foo' => 'bar',
'lazy1' => Inertia::lazy(fn () => 'baz'),
'lazy2' => Inertia::lazy(fn () => 'qux'),
])
);

$called = false;

$response->assertInertia(function (AssertableInertia $inertia) use (&$called) {
$inertia->where('foo', 'bar');
$inertia->missing('lazy1');
$inertia->missing('lazy2');

$inertia->reloadExcept('lazy1', function ($inertia) use (&$called) {
$inertia->where('foo', 'bar');
$inertia->missing('lazy1');
$inertia->where('lazy2', 'qux');
$called = true;
});
});

$this->assertTrue($called);
}
}