|
18 | 18 | use Symfony\Contracts\Translation\TranslatorInterface; |
19 | 19 | use Throwable; |
20 | 20 | use Twig\Environment; |
| 21 | +use Twig\Loader\ChainLoader; |
| 22 | +use Twig\Loader\FilesystemLoader; |
21 | 23 |
|
22 | 24 | class ErrorControllerTest extends DbAwareTestCase |
23 | 25 | { |
@@ -119,6 +121,34 @@ public function testErrorPageRecoversTranslatorLocaleFromPath(): void |
119 | 121 | self::assertSame('nl', $translator->getLocale()); |
120 | 122 | } |
121 | 123 |
|
| 124 | + public function testErrorPageTranslatesUnderscoreFunctionInRequestedLocale(): void |
| 125 | + { |
| 126 | + // End-to-end: a `{{ __('...') }}` string in the rendered error page must be |
| 127 | + // translated in the locale recovered from the URL. `http_error.name` is |
| 128 | + // "Error %status_code%" (en) / "Fout %status_code%" (nl). |
| 129 | + $this->registerFixtureTemplatePath(); |
| 130 | + $this->setGeneralConfig('notfound', ['locale_probe.html.twig']); |
| 131 | + |
| 132 | + $body = (string) $this->renderError(new NotFoundHttpException(), '/nl/this-page-does-not-exist')->getContent(); |
| 133 | + |
| 134 | + self::assertStringContainsString('LOCALE_PROBE:Fout 404', $body); |
| 135 | + self::assertStringNotContainsString('Error 404', $body); |
| 136 | + } |
| 137 | + |
| 138 | + public function testErrorPageTranslatesUnderscoreFunctionInDefaultLocale(): void |
| 139 | + { |
| 140 | + // The counterpart of the test above: with no locale segment in the URL, the |
| 141 | + // same `__()` string must fall back to the default locale (en) - and must not |
| 142 | + // leak a previous request's locale onto the shared translator. |
| 143 | + $this->registerFixtureTemplatePath(); |
| 144 | + $this->setGeneralConfig('notfound', ['locale_probe.html.twig']); |
| 145 | + |
| 146 | + $body = (string) $this->renderError(new NotFoundHttpException(), '/this-page-does-not-exist')->getContent(); |
| 147 | + |
| 148 | + self::assertStringContainsString('LOCALE_PROBE:Error 404', $body); |
| 149 | + self::assertStringNotContainsString('Fout 404', $body); |
| 150 | + } |
| 151 | + |
122 | 152 | public function testNotFoundPageWithNonLocalizedContentTypeDoesNotError(): void |
123 | 153 | { |
124 | 154 | // The default `notfound` points at `blocks/404-not-found`. The `blocks` |
@@ -185,6 +215,31 @@ private function renderError(Throwable $exception, string $path): Response |
185 | 215 | } |
186 | 216 | } |
187 | 217 |
|
| 218 | + /** |
| 219 | + * Make the `Fixtures/` directory resolvable by name, so a fixture template can be |
| 220 | + * pointed at via the `notfound` config. Mirrors how Bolt prepends paths to the |
| 221 | + * existing filesystem loader (see TwigAwareController::setTwigLoader()) rather than |
| 222 | + * replacing it, so the added path survives rendering. |
| 223 | + */ |
| 224 | + private function registerFixtureTemplatePath(): void |
| 225 | + { |
| 226 | + /** @var Environment $twig */ |
| 227 | + $twig = self::getContainer()->get('twig'); |
| 228 | + |
| 229 | + $loader = $twig->getLoader(); |
| 230 | + $loaders = $loader instanceof ChainLoader ? $loader->getLoaders() : [$loader]; |
| 231 | + |
| 232 | + foreach ($loaders as $candidate) { |
| 233 | + if ($candidate instanceof FilesystemLoader) { |
| 234 | + $candidate->addPath(__DIR__ . '/Fixtures'); |
| 235 | + |
| 236 | + return; |
| 237 | + } |
| 238 | + } |
| 239 | + |
| 240 | + self::fail('Could not find a FilesystemLoader to register the fixture template path on.'); |
| 241 | + } |
| 242 | + |
188 | 243 | private function getPublishedPage(): Content |
189 | 244 | { |
190 | 245 | $page = $this->getEm()->getRepository(Content::class) |
|
0 commit comments