Skip to content

Commit 051dcff

Browse files
committed
Added inertia:check-ssr Artisan command and isHealthy() method on HttpGateway
1 parent d2ea2a5 commit 051dcff

File tree

6 files changed

+162
-9
lines changed

6 files changed

+162
-9
lines changed

src/Commands/CheckSsr.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Inertia\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use Inertia\Ssr\Gateway;
7+
use Inertia\Ssr\HasHealthCheck;
8+
use Symfony\Component\Console\Attribute\AsCommand;
9+
10+
#[AsCommand(name: 'inertia:check-ssr')]
11+
class CheckSsr extends Command
12+
{
13+
/**
14+
* The console command name.
15+
*
16+
* @var string
17+
*/
18+
protected $signature = 'inertia:check-ssr';
19+
20+
/**
21+
* The console command description.
22+
*
23+
* @var string
24+
*/
25+
protected $description = 'Check the Inertia SSR server health status';
26+
27+
/**
28+
* check the SSR server via a Node process.
29+
*/
30+
public function handle(Gateway $gateway): int
31+
{
32+
if (! $gateway instanceof HasHealthCheck) {
33+
$this->error('The SSR gateway does not support health checks.');
34+
35+
return self::FAILURE;
36+
}
37+
38+
($check = $gateway->isHealthy())
39+
? $this->info('Inertia SSR server is running.')
40+
: $this->error('Inertia SSR server is not running.');
41+
42+
return $check ? self::SUCCESS : self::FAILURE;
43+
}
44+
}

src/ServiceProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ protected function registerConsoleCommands(): void
6868
Commands\CreateMiddleware::class,
6969
Commands\StartSsr::class,
7070
Commands\StopSsr::class,
71+
Commands\CheckSsr::class,
7172
]);
7273
}
7374

src/Ssr/HasHealthCheck.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Inertia\Ssr;
4+
5+
interface HasHealthCheck
6+
{
7+
/**
8+
* Determine if the SSR server is healthy.
9+
*/
10+
public function isHealthy(): bool;
11+
}

src/Ssr/HttpGateway.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
use Exception;
66
use Illuminate\Http\Client\StrayRequestException;
77
use Illuminate\Support\Facades\Http;
8+
use Illuminate\Support\Str;
89

9-
class HttpGateway implements Gateway
10+
class HttpGateway implements Gateway, HasHealthCheck
1011
{
1112
/**
1213
* Dispatch the Inertia page to the Server Side Rendering engine.
@@ -21,7 +22,7 @@ public function dispatch(array $page): ?Response
2122
return null;
2223
}
2324

24-
if (! $url = $this->getHttpUrl()) {
25+
if (! $url = $this->getUrl('/render')) {
2526
return null;
2627
}
2728

@@ -45,6 +46,14 @@ public function dispatch(array $page): ?Response
4546
);
4647
}
4748

49+
/**
50+
* Determine if the SSR server is healthy.
51+
*/
52+
public function isHealthy(): bool
53+
{
54+
return Http::get($this->getUrl('/health'))->successful();
55+
}
56+
4857
/**
4958
* Determine if dispatch should proceed even if no bundle is detected.
5059
*/
@@ -62,10 +71,12 @@ protected function bundleExists(): bool
6271
}
6372

6473
/**
65-
* Get the SSR URL from the configuration, ensuring it ends with '/render'.
74+
* Get the SSR URL from the configuration, ensuring it ends with '/{$path}'.
6675
*/
67-
public function getHttpUrl(): ?string
76+
public function getUrl(string $path): ?string
6877
{
69-
return str_replace('/render', '', rtrim(config('inertia.ssr.url', 'http://127.0.0.1:13714'), '/')).'/render';
78+
$path = Str::start($path, '/');
79+
80+
return str_replace($path, '', rtrim(config('inertia.ssr.url', 'http://127.0.0.1:13714'), '/')).$path;
7081
}
7182
}

