Skip to content
Merged
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ This serves two purposes:
- Added missing collection key types in Hyde facade method annotations in https://github.com/hydephp/develop/pull/1784
- Fixed heading permalinks button text showing in Google Search previews https://github.com/hydephp/develop/issues/1801 in https://github.com/hydephp/develop/pull/1803
- Realtime Compiler: Updated the exception handler to match HTTP exception codes when sending error responses in https://github.com/hydephp/develop/pull/1853
- Realtime Compiler: Improved routing for nested index pages in https://github.com/hydephp/develop/pull/1852

### Security
- in case of vulnerabilities.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
class PathNormalizerMiddleware
{
protected array $pathRewrites = [
'/docs' => '/docs/index',
'/docs/search.html' => '/docs/search',
];

Expand Down
13 changes: 12 additions & 1 deletion packages/realtime-compiler/src/Routing/PageRouter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Hyde\Pages\Concerns\BaseMarkdownPage;
use Hyde\Framework\Actions\StaticPageBuilder;
use Hyde\RealtimeCompiler\Http\LiveEditController;
use Hyde\Framework\Exceptions\RouteNotFoundException;
use Hyde\Framework\Features\Documentation\DocumentationSearchPage;
use Hyde\Pages\Concerns\HydePage;
use Hyde\RealtimeCompiler\Concerns\InteractsWithLaravel;
Expand Down Expand Up @@ -98,6 +99,16 @@ protected function getPageFromRoute(): HydePage
return new DocumentationSearchPage();
}

return Routes::getOrFail($this->normalizePath($this->request->path))->getPage();
try {
return Routes::getOrFail($this->normalizePath($this->request->path))->getPage();
} catch (RouteNotFoundException $exception) {
$index = Routes::get($this->normalizePath($this->request->path).'/index');

if ($index) {
return $index->getPage();
}

throw $exception;
}
}
}
37 changes: 37 additions & 0 deletions packages/realtime-compiler/tests/Integration/IntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,39 @@ public function test404()
->assertSeeText('Route [non-existent-page] not found.');
}

public function testNestedIndexPageRouting()
{
if (! is_dir($this->projectPath('_pages/about'))) {
mkdir($this->projectPath('_pages/about'), 0755, true);
}

file_put_contents($this->projectPath('_docs/index.md'), '# Documentation');
file_put_contents($this->projectPath('_pages/about/index.md'), '# About');
file_put_contents($this->projectPath('_pages/about/contact.md'), '# Contact');

$this->get('/docs/index.html')->assertStatus(200)->assertSeeText('Documentation');
$this->get('/about/index.html')->assertStatus(200)->assertSeeText('About');
$this->get('/about/contact.html')->assertStatus(200)->assertSeeText('Contact');

$this->get('/docs/index')->assertStatus(200)->assertSeeText('Documentation');
$this->get('/about/index')->assertStatus(200)->assertSeeText('About');
$this->get('/about/contact')->assertStatus(200)->assertSeeText('Contact');

$this->get('/docs/')->assertStatus(200)->assertSeeText('Documentation');
$this->get('/about/')->assertStatus(200)->assertSeeText('About');
$this->get('/about/contact/')->assertStatus(200)->assertSeeText('Contact');

$this->get('/docs')->assertStatus(200)->assertSeeText('Documentation');
$this->get('/about')->assertStatus(200)->assertSeeText('About');
$this->get('/about/contact')->assertStatus(200)->assertSeeText('Contact');

$this->get('/about/contact/index')->assertStatus(404);

unlink($this->projectPath('_docs/index.md'));
unlink($this->projectPath('_pages/about/index.md'));
unlink($this->projectPath('_pages/about/contact.md'));
}

public function testDynamicDocumentationSearchPages()
{
file_put_contents($this->projectPath('_docs/index.md'), '# Documentation');
Expand All @@ -28,6 +61,10 @@ public function testDynamicDocumentationSearchPages()
->assertStatus(200)
->assertSeeText('Search the documentation site');

$this->get('/docs/search.html')
->assertStatus(200)
->assertSeeText('Search the documentation site');

$this->get('/docs/search.json')
->assertStatus(200)
->assertHeader('Content-Type', 'application/json')
Expand Down
8 changes: 5 additions & 3 deletions packages/realtime-compiler/tests/Integration/TestResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class TestResponse
protected ResponseInterface $response;
protected IntegrationTestCase $test;

protected string $uri;
protected string $html;
protected string $text;

Expand All @@ -19,13 +20,14 @@ public static function get(IntegrationTestCase $test, string $uri): static

$response = $guzzle->get('http://localhost:8080'.$uri, ['http_errors' => false]);

return new static($test, $response);
return new static($test, $response, $uri);
}

public function __construct(IntegrationTestCase $test, ResponseInterface $response)
public function __construct(IntegrationTestCase $test, ResponseInterface $response, string $uri)
{
$this->test = $test;
$this->response = $response;
$this->uri = $uri;

$this->parsePageData();
}
Expand Down Expand Up @@ -70,7 +72,7 @@ public function ddHeaders(): void

public function assertStatus(int $code): static
{
$this->test->assertSame($code, $this->response->getStatusCode());
$this->test->assertSame($code, $this->response->getStatusCode(), sprintf('Did not receive expected code %s when accessing %s', $code, $this->uri));

return $this;
}
Expand Down