From 16b8733bcdd80047e33ec04e203b9166baf299a9 Mon Sep 17 00:00:00 2001 From: Claudio Dekker Date: Sun, 26 Dec 2021 18:10:29 +0100 Subject: [PATCH 1/3] Migrate to AssertableJson (Laravel-core) --- src/Testing/Assert.php | 6 + src/Testing/AssertableInertia.php | 83 +++++++++ src/Testing/TestResponseMacros.php | 11 +- tests/Testing/AssertTest.php | 202 +--------------------- tests/Testing/AssertableInertiaTest.php | 210 +++++++++++++++++++++++ tests/Testing/TestResponseMacrosTest.php | 8 +- 6 files changed, 322 insertions(+), 198 deletions(-) create mode 100644 src/Testing/AssertableInertia.php create mode 100644 tests/Testing/AssertableInertiaTest.php diff --git a/src/Testing/Assert.php b/src/Testing/Assert.php index 1b748d69..49dfee8a 100644 --- a/src/Testing/Assert.php +++ b/src/Testing/Assert.php @@ -34,6 +34,12 @@ class Assert implements Arrayable protected function __construct(string $component, array $props, string $url, string $version = null, string $path = null) { + echo "\033[0;31mInertia's built-in 'Assert' library will be removed in a future version of inertia-laravel:\033[0m\n"; + echo "\033[0;31m - If you are seeing this error while using \$response->assertInertia(...), please upgrade to Laravel 8.32.0 or higher.\033[0m\n"; + echo "\033[0;31m - If you are using the 'Assert' class directly, please adapt your tests to use the 'AssertableInertia' class instead.\033[0m\n"; + echo "\033[0;31mFor more information and questions, please see https://github.com/inertiajs/inertia-laravel/pull/334 \033[0m\n\n"; + @trigger_error("Inertia's built-in 'Assert' library will be removed in a future version of inertia-laravel", \E_USER_DEPRECATED); + $this->path = $path; $this->component = $component; diff --git a/src/Testing/AssertableInertia.php b/src/Testing/AssertableInertia.php new file mode 100644 index 00000000..69d01b91 --- /dev/null +++ b/src/Testing/AssertableInertia.php @@ -0,0 +1,83 @@ +assertViewHas('page'); + $page = json_decode(json_encode($response->viewData('page')), true); + + PHPUnit::assertIsArray($page); + PHPUnit::assertArrayHasKey('component', $page); + PHPUnit::assertArrayHasKey('props', $page); + PHPUnit::assertArrayHasKey('url', $page); + PHPUnit::assertArrayHasKey('version', $page); + } catch (AssertionFailedError $e) { + PHPUnit::fail('Not a valid Inertia response.'); + } + + $instance = static::fromArray($page['props']); + $instance->component = $page['component']; + $instance->url = $page['url']; + $instance->version = $page['version']; + + return $instance; + } + + public function component(string $value = null, $shouldExist = null): self + { + PHPUnit::assertSame($value, $this->component, 'Unexpected Inertia page component.'); + + if ($shouldExist || (is_null($shouldExist) && config('inertia.testing.ensure_pages_exist', true))) { + try { + app('inertia.testing.view-finder')->find($value); + } catch (InvalidArgumentException $exception) { + PHPUnit::fail(sprintf('Inertia page component file [%s] does not exist.', $value)); + } + } + + return $this; + } + + public function url(string $value): self + { + PHPUnit::assertSame($value, $this->url, 'Unexpected Inertia page url.'); + + return $this; + } + + public function version(string $value): self + { + PHPUnit::assertSame($value, $this->version, 'Unexpected Inertia asset version.'); + + return $this; + } + + public function toArray() + { + return [ + 'component' => $this->component, + 'props' => $this->prop(), + 'url' => $this->url, + 'version' => $this->version, + ]; + } +} diff --git a/src/Testing/TestResponseMacros.php b/src/Testing/TestResponseMacros.php index 59064d90..f5d9b0b9 100644 --- a/src/Testing/TestResponseMacros.php +++ b/src/Testing/TestResponseMacros.php @@ -3,13 +3,18 @@ namespace Inertia\Testing; use Closure; +use Illuminate\Testing\Fluent\AssertableJson; class TestResponseMacros { public function assertInertia() { return function (Closure $callback = null) { - $assert = Assert::fromTestResponse($this); + if (class_exists(AssertableJson::class)) { + $assert = AssertableInertia::fromTestResponse($this); + } else { + $assert = Assert::fromTestResponse($this); + } if (is_null($callback)) { return $this; @@ -24,6 +29,10 @@ public function assertInertia() public function inertiaPage() { return function () { + if (class_exists(AssertableJson::class)) { + return AssertableInertia::fromTestResponse($this)->toArray(); + } + return Assert::fromTestResponse($this)->toArray(); }; } diff --git a/tests/Testing/AssertTest.php b/tests/Testing/AssertTest.php index 745b4bfd..853867d0 100644 --- a/tests/Testing/AssertTest.php +++ b/tests/Testing/AssertTest.php @@ -7,6 +7,7 @@ use Illuminate\Foundation\Auth\User; use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Support\Collection; +use Illuminate\Testing\Fluent\AssertableJson; use Inertia\Inertia; use Inertia\Testing\Assert; use Inertia\Tests\TestCase; @@ -15,146 +16,13 @@ class AssertTest extends TestCase { - /** @test */ - public function the_view_is_served_by_inertia(): void + public function setUp(): void { - $response = $this->makeMockRequest( - Inertia::render('foo') - ); + parent::setUp(); - $response->assertInertia(); - } - - /** @test */ - public function the_view_is_not_served_by_inertia(): void - { - $response = $this->makeMockRequest(view('welcome')); - $response->assertOk(); // Make sure we can render the built-in Orchestra 'welcome' view.. - - $this->expectException(AssertionFailedError::class); - $this->expectExceptionMessage('Not a valid Inertia response.'); - - $response->assertInertia(); - } - - /** @test */ - public function the_component_matches(): void - { - $response = $this->makeMockRequest( - Inertia::render('foo') - ); - - $response->assertInertia(function (Assert $inertia) { - $inertia->component('foo'); - }); - } - - /** @test */ - public function the_component_does_not_match(): void - { - $response = $this->makeMockRequest( - Inertia::render('foo') - ); - - $this->expectException(AssertionFailedError::class); - $this->expectExceptionMessage('Unexpected Inertia page component.'); - - $response->assertInertia(function (Assert $inertia) { - $inertia->component('bar'); - }); - } - - /** @test */ - public function the_component_exists_on_the_filesystem(): void - { - $response = $this->makeMockRequest( - Inertia::render('Stubs/ExamplePage') - ); - - config()->set('inertia.testing.ensure_pages_exist', true); - $response->assertInertia(function (Assert $inertia) { - $inertia->component('Stubs/ExamplePage'); - }); - } - - /** @test */ - public function the_component_does_not_exist_on_the_filesystem(): void - { - $response = $this->makeMockRequest( - Inertia::render('foo') - ); - - config()->set('inertia.testing.ensure_pages_exist', true); - $this->expectException(AssertionFailedError::class); - $this->expectExceptionMessage('Inertia page component file [foo] does not exist.'); - - $response->assertInertia(function (Assert $inertia) { - $inertia->component('foo'); - }); - } - - /** @test */ - public function it_can_force_enable_the_component_file_existence(): void - { - $response = $this->makeMockRequest( - Inertia::render('foo') - ); - - config()->set('inertia.testing.ensure_pages_exist', false); - $this->expectException(AssertionFailedError::class); - $this->expectExceptionMessage('Inertia page component file [foo] does not exist.'); - - $response->assertInertia(function (Assert $inertia) { - $inertia->component('foo', true); - }); - } - - /** @test */ - public function it_can_force_disable_the_component_file_existence_check(): void - { - $response = $this->makeMockRequest( - Inertia::render('foo') - ); - - config()->set('inertia.testing.ensure_pages_exist', true); - - $response->assertInertia(function (Assert $inertia) { - $inertia->component('foo', false); - }); - } - - /** @test */ - public function the_component_does_not_exist_on_the_filesystem_when_it_does_not_exist_relative_to_any_of_the_given_paths(): void - { - $response = $this->makeMockRequest( - Inertia::render('fixtures/ExamplePage') - ); - - config()->set('inertia.testing.ensure_pages_exist', true); - config()->set('inertia.testing.page_paths', [realpath(__DIR__)]); - $this->expectException(AssertionFailedError::class); - $this->expectExceptionMessage('Inertia page component file [fixtures/ExamplePage] does not exist.'); - - $response->assertInertia(function (Assert $inertia) { - $inertia->component('fixtures/ExamplePage'); - }); - } - - /** @test */ - public function the_component_does_not_exist_on_the_filesystem_when_it_does_not_have_one_of_the_configured_extensions(): void - { - $response = $this->makeMockRequest( - Inertia::render('fixtures/ExamplePage') - ); - - config()->set('inertia.testing.ensure_pages_exist', true); - config()->set('inertia.testing.page_extensions', ['bin', 'exe', 'svg']); - $this->expectException(AssertionFailedError::class); - $this->expectExceptionMessage('Inertia page component file [fixtures/ExamplePage] does not exist.'); - - $response->assertInertia(function (Assert $inertia) { - $inertia->component('fixtures/ExamplePage'); - }); + if (class_exists(AssertableJson::class)) { + $this->markTestSkipped("These tests are not applicable on Laravel 8.32 or newer, as Laravel's built-in AssertableJson is used instead."); + } } /** @test */ @@ -1202,64 +1070,6 @@ public function it_cannot_count_multiple_props_at_once_when_at_least_one_is_miss }); } - /** @test */ - public function the_page_url_matches(): void - { - $response = $this->makeMockRequest( - Inertia::render('foo') - ); - - $response->assertInertia(function (Assert $inertia) { - $inertia->url('/example-url'); - }); - } - - /** @test */ - public function the_page_url_does_not_match(): void - { - $response = $this->makeMockRequest( - Inertia::render('foo') - ); - - $this->expectException(AssertionFailedError::class); - $this->expectExceptionMessage('Unexpected Inertia page url.'); - - $response->assertInertia(function (Assert $inertia) { - $inertia->url('/invalid-page'); - }); - } - - /** @test */ - public function the_asset_version_matches(): void - { - Inertia::version('example-version'); - - $response = $this->makeMockRequest( - Inertia::render('foo') - ); - - $response->assertInertia(function (Assert $inertia) { - $inertia->version('example-version'); - }); - } - - /** @test */ - public function the_asset_version_does_not_match(): void - { - Inertia::version('example-version'); - - $response = $this->makeMockRequest( - Inertia::render('foo') - ); - - $this->expectException(AssertionFailedError::class); - $this->expectExceptionMessage('Unexpected Inertia asset version.'); - - $response->assertInertia(function (Assert $inertia) { - $inertia->version('different-version'); - }); - } - /** @test */ public function it_is_macroable(): void { diff --git a/tests/Testing/AssertableInertiaTest.php b/tests/Testing/AssertableInertiaTest.php new file mode 100644 index 00000000..613cccc2 --- /dev/null +++ b/tests/Testing/AssertableInertiaTest.php @@ -0,0 +1,210 @@ +makeMockRequest( + Inertia::render('foo') + ); + + $response->assertInertia(); + } + + /** @test */ + public function the_view_is_not_served_by_inertia(): void + { + $response = $this->makeMockRequest(view('welcome')); + $response->assertOk(); // Make sure we can render the built-in Orchestra 'welcome' view.. + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('Not a valid Inertia response.'); + + $response->assertInertia(); + } + + /** @test */ + public function the_component_matches(): void + { + $response = $this->makeMockRequest( + Inertia::render('foo') + ); + + $response->assertInertia(function ($inertia) { + $inertia->component('foo'); + }); + } + + /** @test */ + public function the_component_does_not_match(): void + { + $response = $this->makeMockRequest( + Inertia::render('foo') + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('Unexpected Inertia page component.'); + + $response->assertInertia(function ($inertia) { + $inertia->component('bar'); + }); + } + + /** @test */ + public function the_component_exists_on_the_filesystem(): void + { + $response = $this->makeMockRequest( + Inertia::render('Stubs/ExamplePage') + ); + + config()->set('inertia.testing.ensure_pages_exist', true); + $response->assertInertia(function ($inertia) { + $inertia->component('Stubs/ExamplePage'); + }); + } + + /** @test */ + public function the_component_does_not_exist_on_the_filesystem(): void + { + $response = $this->makeMockRequest( + Inertia::render('foo') + ); + + config()->set('inertia.testing.ensure_pages_exist', true); + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('Inertia page component file [foo] does not exist.'); + + $response->assertInertia(function ($inertia) { + $inertia->component('foo'); + }); + } + + /** @test */ + public function it_can_force_enable_the_component_file_existence(): void + { + $response = $this->makeMockRequest( + Inertia::render('foo') + ); + + config()->set('inertia.testing.ensure_pages_exist', false); + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('Inertia page component file [foo] does not exist.'); + + $response->assertInertia(function ($inertia) { + $inertia->component('foo', true); + }); + } + + /** @test */ + public function it_can_force_disable_the_component_file_existence_check(): void + { + $response = $this->makeMockRequest( + Inertia::render('foo') + ); + + config()->set('inertia.testing.ensure_pages_exist', true); + + $response->assertInertia(function ($inertia) { + $inertia->component('foo', false); + }); + } + + /** @test */ + public function the_component_does_not_exist_on_the_filesystem_when_it_does_not_exist_relative_to_any_of_the_given_paths(): void + { + $response = $this->makeMockRequest( + Inertia::render('fixtures/ExamplePage') + ); + + config()->set('inertia.testing.ensure_pages_exist', true); + config()->set('inertia.testing.page_paths', [realpath(__DIR__)]); + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('Inertia page component file [fixtures/ExamplePage] does not exist.'); + + $response->assertInertia(function ($inertia) { + $inertia->component('fixtures/ExamplePage'); + }); + } + + /** @test */ + public function the_component_does_not_exist_on_the_filesystem_when_it_does_not_have_one_of_the_configured_extensions(): void + { + $response = $this->makeMockRequest( + Inertia::render('fixtures/ExamplePage') + ); + + config()->set('inertia.testing.ensure_pages_exist', true); + config()->set('inertia.testing.page_extensions', ['bin', 'exe', 'svg']); + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('Inertia page component file [fixtures/ExamplePage] does not exist.'); + + $response->assertInertia(function ($inertia) { + $inertia->component('fixtures/ExamplePage'); + }); + } + + /** @test */ + public function the_page_url_matches(): void + { + $response = $this->makeMockRequest( + Inertia::render('foo') + ); + + $response->assertInertia(function ($inertia) { + $inertia->url('/example-url'); + }); + } + + /** @test */ + public function the_page_url_does_not_match(): void + { + $response = $this->makeMockRequest( + Inertia::render('foo') + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('Unexpected Inertia page url.'); + + $response->assertInertia(function ($inertia) { + $inertia->url('/invalid-page'); + }); + } + + /** @test */ + public function the_asset_version_matches(): void + { + Inertia::version('example-version'); + + $response = $this->makeMockRequest( + Inertia::render('foo') + ); + + $response->assertInertia(function ($inertia) { + $inertia->version('example-version'); + }); + } + + /** @test */ + public function the_asset_version_does_not_match(): void + { + Inertia::version('example-version'); + + $response = $this->makeMockRequest( + Inertia::render('foo') + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('Unexpected Inertia asset version.'); + + $response->assertInertia(function ($inertia) { + $inertia->version('different-version'); + }); + } +} diff --git a/tests/Testing/TestResponseMacrosTest.php b/tests/Testing/TestResponseMacrosTest.php index dc44f18b..a987d7b4 100644 --- a/tests/Testing/TestResponseMacrosTest.php +++ b/tests/Testing/TestResponseMacrosTest.php @@ -2,6 +2,7 @@ namespace Inertia\Tests\Testing; +use Illuminate\Testing\Fluent\AssertableJson; use Inertia\Inertia; use Inertia\Testing\Assert; use Inertia\Tests\TestCase; @@ -17,7 +18,12 @@ public function it_can_make_inertia_assertions(): void $success = false; $response->assertInertia(function ($page) use (&$success) { - $this->assertInstanceOf(Assert::class, $page); + if (class_exists(AssertableJson::class)) { + $this->assertInstanceOf(AssertableJson::class, $page); + } else { + // TODO: Remove once built-in Assert library is removed. + $this->assertInstanceOf(Assert::class, $page); + } $success = true; }); From 93dac4a3258f793b0b52215dbf999a4498120d43 Mon Sep 17 00:00:00 2001 From: Claudio Dekker Date: Sun, 26 Dec 2021 19:34:01 +0100 Subject: [PATCH 2/3] Update PR number --- src/Testing/Assert.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Testing/Assert.php b/src/Testing/Assert.php index 49dfee8a..fcb5a4aa 100644 --- a/src/Testing/Assert.php +++ b/src/Testing/Assert.php @@ -37,7 +37,7 @@ protected function __construct(string $component, array $props, string $url, str echo "\033[0;31mInertia's built-in 'Assert' library will be removed in a future version of inertia-laravel:\033[0m\n"; echo "\033[0;31m - If you are seeing this error while using \$response->assertInertia(...), please upgrade to Laravel 8.32.0 or higher.\033[0m\n"; echo "\033[0;31m - If you are using the 'Assert' class directly, please adapt your tests to use the 'AssertableInertia' class instead.\033[0m\n"; - echo "\033[0;31mFor more information and questions, please see https://github.com/inertiajs/inertia-laravel/pull/334 \033[0m\n\n"; + echo "\033[0;31mFor more information and questions, please see https://github.com/inertiajs/inertia-laravel/pull/338 \033[0m\n\n"; @trigger_error("Inertia's built-in 'Assert' library will be removed in a future version of inertia-laravel", \E_USER_DEPRECATED); $this->path = $path; From 58b358a3714b10ae9758794d61e07b3ecde6ce79 Mon Sep 17 00:00:00 2001 From: Claudio Dekker Date: Sun, 26 Dec 2021 19:34:42 +0100 Subject: [PATCH 3/3] Add link in actual error --- src/Testing/Assert.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Testing/Assert.php b/src/Testing/Assert.php index fcb5a4aa..663ce394 100644 --- a/src/Testing/Assert.php +++ b/src/Testing/Assert.php @@ -38,7 +38,7 @@ protected function __construct(string $component, array $props, string $url, str echo "\033[0;31m - If you are seeing this error while using \$response->assertInertia(...), please upgrade to Laravel 8.32.0 or higher.\033[0m\n"; echo "\033[0;31m - If you are using the 'Assert' class directly, please adapt your tests to use the 'AssertableInertia' class instead.\033[0m\n"; echo "\033[0;31mFor more information and questions, please see https://github.com/inertiajs/inertia-laravel/pull/338 \033[0m\n\n"; - @trigger_error("Inertia's built-in 'Assert' library will be removed in a future version of inertia-laravel", \E_USER_DEPRECATED); + @trigger_error("Inertia's built-in 'Assert' library will be removed in a future version of inertia-laravel: https://github.com/inertiajs/inertia-laravel/pull/338", \E_USER_DEPRECATED); $this->path = $path;