tests/Commands/CheckSsrTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
namespace Inertia\Tests;
4+
5+
use Illuminate\Foundation\Application;
6+
use Inertia\Commands\CheckSsr; // Assuming you updated the command name
7+
use Inertia\Ssr\Gateway;
8+
use Inertia\Ssr\HttpGateway; // Your concrete Gateway implementation
9+
use Mockery as m;
10+
use PHPUnit\Framework\TestCase;
11+
use Symfony\Component\Console\Input\ArrayInput;
12+
use Symfony\Component\Console\Output\BufferedOutput; // Import BufferedOutput
13+
14+
class CheckSsrTest extends TestCase
15+
{
16+
protected function tearDown(): void
17+
{
18+
m::close();
19+
}
20+
21+
public function test_success_on_healthy_ssr_server()
22+
{
23+
$container = new Application;
24+
$container->instance(Gateway::class, m::mock(HttpGateway::class)
25+
->shouldReceive('isHealthy')
26+
->andReturnTrue()
27+
->getMock()
28+
);
29+
30+
$command = new CheckSsr;
31+
$command->setLaravel($container);
32+
33+
$exitCode = $command->run(new ArrayInput([]), $output = new BufferedOutput);
34+
35+
$this->assertEquals(0, $exitCode);
36+
$this->assertStringContainsString('Inertia SSR server is running.', $output->fetch());
37+
}
38+
39+
public function test_failure_on_unhealthy_ssr_server()
40+
{
41+
$container = new Application;
42+
$container->instance(Gateway::class, m::mock(HttpGateway::class)
43+
->shouldReceive('isHealthy')
44+
->andReturnFalse()
45+
->getMock()
46+
);
47+
48+
$command = new CheckSsr;
49+
$command->setLaravel($container);
50+
51+
$exitCode = $command->run(new ArrayInput([]), $output = new BufferedOutput);
52+
53+
$this->assertEquals(1, $exitCode);
54+
$this->assertStringContainsString('Inertia SSR server is not running.', $output->fetch());
55+
}
56+
57+
public function test_failure_on_unsupported_gateway()
58+
{
59+
$container = new Application;
60+
$container->instance(Gateway::class, m::mock(Gateway::class));
61+
62+
$command = new CheckSsr;
63+
$command->setLaravel($container);
64+
65+
$output = new BufferedOutput;
66+
$exitCode = $command->run(new ArrayInput([]), $output = new BufferedOutput);
67+
68+
$this->assertEquals(1, $exitCode);
69+
$this->assertStringContainsString('The SSR gateway does not support health checks.', $output->fetch());
70+
}
71+
}

tests/HttpGatewayTest.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ class HttpGatewayTest extends TestCase
99
{
1010
protected HttpGateway $gateway;
1111

12+
protected string $renderUrl;
13+
1214
protected function setUp(): void
1315
{
1416
parent::setUp();
1517

1618
$this->gateway = new HttpGateway;
19+
$this->renderUrl = $this->gateway->getUrl('render');
1720

1821
Http::preventStrayRequests();
1922
}
@@ -46,7 +49,7 @@ public function test_it_uses_the_configured_http_url_when_the_bundle_file_is_det
4649
]);
4750

4851
Http::fake([
49-
$this->gateway->getHttpUrl() => Http::response(json_encode([
52+
$this->renderUrl => Http::response(json_encode([
5053
'head' => ['<title>SSR Test</title>', '<style></style>'],
5154
'body' => '<div id="app">SSR Response</div>',
5255
])),
@@ -69,7 +72,7 @@ public function test_it_uses_the_configured_http_url__when_bundle_file_detection
6972
]);
7073

7174
Http::fake([
72-
$this->gateway->getHttpUrl() => Http::response(json_encode([
75+
$this->renderUrl => Http::response(json_encode([
7376
'head' => ['<title>SSR Test</title>', '<style></style>'],
7477
'body' => '<div id="app">SSR Response</div>',
7578
])),
@@ -91,7 +94,7 @@ public function test_it_returns_null_when_the_http_request_fails()
9194
]);
9295

9396
Http::fake([
94-
$this->gateway->getHttpUrl() => Http::response(null, 500),
97+
$this->renderUrl => Http::response(null, 500),
9598
]);
9699

97100
$this->assertNull($this->gateway->dispatch(['page' => self::EXAMPLE_PAGE_OBJECT]));
@@ -105,9 +108,21 @@ public function test_it_returns_null_when_invalid_json_is_returned()
105108
]);
106109

107110
Http::fake([
108-
$this->gateway->getHttpUrl() => Http::response('invalid json'),
111+
$this->renderUrl => Http::response('invalid json'),
109112
]);
110113

111114
$this->assertNull($this->gateway->dispatch(['page' => self::EXAMPLE_PAGE_OBJECT]));
112115
}
116+
117+
public function test_health_check_the_ssr_server()
118+
{
119+
Http::fake([
120+
$this->gateway->getUrl('health') => Http::sequence()
121+
->push(status: 200)
122+
->push(status: 500),
123+
]);
124+
125+
$this->assertTrue($this->gateway->isHealthy());
126+
$this->assertFalse($this->gateway->isHealthy());
127+
}
113128
}

0 commit comments

Comments
 (0)