From 259e9da1f3d529087aa37704c93337668a38eb0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ballang=C3=A9?= Date: Thu, 8 Sep 2022 17:53:28 -0400 Subject: [PATCH] Fallback to Translator's locale when there is no Request available --- src/Provider/LocaleProvider.php | 8 +- tests/Provider/LocaleProviderTest.php | 218 ++++++++++++++++++++++++++ 2 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 tests/Provider/LocaleProviderTest.php diff --git a/src/Provider/LocaleProvider.php b/src/Provider/LocaleProvider.php index f3c472b0..9c15407b 100644 --- a/src/Provider/LocaleProvider.php +++ b/src/Provider/LocaleProvider.php @@ -25,7 +25,7 @@ public function provideCurrentLocale(): ?string { $currentRequest = $this->requestStack->getCurrentRequest(); if (! $currentRequest instanceof Request) { - return null; + return $this->translator?->getLocale() ?: null; } $currentLocale = $currentRequest->getLocale(); @@ -33,11 +33,7 @@ public function provideCurrentLocale(): ?string return $currentLocale; } - if ($this->translator !== null) { - return $this->translator->getLocale(); - } - - return null; + return $this->translator?->getLocale() ?: null; } public function provideFallbackLocale(): ?string diff --git a/tests/Provider/LocaleProviderTest.php b/tests/Provider/LocaleProviderTest.php new file mode 100644 index 00000000..3f23e129 --- /dev/null +++ b/tests/Provider/LocaleProviderTest.php @@ -0,0 +1,218 @@ +requestStack = $this->createMock(RequestStack::class); + $this->parameterBag = $this->createMock(ParameterBagInterface::class); + $this->translator = $this->createMock(TranslatorInterface::class); + + $this->localeProvider = new LocaleProvider( + $this->requestStack, + $this->parameterBag, + $this->translator, + ); + } + + public function testProvideCurrentLocaleReadsFromRequest(): void + { + $request = $this->createMock(Request::class); + $request->expects($this->once()) + ->method('getLocale') + ->willReturn('ZZ'); + + $this->requestStack->expects($this->once()) + ->method('getCurrentRequest') + ->willReturn($request); + + $this->translator->expects($this->never()) + ->method('getLocale'); + + $this->assertSame('ZZ', $this->localeProvider->provideCurrentLocale()); + } + + public function testProvideCurrentLocaleIgnoresRequestLocaleWhenEmpty(): void + { + $request = $this->createMock(Request::class); + $request->expects($this->once()) + ->method('getLocale') + ->willReturn(''); + + $this->requestStack->expects($this->once()) + ->method('getCurrentRequest') + ->willReturn($request); + + $this->translator->expects($this->once()) + ->method('getLocale') + ->willReturn('ZZ'); + + $this->assertSame('ZZ', $this->localeProvider->provideCurrentLocale()); + } + + public function testProvideCurrentLocaleFallsBackGracefully(): void + { + $request = $this->createMock(Request::class); + $request->expects($this->once()) + ->method('getLocale') + ->willReturn(''); + + $this->requestStack->expects($this->once()) + ->method('getCurrentRequest') + ->willReturn($request); + + $this->translator->expects($this->once()) + ->method('getLocale') + ->willReturn(''); + + $this->assertNull($this->localeProvider->provideCurrentLocale()); + } + + public function testProvideCurrentLocaleUsesTranslatorWhenNoRequestAvailable(): void + { + $this->requestStack->expects($this->once()) + ->method('getCurrentRequest') + ->willReturn(null); + + $this->translator->expects($this->once()) + ->method('getLocale') + ->willReturn('ZZ'); + + $this->assertSame('ZZ', $this->localeProvider->provideCurrentLocale()); + } + + public function testProvideCurrentLocaleHandlesMissingTranslatorWhenNoRequest(): void + { + $localeProvider = new LocaleProvider( + $this->requestStack, + $this->parameterBag, + null + ); + + $this->requestStack->expects($this->once()) + ->method('getCurrentRequest') + ->willReturn(null); + + $this->assertNull($localeProvider->provideCurrentLocale()); + } + + public function testProvideCurrentLocaleHandlesMissingTranslatorWhenEmptyRequestLocale(): void + { + $localeProvider = new LocaleProvider( + $this->requestStack, + $this->parameterBag, + null + ); + + $request = $this->createMock(Request::class); + $request->expects($this->once()) + ->method('getLocale') + ->willReturn(''); + $this->requestStack->expects($this->once()) + ->method('getCurrentRequest') + ->willReturn($request); + + $this->assertNull($localeProvider->provideCurrentLocale()); + } + + public function testProvideFallbackLocaleReadsFromRequest(): void + { + $request = $this->createMock(Request::class); + $request->expects($this->once()) + ->method('getDefaultLocale') + ->willReturn('ZZ'); + + $this->requestStack->expects($this->once()) + ->method('getCurrentRequest') + ->willReturn($request); + + $this->assertSame('ZZ', $this->localeProvider->provideFallbackLocale()); + } + + public function testProvideFallbackLocaleReadsFromConfigWhenNoRequest(): void + { + $this->requestStack->expects($this->once()) + ->method('getCurrentRequest') + ->willReturn(null); + + $this->parameterBag->expects($this->once()) + ->method('has') + ->with('locale') + ->willReturn(true); + + $this->parameterBag->expects($this->once()) + ->method('get') + ->with('locale') + ->willReturn('ZZ'); + + $this->assertSame('ZZ', $this->localeProvider->provideFallbackLocale()); + } + + public function testProvideFallbackLocaleFallsBackToDefaultConfiguredLocale(): void + { + $this->requestStack->expects($this->once()) + ->method('getCurrentRequest') + ->willReturn(null); + + $this->parameterBag->expects($this->once()) + ->method('has') + ->with('locale') + ->willReturn(false); + + $this->parameterBag->expects($this->once()) + ->method('get') + ->with('kernel.default_locale') + ->willReturn('ZZ'); + + $this->assertSame('ZZ', $this->localeProvider->provideFallbackLocale()); + } + + /** @dataProvider getExpectedExceptionsProvider */ + public function testProvideFallbackLocaleHandlesConfigExceptions(Throwable $expectedException): void + { + $this->requestStack->expects($this->once()) + ->method('getCurrentRequest') + ->willReturn(null); + + $this->parameterBag->expects($this->once()) + ->method('has') + ->with('locale') + ->willReturn(false); + + $this->parameterBag->expects($this->once()) + ->method('get') + ->willThrowException($expectedException); + + $this->assertNull($this->localeProvider->provideFallbackLocale()); + } + + public function getExpectedExceptionsProvider(): array + { + return [ + [new ParameterNotFoundException('foo')], + [new InvalidArgumentException()], + ]; + } +}